aboutsummaryrefslogtreecommitdiff
path: root/xorg-server
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server')
-rw-r--r--xorg-server/configure.ac4495
-rw-r--r--xorg-server/dix/colormap.c5523
-rw-r--r--xorg-server/dix/gc.c2317
-rw-r--r--xorg-server/hw/xfree86/common/Makefile.am1
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c2278
-rw-r--r--xorg-server/hw/xquartz/X11Application.m28
-rw-r--r--xorg-server/hw/xquartz/mach-startup/bundle-main.c5
-rw-r--r--xorg-server/os/log.c1241
8 files changed, 7958 insertions, 7930 deletions
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index 959ed48a8..1c7875ee3 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -1,2248 +1,2247 @@
-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])
-CONFIG_LIB='$(top_builddir)/config/libconfig.la'
-
-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 $CONFIG_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 $CONFIG_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 $CONFIG_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 $CONFIG_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 $CONFIG_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 $CONFIG_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 $CONFIG_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)
+
+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
+])
diff --git a/xorg-server/dix/colormap.c b/xorg-server/dix/colormap.c
index 8bd41ce67..e22c35cb8 100644
--- a/xorg-server/dix/colormap.c
+++ b/xorg-server/dix/colormap.c
@@ -1,2761 +1,2762 @@
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-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 Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL 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.
-
-******************************************************************/
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include "misc.h"
-#include "dix.h"
-#include "colormapst.h"
-#include "os.h"
-#include "scrnintstr.h"
-#include "resource.h"
-#include "windowstr.h"
-#include "privates.h"
-#include "xace.h"
-
-#ifdef _MSC_VER
-#define UpdateColors thisUpdateColors
-#endif
-
-static Pixel FindBestPixel(
- EntryPtr /*pentFirst*/,
- int /*size*/,
- xrgb * /*prgb*/,
- int /*channel*/
-);
-
-static int AllComp(
- EntryPtr /*pent*/,
- xrgb * /*prgb*/
-);
-
-static int RedComp(
- EntryPtr /*pent*/,
- xrgb * /*prgb*/
-);
-
-static int GreenComp(
- EntryPtr /*pent*/,
- xrgb * /*prgb*/
-);
-
-static int BlueComp(
- EntryPtr /*pent*/,
- xrgb * /*prgb*/
-);
-
-static void FreePixels(
- ColormapPtr /*pmap*/,
- int /*client*/
-);
-
-static void CopyFree(
- int /*channel*/,
- int /*client*/,
- ColormapPtr /*pmapSrc*/,
- ColormapPtr /*pmapDst*/
-);
-
-static void FreeCell(
- ColormapPtr /*pmap*/,
- Pixel /*i*/,
- int /*channel*/
-);
-
-static void UpdateColors(
- ColormapPtr /*pmap*/
-);
-
-static int AllocDirect(
- int /*client*/,
- ColormapPtr /*pmap*/,
- int /*c*/,
- int /*r*/,
- int /*g*/,
- int /*b*/,
- Bool /*contig*/,
- Pixel * /*pixels*/,
- Pixel * /*prmask*/,
- Pixel * /*pgmask*/,
- Pixel * /*pbmask*/
-);
-
-static int AllocPseudo(
- int /*client*/,
- ColormapPtr /*pmap*/,
- int /*c*/,
- int /*r*/,
- Bool /*contig*/,
- Pixel * /*pixels*/,
- Pixel * /*pmask*/,
- Pixel ** /*pppixFirst*/
-);
-
-static Bool AllocCP(
- ColormapPtr /*pmap*/,
- EntryPtr /*pentFirst*/,
- int /*count*/,
- int /*planes*/,
- Bool /*contig*/,
- Pixel * /*pixels*/,
- Pixel * /*pMask*/
-);
-
-static Bool AllocShared(
- ColormapPtr /*pmap*/,
- Pixel * /*ppix*/,
- int /*c*/,
- int /*r*/,
- int /*g*/,
- int /*b*/,
- Pixel /*rmask*/,
- Pixel /*gmask*/,
- Pixel /*bmask*/,
- Pixel * /*ppixFirst*/
-);
-
-static int FreeCo(
- ColormapPtr /*pmap*/,
- int /*client*/,
- int /*color*/,
- int /*npixIn*/,
- Pixel * /*ppixIn*/,
- Pixel /*mask*/
-);
-
-static int TellNoMap(
- WindowPtr /*pwin*/,
- Colormap * /*pmid*/
-);
-
-static void FindColorInRootCmap (
- ColormapPtr /* pmap */,
- EntryPtr /* pentFirst */,
- int /* size */,
- xrgb* /* prgb */,
- Pixel* /* pPixel */,
- int /* channel */,
- ColorCompareProcPtr /* comp */
-);
-
-#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
-#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
-#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
-#if COMPOSITE
-#define ALPHAMASK(vis) ((vis)->nplanes < 32 ? 0 : \
- (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask))
-#else
-#define ALPHAMASK(vis) 0
-#endif
-
-#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
-
-/* GetNextBitsOrBreak(bits, mask, base) --
- * (Suggestion: First read the macro, then read this explanation.
- *
- * Either generate the next value to OR in to a pixel or break out of this
- * while loop
- *
- * This macro is used when we're trying to generate all 2^n combinations of
- * bits in mask. What we're doing here is counting in binary, except that
- * the bits we use to count may not be contiguous. This macro will be
- * called 2^n times, returning a different value in bits each time. Then
- * it will cause us to break out of a surrounding loop. (It will always be
- * called from within a while loop.)
- * On call: mask is the value we want to find all the combinations for
- * base has 1 bit set where the least significant bit of mask is set
- *
- * For example,if mask is 01010, base should be 0010 and we count like this:
- * 00010 (see this isn't so hard),
- * then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
- * we add that to bits getting (0100 + 0100) =
- * 01000 for our next value.
- * then we add 0010 to get
- * 01010 and we're done (easy as 1, 2, 3)
- */
-#define GetNextBitsOrBreak(bits, mask, base) \
- if((bits) == (mask)) \
- break; \
- (bits) += (base); \
- while((bits) & ~(mask)) \
- (bits) += ((bits) & ~(mask));
-/* ID of server as client */
-#define SERVER_ID 0
-
-typedef struct _colorResource
-{
- Colormap mid;
- int client;
-} colorResource;
-
-/* Invariants:
- * refcnt == 0 means entry is empty
- * refcnt > 0 means entry is useable by many clients, so it can't be changed
- * refcnt == AllocPrivate means entry owned by one client only
- * fShared should only be set if refcnt == AllocPrivate, and only in red map
- */
-
-
-/**
- * Create and initialize the color map
- *
- * \param mid resource to use for this colormap
- * \param alloc 1 iff all entries are allocated writable
- */
-int
-CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
- ColormapPtr *ppcmap, int alloc, int client)
-{
- int class, size;
- unsigned long sizebytes;
- ColormapPtr pmap;
- EntryPtr pent;
- int i;
- Pixel *ppix, **pptr;
-
- class = pVisual->class;
- if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
- return (BadMatch);
-
- size = pVisual->ColormapEntries;
- sizebytes = (size * sizeof(Entry)) +
- (MAXCLIENTS * sizeof(Pixel *)) +
- (MAXCLIENTS * sizeof(int));
- if ((class | DynamicClass) == DirectColor)
- sizebytes *= 3;
- sizebytes += sizeof(ColormapRec);
- pmap = malloc(sizebytes);
- if (!pmap)
- return (BadAlloc);
-#if defined(_XSERVER64)
- pmap->pad0 = 0;
- pmap->pad1 = 0;
-#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
- pmap->pad2 = 0;
-#endif
-#endif
- pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));
- sizebytes = size * sizeof(Entry);
- pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
- pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
- (MAXCLIENTS * sizeof(Pixel *)));
- pmap->mid = mid;
- pmap->flags = 0; /* start out with all flags clear */
- if(mid == pScreen->defColormap)
- pmap->flags |= IsDefault;
- pmap->pScreen = pScreen;
- pmap->pVisual = pVisual;
- pmap->class = class;
- if ((class | DynamicClass) == DirectColor)
- size = NUMRED(pVisual);
- pmap->freeRed = size;
- bzero ((char *) pmap->red, (int)sizebytes);
- bzero((char *) pmap->numPixelsRed, MAXCLIENTS * sizeof(int));
- for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
- *pptr = (Pixel *)NULL;
- if (alloc == AllocAll)
- {
- if (class & DynamicClass)
- pmap->flags |= AllAllocated;
- for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
- pent->refcnt = AllocPrivate;
- pmap->freeRed = 0;
- ppix = malloc(size * sizeof(Pixel));
- if (!ppix)
- {
- free(pmap);
- return (BadAlloc);
- }
- pmap->clientPixelsRed[client] = ppix;
- for(i = 0; i < size; i++)
- ppix[i] = i;
- pmap->numPixelsRed[client] = size;
- }
-
- if ((class | DynamicClass) == DirectColor)
- {
- pmap->freeGreen = NUMGREEN(pVisual);
- pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
- (MAXCLIENTS * sizeof(int)));
- pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
- pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
- (MAXCLIENTS * sizeof(Pixel *)));
- pmap->freeBlue = NUMBLUE(pVisual);
- pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
- (MAXCLIENTS * sizeof(int)));
- pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
- pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
- (MAXCLIENTS * sizeof(Pixel *)));
-
- bzero ((char *) pmap->green, (int)sizebytes);
- bzero ((char *) pmap->blue, (int)sizebytes);
-
- memmove((char *) pmap->clientPixelsGreen,
- (char *) pmap->clientPixelsRed,
- MAXCLIENTS * sizeof(Pixel *));
- memmove((char *) pmap->clientPixelsBlue,
- (char *) pmap->clientPixelsRed,
- MAXCLIENTS * sizeof(Pixel *));
- bzero((char *) pmap->numPixelsGreen, MAXCLIENTS * sizeof(int));
- bzero((char *) pmap->numPixelsBlue, MAXCLIENTS * sizeof(int));
-
- /* If every cell is allocated, mark its refcnt */
- if (alloc == AllocAll)
- {
- size = pmap->freeGreen;
- for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
- pent->refcnt = AllocPrivate;
- pmap->freeGreen = 0;
- ppix = malloc(size * sizeof(Pixel));
- if (!ppix)
- {
- free(pmap->clientPixelsRed[client]);
- free(pmap);
- return(BadAlloc);
- }
- pmap->clientPixelsGreen[client] = ppix;
- for(i = 0; i < size; i++)
- ppix[i] = i;
- pmap->numPixelsGreen[client] = size;
-
- size = pmap->freeBlue;
- for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
- pent->refcnt = AllocPrivate;
- pmap->freeBlue = 0;
- ppix = malloc(size * sizeof(Pixel));
- if (!ppix)
- {
- free(pmap->clientPixelsGreen[client]);
- free(pmap->clientPixelsRed[client]);
- free(pmap);
- return(BadAlloc);
- }
- pmap->clientPixelsBlue[client] = ppix;
- for(i = 0; i < size; i++)
- ppix[i] = i;
- pmap->numPixelsBlue[client] = size;
- }
- }
- pmap->devPrivates = NULL;
- pmap->flags |= BeingCreated;
-
- if (!AddResource(mid, RT_COLORMAP, (pointer)pmap))
- return (BadAlloc);
-
- /*
- * Security creation/labeling check
- */
- i = XaceHook(XACE_RESOURCE_ACCESS, clients[client], mid, RT_COLORMAP,
- pmap, RT_NONE, NULL, DixCreateAccess);
- if (i != Success) {
- FreeResource(mid, RT_NONE);
- return i;
- }
-
- /* If the device wants a chance to initialize the colormap in any way,
- * this is it. In specific, if this is a Static colormap, this is the
- * time to fill in the colormap's values */
- if (!(*pScreen->CreateColormap)(pmap))
- {
- FreeResource (mid, RT_NONE);
- return BadAlloc;
- }
- pmap->flags &= ~BeingCreated;
- *ppcmap = pmap;
- return (Success);
-}
-
-/**
- *
- * \param value must conform to DeleteType
- */
-int
-FreeColormap (pointer value, XID mid)
-{
- int i;
- EntryPtr pent;
- ColormapPtr pmap = (ColormapPtr)value;
-
- if(CLIENT_ID(mid) != SERVER_ID)
- {
- (*pmap->pScreen->UninstallColormap) (pmap);
- WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid);
- }
-
- /* This is the device's chance to undo anything it needs to, especially
- * to free any storage it allocated */
- (*pmap->pScreen->DestroyColormap)(pmap);
-
- if(pmap->clientPixelsRed)
- {
- for(i = 0; i < MAXCLIENTS; i++)
- free(pmap->clientPixelsRed[i]);
- }
-
- if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
- {
- for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
- pent >= pmap->red;
- pent--)
- {
- if(pent->fShared)
- {
- if (--pent->co.shco.red->refcnt == 0)
- free(pent->co.shco.red);
- if (--pent->co.shco.green->refcnt == 0)
- free(pent->co.shco.green);
- if (--pent->co.shco.blue->refcnt == 0)
- free(pent->co.shco.blue);
- }
- }
- }
- if((pmap->class | DynamicClass) == DirectColor)
- {
- for(i = 0; i < MAXCLIENTS; i++)
- {
- free(pmap->clientPixelsGreen[i]);
- free(pmap->clientPixelsBlue[i]);
- }
- }
-
- dixFreePrivates(pmap->devPrivates);
- free(pmap);
- return(Success);
-}
-
-/* Tell window that pmid has disappeared */
-static int
-TellNoMap (WindowPtr pwin, Colormap *pmid)
-{
- xEvent xE;
-
- if (wColormap(pwin) == *pmid)
- {
- /* This should be call to DeliverEvent */
- xE.u.u.type = ColormapNotify;
- xE.u.colormap.window = pwin->drawable.id;
- xE.u.colormap.colormap = None;
- xE.u.colormap.new = TRUE;
- xE.u.colormap.state = ColormapUninstalled;
-#ifdef PANORAMIX
- if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
-#endif
- DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
- if (pwin->optional) {
- pwin->optional->colormap = None;
- CheckWindowOptionalNeed (pwin);
- }
- }
-
- return (WT_WALKCHILDREN);
-}
-
-/* Tell window that pmid got uninstalled */
-int
-TellLostMap (WindowPtr pwin, pointer value)
-{
- Colormap *pmid = (Colormap *)value;
- xEvent xE;
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
- return WT_STOPWALKING;
-#endif
- if (wColormap(pwin) == *pmid)
- {
- /* This should be call to DeliverEvent */
- xE.u.u.type = ColormapNotify;
- xE.u.colormap.window = pwin->drawable.id;
- xE.u.colormap.colormap = *pmid;
- xE.u.colormap.new = FALSE;
- xE.u.colormap.state = ColormapUninstalled;
- DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
- }
-
- return (WT_WALKCHILDREN);
-}
-
-/* Tell window that pmid got installed */
-int
-TellGainedMap (WindowPtr pwin, pointer value)
-{
- Colormap *pmid = (Colormap *)value;
- xEvent xE;
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
- return WT_STOPWALKING;
-#endif
- if (wColormap (pwin) == *pmid)
- {
- /* This should be call to DeliverEvent */
- xE.u.u.type = ColormapNotify;
- xE.u.colormap.window = pwin->drawable.id;
- xE.u.colormap.colormap = *pmid;
- xE.u.colormap.new = FALSE;
- xE.u.colormap.state = ColormapInstalled;
- DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
- }
-
- return (WT_WALKCHILDREN);
-}
-
-
-int
-CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client)
-{
- ColormapPtr pmap = (ColormapPtr) NULL;
- int result, alloc, size;
- Colormap midSrc;
- ScreenPtr pScreen;
- VisualPtr pVisual;
-
- pScreen = pSrc->pScreen;
- pVisual = pSrc->pVisual;
- midSrc = pSrc->mid;
- alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
- AllocAll : AllocNone;
- size = pVisual->ColormapEntries;
-
- /* If the create returns non-0, it failed */
- result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
- if(result != Success)
- return(result);
- if(alloc == AllocAll)
- {
- memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
- if((pmap->class | DynamicClass) == DirectColor)
- {
- memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
- memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
- }
- pSrc->flags &= ~AllAllocated;
- FreePixels(pSrc, client);
- UpdateColors(pmap);
- return(Success);
- }
-
- CopyFree(REDMAP, client, pSrc, pmap);
- if ((pmap->class | DynamicClass) == DirectColor)
- {
- CopyFree(GREENMAP, client, pSrc, pmap);
- CopyFree(BLUEMAP, client, pSrc, pmap);
- }
- if (pmap->class & DynamicClass)
- UpdateColors(pmap);
- /* XXX should worry about removing any RT_CMAPENTRY resource */
- return(Success);
-}
-
-/* Helper routine for freeing large numbers of cells from a map */
-static void
-CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst)
-{
- int z, npix;
- EntryPtr pentSrcFirst, pentDstFirst;
- EntryPtr pentSrc, pentDst;
- Pixel *ppix;
- int nalloc;
-
- switch(channel)
- {
- default: /* so compiler can see that everything gets initialized */
- case REDMAP:
- ppix = (pmapSrc->clientPixelsRed)[client];
- npix = (pmapSrc->numPixelsRed)[client];
- pentSrcFirst = pmapSrc->red;
- pentDstFirst = pmapDst->red;
- break;
- case GREENMAP:
- ppix = (pmapSrc->clientPixelsGreen)[client];
- npix = (pmapSrc->numPixelsGreen)[client];
- pentSrcFirst = pmapSrc->green;
- pentDstFirst = pmapDst->green;
- break;
- case BLUEMAP:
- ppix = (pmapSrc->clientPixelsBlue)[client];
- npix = (pmapSrc->numPixelsBlue)[client];
- pentSrcFirst = pmapSrc->blue;
- pentDstFirst = pmapDst->blue;
- break;
- }
- nalloc = 0;
- if (pmapSrc->class & DynamicClass)
- {
- for(z = npix; --z >= 0; ppix++)
- {
- /* Copy entries */
- pentSrc = pentSrcFirst + *ppix;
- pentDst = pentDstFirst + *ppix;
- if (pentDst->refcnt > 0)
- {
- pentDst->refcnt++;
- }
- else
- {
- *pentDst = *pentSrc;
- nalloc++;
- if (pentSrc->refcnt > 0)
- pentDst->refcnt = 1;
- else
- pentSrc->fShared = FALSE;
- }
- FreeCell(pmapSrc, *ppix, channel);
- }
- }
-
- /* Note that FreeCell has already fixed pmapSrc->free{Color} */
- switch(channel)
- {
- case REDMAP:
- pmapDst->freeRed -= nalloc;
- (pmapDst->clientPixelsRed)[client] =
- (pmapSrc->clientPixelsRed)[client];
- (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
- (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
- (pmapSrc->numPixelsRed)[client] = 0;
- break;
- case GREENMAP:
- pmapDst->freeGreen -= nalloc;
- (pmapDst->clientPixelsGreen)[client] =
- (pmapSrc->clientPixelsGreen)[client];
- (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
- (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
- (pmapSrc->numPixelsGreen)[client] = 0;
- break;
- case BLUEMAP:
- pmapDst->freeBlue -= nalloc;
- pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
- pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
- pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
- pmapSrc->numPixelsBlue[client] = 0;
- break;
- }
-}
-
-/* Free the ith entry in a color map. Must handle freeing of
- * colors allocated through AllocColorPlanes */
-static void
-FreeCell (ColormapPtr pmap, Pixel i, int channel)
-{
- EntryPtr pent;
- int *pCount;
-
-
- switch (channel)
- {
- default: /* so compiler can see that everything gets initialized */
- case PSEUDOMAP:
- case REDMAP:
- pent = (EntryPtr) &pmap->red[i];
- pCount = &pmap->freeRed;
- break;
- case GREENMAP:
- pent = (EntryPtr) &pmap->green[i];
- pCount = &pmap->freeGreen;
- break;
- case BLUEMAP:
- pent = (EntryPtr) &pmap->blue[i];
- pCount = &pmap->freeBlue;
- break;
- }
- /* If it's not privately allocated and it's not time to free it, just
- * decrement the count */
- if (pent->refcnt > 1)
- pent->refcnt--;
- else
- {
- /* If the color type is shared, find the sharedcolor. If decremented
- * refcnt is 0, free the shared cell. */
- if (pent->fShared)
- {
- if(--pent->co.shco.red->refcnt == 0)
- free(pent->co.shco.red);
- if(--pent->co.shco.green->refcnt == 0)
- free(pent->co.shco.green);
- if(--pent->co.shco.blue->refcnt == 0)
- free(pent->co.shco.blue);
- pent->fShared = FALSE;
- }
- pent->refcnt = 0;
- *pCount += 1;
- }
-}
-
-static void
-UpdateColors (ColormapPtr pmap)
-{
- xColorItem *defs;
- xColorItem *pdef;
- EntryPtr pent;
- VisualPtr pVisual;
- int i, n, size;
-
- pVisual = pmap->pVisual;
- size = pVisual->ColormapEntries;
- defs = malloc(size * sizeof(xColorItem));
- if (!defs)
- return;
- n = 0;
- pdef = defs;
- if (pmap->class == DirectColor)
- {
- for (i = 0; i < size; i++)
- {
- if (!pmap->red[i].refcnt &&
- !pmap->green[i].refcnt &&
- !pmap->blue[i].refcnt)
- continue;
- pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
- ((Pixel)i << pVisual->offsetGreen) |
- ((Pixel)i << pVisual->offsetBlue);
- pdef->red = pmap->red[i].co.local.red;
- pdef->green = pmap->green[i].co.local.green;
- pdef->blue = pmap->blue[i].co.local.blue;
- pdef->flags = DoRed|DoGreen|DoBlue;
- pdef++;
- n++;
- }
- }
- else
- {
- for (i = 0, pent = pmap->red; i < size; i++, pent++)
- {
- if (!pent->refcnt)
- continue;
- pdef->pixel = i;
- if(pent->fShared)
- {
- pdef->red = pent->co.shco.red->color;
- pdef->green = pent->co.shco.green->color;
- pdef->blue = pent->co.shco.blue->color;
- }
- else
- {
- pdef->red = pent->co.local.red;
- pdef->green = pent->co.local.green;
- pdef->blue = pent->co.local.blue;
- }
- pdef->flags = DoRed|DoGreen|DoBlue;
- pdef++;
- n++;
- }
- }
- if (n)
- (*pmap->pScreen->StoreColors)(pmap, n, defs);
- free(defs);
-}
-
-/* Get a read-only color from a ColorMap (probably slow for large maps)
- * Returns by changing the value in pred, pgreen, pblue and pPix
- */
-int
-AllocColor (ColormapPtr pmap,
- unsigned short *pred, unsigned short *pgreen, unsigned short *pblue,
- Pixel *pPix, int client)
-{
- Pixel pixR, pixG, pixB;
- int entries;
- xrgb rgb;
- int class;
- VisualPtr pVisual;
- int npix;
- Pixel *ppix;
-
- pVisual = pmap->pVisual;
- (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
- rgb.red = *pred;
- rgb.green = *pgreen;
- rgb.blue = *pblue;
- class = pmap->class;
- entries = pVisual->ColormapEntries;
-
- /* If the colormap is being created, then we want to be able to change
- * the colormap, even if it's a static type. Otherwise, we'd never be
- * able to initialize static colormaps
- */
- if(pmap->flags & BeingCreated)
- class |= DynamicClass;
-
- /* If this is one of the static storage classes, and we're not initializing
- * it, the best we can do is to find the closest color entry to the
- * requested one and return that.
- */
- switch (class) {
- case StaticColor:
- case StaticGray:
- /* Look up all three components in the same pmap */
- *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
- *pred = pmap->red[pixR].co.local.red;
- *pgreen = pmap->red[pixR].co.local.green;
- *pblue = pmap->red[pixR].co.local.blue;
- npix = pmap->numPixelsRed[client];
- ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
- (npix + 1) * sizeof(Pixel));
- if (!ppix)
- return (BadAlloc);
- ppix[npix] = pixR;
- pmap->clientPixelsRed[client] = ppix;
- pmap->numPixelsRed[client]++;
- break;
-
- case TrueColor:
- /* Look up each component in its own map, then OR them together */
- pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
- pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
- pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
- *pPix = (pixR << pVisual->offsetRed) |
- (pixG << pVisual->offsetGreen) |
- (pixB << pVisual->offsetBlue) |
- ALPHAMASK(pVisual);
-
- *pred = pmap->red[pixR].co.local.red;
- *pgreen = pmap->green[pixG].co.local.green;
- *pblue = pmap->blue[pixB].co.local.blue;
- npix = pmap->numPixelsRed[client];
- ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
- (npix + 1) * sizeof(Pixel));
- if (!ppix)
- return (BadAlloc);
- ppix[npix] = pixR;
- pmap->clientPixelsRed[client] = ppix;
- npix = pmap->numPixelsGreen[client];
- ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
- (npix + 1) * sizeof(Pixel));
- if (!ppix)
- return (BadAlloc);
- ppix[npix] = pixG;
- pmap->clientPixelsGreen[client] = ppix;
- npix = pmap->numPixelsBlue[client];
- ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
- (npix + 1) * sizeof(Pixel));
- if (!ppix)
- return (BadAlloc);
- ppix[npix] = pixB;
- pmap->clientPixelsBlue[client] = ppix;
- pmap->numPixelsRed[client]++;
- pmap->numPixelsGreen[client]++;
- pmap->numPixelsBlue[client]++;
- break;
-
- case GrayScale:
- case PseudoColor:
- if (pmap->mid != pmap->pScreen->defColormap &&
- pmap->pVisual->vid == pmap->pScreen->rootVisual)
- {
- ColormapPtr prootmap;
- dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
- RT_COLORMAP, clients[client], DixReadAccess);
-
- if (pmap->class == prootmap->class)
- FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
- pPix, PSEUDOMAP, AllComp);
- }
- if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
- client, AllComp) != Success)
- return (BadAlloc);
- break;
-
- case DirectColor:
- if (pmap->mid != pmap->pScreen->defColormap &&
- pmap->pVisual->vid == pmap->pScreen->rootVisual)
- {
- ColormapPtr prootmap;
- dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
- RT_COLORMAP, clients[client], DixReadAccess);
-
- if (pmap->class == prootmap->class)
- {
- pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
- FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
- &pixR, REDMAP, RedComp);
- pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
- FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb,
- &pixG, GREENMAP, GreenComp);
- pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
- FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb,
- &pixB, BLUEMAP, BlueComp);
- *pPix = pixR | pixG | pixB;
- }
- }
-
- pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
- if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
- client, RedComp) != Success)
- return (BadAlloc);
- pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
- if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
- GREENMAP, client, GreenComp) != Success)
- {
- (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
- return (BadAlloc);
- }
- pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
- if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
- client, BlueComp) != Success)
- {
- (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
- (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
- return (BadAlloc);
- }
- *pPix = pixR | pixG | pixB | ALPHAMASK(pVisual);
-
- break;
- }
-
- /* if this is the client's first pixel in this colormap, tell the
- * resource manager that the client has pixels in this colormap which
- * should be freed when the client dies */
- if ((pmap->numPixelsRed[client] == 1) &&
- (CLIENT_ID(pmap->mid) != client) &&
- !(pmap->flags & BeingCreated))
- {
- colorResource *pcr;
-
- pcr = malloc(sizeof(colorResource));
- if (!pcr)
- {
- (void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
- return (BadAlloc);
- }
- pcr->mid = pmap->mid;
- pcr->client = client;
- if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
- return (BadAlloc);
- }
- return (Success);
-}
-
-/*
- * FakeAllocColor -- fake an AllocColor request by
- * returning a free pixel if availible, otherwise returning
- * the closest matching pixel. This is used by the mi
- * software sprite code to recolor cursors. A nice side-effect
- * is that this routine will never return failure.
- */
-
-void
-FakeAllocColor (ColormapPtr pmap, xColorItem *item)
-{
- Pixel pixR, pixG, pixB;
- Pixel temp;
- int entries;
- xrgb rgb;
- int class;
- VisualPtr pVisual;
-
- pVisual = pmap->pVisual;
- rgb.red = item->red;
- rgb.green = item->green;
- rgb.blue = item->blue;
- (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
- class = pmap->class;
- entries = pVisual->ColormapEntries;
-
- switch (class) {
- case GrayScale:
- case PseudoColor:
- temp = 0;
- item->pixel = 0;
- if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
- -1, AllComp) == Success) {
- item->pixel = temp;
- break;
- }
- /* fall through ... */
- case StaticColor:
- case StaticGray:
- item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
- break;
-
- case DirectColor:
- /* Look up each component in its own map, then OR them together */
- pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed;
- pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
- pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
- if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
- -1, RedComp) != Success)
- pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
- << pVisual->offsetRed;
- if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
- GREENMAP, -1, GreenComp) != Success)
- pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
- GREENMAP) << pVisual->offsetGreen;
- if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
- -1, BlueComp) != Success)
- pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
- << pVisual->offsetBlue;
- item->pixel = pixR | pixG | pixB;
- break;
-
- case TrueColor:
- /* Look up each component in its own map, then OR them together */
- pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
- pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
- pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
- item->pixel = (pixR << pVisual->offsetRed) |
- (pixG << pVisual->offsetGreen) |
- (pixB << pVisual->offsetBlue);
- break;
- }
-}
-
-/* free a pixel value obtained from FakeAllocColor */
-void
-FakeFreeColor(ColormapPtr pmap, Pixel pixel)
-{
- VisualPtr pVisual;
- Pixel pixR, pixG, pixB;
-
- switch (pmap->class) {
- case GrayScale:
- case PseudoColor:
- if (pmap->red[pixel].refcnt == AllocTemporary)
- pmap->red[pixel].refcnt = 0;
- break;
- case DirectColor:
- pVisual = pmap->pVisual;
- pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed;
- pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
- pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
- if (pmap->red[pixR].refcnt == AllocTemporary)
- pmap->red[pixR].refcnt = 0;
- if (pmap->green[pixG].refcnt == AllocTemporary)
- pmap->green[pixG].refcnt = 0;
- if (pmap->blue[pixB].refcnt == AllocTemporary)
- pmap->blue[pixB].refcnt = 0;
- break;
- }
-}
-
-typedef unsigned short BigNumUpper;
-typedef unsigned long BigNumLower;
-
-#define BIGNUMLOWERBITS 24
-#define BIGNUMUPPERBITS 16
-#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
-#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
-#define UPPERPART(i) ((i) >> BIGNUMLOWERBITS)
-#define LOWERPART(i) ((i) & (BIGNUMLOWER - 1))
-
-typedef struct _bignum {
- BigNumUpper upper;
- BigNumLower lower;
-} BigNumRec, *BigNumPtr;
-
-#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
- ((x)->upper == (y)->upper && (x)->lower > (y)->lower))
-
-#define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \
- ((r)->lower = LOWERPART(u)))
-
-#define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \
- ((r)->lower = BIGNUMLOWER-1))
-
-static void
-BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
-{
- BigNumLower lower, carry = 0;
-
- lower = x->lower + y->lower;
- if (lower >= BIGNUMLOWER) {
- lower -= BIGNUMLOWER;
- carry = 1;
- }
- r->lower = lower;
- r->upper = x->upper + y->upper + carry;
-}
-
-static Pixel
-FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel)
-{
- EntryPtr pent;
- Pixel pixel, final;
- long dr, dg, db;
- unsigned long sq;
- BigNumRec minval, sum, temp;
-
- final = 0;
- MaxBigNum(&minval);
- /* look for the minimal difference */
- for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
- {
- dr = dg = db = 0;
- switch(channel)
- {
- case PSEUDOMAP:
- dg = (long) pent->co.local.green - prgb->green;
- db = (long) pent->co.local.blue - prgb->blue;
- case REDMAP:
- dr = (long) pent->co.local.red - prgb->red;
- break;
- case GREENMAP:
- dg = (long) pent->co.local.green - prgb->green;
- break;
- case BLUEMAP:
- db = (long) pent->co.local.blue - prgb->blue;
- break;
- }
- sq = dr * dr;
- UnsignedToBigNum (sq, &sum);
- sq = dg * dg;
- UnsignedToBigNum (sq, &temp);
- BigNumAdd (&sum, &temp, &sum);
- sq = db * db;
- UnsignedToBigNum (sq, &temp);
- BigNumAdd (&sum, &temp, &sum);
- if (BigNumGreater (&minval, &sum))
- {
- final = pixel;
- minval = sum;
- }
- }
- return(final);
-}
-
-static void
-FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size,
- xrgb *prgb, Pixel *pPixel, int channel,
- ColorCompareProcPtr comp)
-{
- EntryPtr pent;
- Pixel pixel;
- int count;
-
- if ((pixel = *pPixel) >= size)
- pixel = 0;
- for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
- {
- if (pent->refcnt > 0 && (*comp) (pent, prgb))
- {
- switch (channel)
- {
- case REDMAP:
- pixel <<= pmap->pVisual->offsetRed;
- break;
- case GREENMAP:
- pixel <<= pmap->pVisual->offsetGreen;
- break;
- case BLUEMAP:
- pixel <<= pmap->pVisual->offsetBlue;
- break;
- default: /* PSEUDOMAP */
- break;
- }
- *pPixel = pixel;
- }
- }
-}
-
-/* Tries to find a color in pmap that exactly matches the one requested in prgb
- * if it can't it allocates one.
- * Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
- * load *pPixel with that value, otherwise set it to 0
- */
-int
-FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb,
- Pixel *pPixel, int channel, int client,
- ColorCompareProcPtr comp)
-{
- EntryPtr pent;
- Bool foundFree;
- Pixel pixel, Free = 0;
- int npix, count, *nump = NULL;
- Pixel **pixp = NULL, *ppix;
- xColorItem def;
-
- foundFree = FALSE;
-
- if((pixel = *pPixel) >= size)
- pixel = 0;
- /* see if there is a match, and also look for a free entry */
- for (pent = pentFirst + pixel, count = size; --count >= 0; )
- {
- if (pent->refcnt > 0)
- {
- if ((*comp) (pent, prgb))
- {
- if (client >= 0)
- pent->refcnt++;
- *pPixel = pixel;
- switch(channel)
- {
- case REDMAP:
- *pPixel <<= pmap->pVisual->offsetRed;
- case PSEUDOMAP:
- break;
- case GREENMAP:
- *pPixel <<= pmap->pVisual->offsetGreen;
- break;
- case BLUEMAP:
- *pPixel <<= pmap->pVisual->offsetBlue;
- break;
- }
- goto gotit;
- }
- }
- else if (!foundFree && pent->refcnt == 0)
- {
- Free = pixel;
- foundFree = TRUE;
- /* If we're initializing the colormap, then we are looking for
- * the first free cell we can find, not to minimize the number
- * of entries we use. So don't look any further. */
- if(pmap->flags & BeingCreated)
- break;
- }
- pixel++;
- if(pixel >= size)
- {
- pent = pentFirst;
- pixel = 0;
- }
- else
- pent++;
- }
-
- /* If we got here, we didn't find a match. If we also didn't find
- * a free entry, we're out of luck. Otherwise, we'll usurp a free
- * entry and fill it in */
- if (!foundFree)
- return (BadAlloc);
- pent = pentFirst + Free;
- pent->fShared = FALSE;
- pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
-
- switch (channel)
- {
- case PSEUDOMAP:
- pent->co.local.red = prgb->red;
- pent->co.local.green = prgb->green;
- pent->co.local.blue = prgb->blue;
- def.red = prgb->red;
- def.green = prgb->green;
- def.blue = prgb->blue;
- def.flags = (DoRed|DoGreen|DoBlue);
- if (client >= 0)
- pmap->freeRed--;
- def.pixel = Free;
- break;
-
- case REDMAP:
- pent->co.local.red = prgb->red;
- def.red = prgb->red;
- def.green = pmap->green[0].co.local.green;
- def.blue = pmap->blue[0].co.local.blue;
- def.flags = DoRed;
- if (client >= 0)
- pmap->freeRed--;
- def.pixel = Free << pmap->pVisual->offsetRed;
- break;
-
- case GREENMAP:
- pent->co.local.green = prgb->green;
- def.red = pmap->red[0].co.local.red;
- def.green = prgb->green;
- def.blue = pmap->blue[0].co.local.blue;
- def.flags = DoGreen;
- if (client >= 0)
- pmap->freeGreen--;
- def.pixel = Free << pmap->pVisual->offsetGreen;
- break;
-
- case BLUEMAP:
- pent->co.local.blue = prgb->blue;
- def.red = pmap->red[0].co.local.red;
- def.green = pmap->green[0].co.local.green;
- def.blue = prgb->blue;
- def.flags = DoBlue;
- if (client >= 0)
- pmap->freeBlue--;
- def.pixel = Free << pmap->pVisual->offsetBlue;
- break;
- }
- (*pmap->pScreen->StoreColors) (pmap, 1, &def);
- pixel = Free;
- *pPixel = def.pixel;
-
-gotit:
- if (pmap->flags & BeingCreated || client == -1)
- return(Success);
- /* Now remember the pixel, for freeing later */
- switch (channel)
- {
- case PSEUDOMAP:
- case REDMAP:
- nump = pmap->numPixelsRed;
- pixp = pmap->clientPixelsRed;
- break;
-
- case GREENMAP:
- nump = pmap->numPixelsGreen;
- pixp = pmap->clientPixelsGreen;
- break;
-
- case BLUEMAP:
- nump = pmap->numPixelsBlue;
- pixp = pmap->clientPixelsBlue;
- break;
- }
- npix = nump[client];
- ppix = (Pixel *) realloc(pixp[client], (npix + 1) * sizeof(Pixel));
- if (!ppix)
- {
- pent->refcnt--;
- if (!pent->fShared)
- switch (channel)
- {
- case PSEUDOMAP:
- case REDMAP:
- pmap->freeRed++;
- break;
- case GREENMAP:
- pmap->freeGreen++;
- break;
- case BLUEMAP:
- pmap->freeBlue++;
- break;
- }
- return(BadAlloc);
- }
- ppix[npix] = pixel;
- pixp[client] = ppix;
- nump[client]++;
-
- return(Success);
-}
-
-/* Comparison functions -- passed to FindColor to determine if an
- * entry is already the color we're looking for or not */
-static int
-AllComp (EntryPtr pent, xrgb *prgb)
-{
- if((pent->co.local.red == prgb->red) &&
- (pent->co.local.green == prgb->green) &&
- (pent->co.local.blue == prgb->blue) )
- return (1);
- return (0);
-}
-
-static int
-RedComp (EntryPtr pent, xrgb *prgb)
-{
- if (pent->co.local.red == prgb->red)
- return (1);
- return (0);
-}
-
-static int
-GreenComp (EntryPtr pent, xrgb *prgb)
-{
- if (pent->co.local.green == prgb->green)
- return (1);
- return (0);
-}
-
-static int
-BlueComp (EntryPtr pent, xrgb *prgb)
-{
- if (pent->co.local.blue == prgb->blue)
- return (1);
- return (0);
-}
-
-
-/* Read the color value of a cell */
-
-int
-QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList, ClientPtr client)
-{
- Pixel *ppix, pixel;
- xrgb *prgb;
- VisualPtr pVisual;
- EntryPtr pent;
- Pixel i;
- int errVal = Success;
-
- pVisual = pmap->pVisual;
- if ((pmap->class | DynamicClass) == DirectColor)
- {
- int numred, numgreen, numblue;
- Pixel rgbbad;
-
- numred = NUMRED(pVisual);
- numgreen = NUMGREEN(pVisual);
- numblue = NUMBLUE(pVisual);
- rgbbad = ~RGBMASK(pVisual);
- for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
- {
- pixel = *ppix;
- if (pixel & rgbbad) {
- client->errorValue = pixel;
- errVal = BadValue;
- continue;
- }
- i = (pixel & pVisual->redMask) >> pVisual->offsetRed;
- if (i >= numred)
- {
- client->errorValue = pixel;
- errVal = BadValue;
- continue;
- }
- prgb->red = pmap->red[i].co.local.red;
- i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
- if (i >= numgreen)
- {
- client->errorValue = pixel;
- errVal = BadValue;
- continue;
- }
- prgb->green = pmap->green[i].co.local.green;
- i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
- if (i >= numblue)
- {
- client->errorValue = pixel;
- errVal = BadValue;
- continue;
- }
- prgb->blue = pmap->blue[i].co.local.blue;
- }
- }
- else
- {
- for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
- {
- pixel = *ppix;
- if (pixel >= pVisual->ColormapEntries)
- {
- client->errorValue = pixel;
- errVal = BadValue;
- }
- else
- {
- pent = (EntryPtr)&pmap->red[pixel];
- if (pent->fShared)
- {
- prgb->red = pent->co.shco.red->color;
- prgb->green = pent->co.shco.green->color;
- prgb->blue = pent->co.shco.blue->color;
- }
- else
- {
- prgb->red = pent->co.local.red;
- prgb->green = pent->co.local.green;
- prgb->blue = pent->co.local.blue;
- }
- }
- }
- }
- return (errVal);
-}
-
-static void
-FreePixels(ColormapPtr pmap, int client)
-{
- Pixel *ppix, *ppixStart;
- int n;
- int class;
-
- class = pmap->class;
- ppixStart = pmap->clientPixelsRed[client];
- if (class & DynamicClass)
- {
- n = pmap->numPixelsRed[client];
- for (ppix = ppixStart; --n >= 0; )
- {
- FreeCell(pmap, *ppix, REDMAP);
- ppix++;
- }
- }
-
- free(ppixStart);
- pmap->clientPixelsRed[client] = (Pixel *) NULL;
- pmap->numPixelsRed[client] = 0;
- if ((class | DynamicClass) == DirectColor)
- {
- ppixStart = pmap->clientPixelsGreen[client];
- if (class & DynamicClass)
- for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
- FreeCell(pmap, *ppix++, GREENMAP);
- free(ppixStart);
- pmap->clientPixelsGreen[client] = (Pixel *) NULL;
- pmap->numPixelsGreen[client] = 0;
-
- ppixStart = pmap->clientPixelsBlue[client];
- if (class & DynamicClass)
- for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
- FreeCell(pmap, *ppix++, BLUEMAP);
- free(ppixStart);
- pmap->clientPixelsBlue[client] = (Pixel *) NULL;
- pmap->numPixelsBlue[client] = 0;
- }
-}
-
-/**
- * Frees all of a client's colors and cells.
- *
- * \param value must conform to DeleteType
- * \unused fakeid
- */
-int
-FreeClientPixels (pointer value, XID fakeid)
-{
- pointer pmap;
- colorResource *pcr = value;
- int rc;
-
- rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient,
- DixRemoveAccess);
- if (rc == Success)
- FreePixels((ColormapPtr)pmap, pcr->client);
- free(pcr);
- return Success;
-}
-
-int
-AllocColorCells (int client, ColormapPtr pmap, int colors, int planes,
- Bool contig, Pixel *ppix, Pixel *masks)
-{
- Pixel rmask, gmask, bmask, *ppixFirst, r, g, b;
- int n, class;
- int ok;
- int oldcount;
- colorResource *pcr = (colorResource *)NULL;
-
- class = pmap->class;
- if (!(class & DynamicClass))
- return (BadAlloc); /* Shouldn't try on this type */
- oldcount = pmap->numPixelsRed[client];
- if (pmap->class == DirectColor)
- oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
- if (!oldcount && (CLIENT_ID(pmap->mid) != client))
- {
- pcr = malloc(sizeof(colorResource));
- if (!pcr)
- return (BadAlloc);
- }
-
- if (pmap->class == DirectColor)
- {
- ok = AllocDirect (client, pmap, colors, planes, planes, planes,
- contig, ppix, &rmask, &gmask, &bmask);
- if(ok == Success)
- {
- for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
- {
- while(!(rmask & r))
- r += r;
- while(!(gmask & g))
- g += g;
- while(!(bmask & b))
- b += b;
- *masks++ = r | g | b;
- }
- }
- }
- else
- {
- ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
- &ppixFirst);
- if(ok == Success)
- {
- for (r = 1, n = planes; --n >= 0; r += r)
- {
- while(!(rmask & r))
- r += r;
- *masks++ = r;
- }
- }
- }
-
- /* if this is the client's first pixels in this colormap, tell the
- * resource manager that the client has pixels in this colormap which
- * should be freed when the client dies */
- if ((ok == Success) && pcr)
- {
- pcr->mid = pmap->mid;
- pcr->client = client;
- if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
- ok = BadAlloc;
- } else if (pcr)
- free(pcr);
-
- return (ok);
-}
-
-
-int
-AllocColorPlanes (int client, ColormapPtr pmap, int colors,
- int r, int g, int b, Bool contig, Pixel *pixels,
- Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
-{
- int ok;
- Pixel mask, *ppixFirst;
- Pixel shift;
- int i;
- int class;
- int oldcount;
- colorResource *pcr = (colorResource *)NULL;
-
- class = pmap->class;
- if (!(class & DynamicClass))
- return (BadAlloc); /* Shouldn't try on this type */
- oldcount = pmap->numPixelsRed[client];
- if (class == DirectColor)
- oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
- if (!oldcount && (CLIENT_ID(pmap->mid) != client))
- {
- pcr = malloc(sizeof(colorResource));
- if (!pcr)
- return (BadAlloc);
- }
-
- if (class == DirectColor)
- {
- ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
- prmask, pgmask, pbmask);
- }
- else
- {
- /* Allocate the proper pixels */
- /* XXX This is sort of bad, because of contig is set, we force all
- * r + g + b bits to be contiguous. Should only force contiguity
- * per mask
- */
- ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
- &mask, &ppixFirst);
-
- if(ok == Success)
- {
- /* now split that mask into three */
- *prmask = *pgmask = *pbmask = 0;
- shift = 1;
- for (i = r; --i >= 0; shift += shift)
- {
- while (!(mask & shift))
- shift += shift;
- *prmask |= shift;
- }
- for (i = g; --i >= 0; shift += shift)
- {
- while (!(mask & shift))
- shift += shift;
- *pgmask |= shift;
- }
- for (i = b; --i >= 0; shift += shift)
- {
- while (!(mask & shift))
- shift += shift;
- *pbmask |= shift;
- }
-
- /* set up the shared color cells */
- if (!AllocShared(pmap, pixels, colors, r, g, b,
- *prmask, *pgmask, *pbmask, ppixFirst))
- {
- (void)FreeColors(pmap, client, colors, pixels, mask);
- ok = BadAlloc;
- }
- }
- }
-
- /* if this is the client's first pixels in this colormap, tell the
- * resource manager that the client has pixels in this colormap which
- * should be freed when the client dies */
- if ((ok == Success) && pcr)
- {
- pcr->mid = pmap->mid;
- pcr->client = client;
- if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
- ok = BadAlloc;
- } else if (pcr)
- free(pcr);
-
- return (ok);
-}
-
-static int
-AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig,
- Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
-{
- Pixel *ppixRed, *ppixGreen, *ppixBlue;
- Pixel *ppix, *pDst, *p;
- int npix, npixR, npixG, npixB;
- Bool okR, okG, okB;
- Pixel *rpix = 0, *gpix = 0, *bpix = 0;
-
- npixR = c << r;
- npixG = c << g;
- npixB = c << b;
- if ((r >= 32) || (g >= 32) || (b >= 32) ||
- (npixR > pmap->freeRed) || (npixR < c) ||
- (npixG > pmap->freeGreen) || (npixG < c) ||
- (npixB > pmap->freeBlue) || (npixB < c))
- return BadAlloc;
-
- /* start out with empty pixels */
- for(p = pixels; p < pixels + c; p++)
- *p = 0;
-
- ppixRed = malloc(npixR * sizeof(Pixel));
- ppixGreen = malloc(npixG * sizeof(Pixel));
- ppixBlue = malloc(npixB * sizeof(Pixel));
- if (!ppixRed || !ppixGreen || !ppixBlue)
- {
- if (ppixBlue) free(ppixBlue);
- if (ppixGreen) free(ppixGreen);
- if (ppixRed) free(ppixRed);
- return(BadAlloc);
- }
-
- okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
- okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
- okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
-
- if (okR && okG && okB)
- {
- rpix = (Pixel *) realloc(pmap->clientPixelsRed[client],
- (pmap->numPixelsRed[client] + (c << r)) *
- sizeof(Pixel));
- if (rpix)
- pmap->clientPixelsRed[client] = rpix;
- gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
- (pmap->numPixelsGreen[client] + (c << g)) *
- sizeof(Pixel));
- if (gpix)
- pmap->clientPixelsGreen[client] = gpix;
- bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
- (pmap->numPixelsBlue[client] + (c << b)) *
- sizeof(Pixel));
- if (bpix)
- pmap->clientPixelsBlue[client] = bpix;
- }
-
- if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
- {
- if (okR)
- for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
- pmap->red[*ppix].refcnt = 0;
- if (okG)
- for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
- pmap->green[*ppix].refcnt = 0;
- if (okB)
- for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
- pmap->blue[*ppix].refcnt = 0;
- free(ppixBlue);
- free(ppixGreen);
- free(ppixRed);
- return(BadAlloc);
- }
-
- *prmask <<= pmap->pVisual->offsetRed;
- *pgmask <<= pmap->pVisual->offsetGreen;
- *pbmask <<= pmap->pVisual->offsetBlue;
-
- ppix = rpix + pmap->numPixelsRed[client];
- for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
- {
- *ppix++ = *p;
- if(p < ppixRed + c)
- *pDst++ |= *p << pmap->pVisual->offsetRed;
- }
- pmap->numPixelsRed[client] += npixR;
- pmap->freeRed -= npixR;
-
- ppix = gpix + pmap->numPixelsGreen[client];
- for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
- {
- *ppix++ = *p;
- if(p < ppixGreen + c)
- *pDst++ |= *p << pmap->pVisual->offsetGreen;
- }
- pmap->numPixelsGreen[client] += npixG;
- pmap->freeGreen -= npixG;
-
- ppix = bpix + pmap->numPixelsBlue[client];
- for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
- {
- *ppix++ = *p;
- if(p < ppixBlue + c)
- *pDst++ |= *p << pmap->pVisual->offsetBlue;
- }
- pmap->numPixelsBlue[client] += npixB;
- pmap->freeBlue -= npixB;
-
-
- for (pDst = pixels; pDst < pixels + c; pDst++)
- *pDst |= ALPHAMASK(pmap->pVisual);
-
- free(ppixBlue);
- free(ppixGreen);
- free(ppixRed);
-
- return (Success);
-}
-
-static int
-AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig,
- Pixel *pixels, Pixel *pmask, Pixel **pppixFirst)
-{
- Pixel *ppix, *p, *pDst, *ppixTemp;
- int npix;
- Bool ok;
-
- npix = c << r;
- if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
- return(BadAlloc);
- if(!(ppixTemp = malloc(npix * sizeof(Pixel))))
- return(BadAlloc);
- ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
-
- if (ok)
- {
-
- /* all the allocated pixels are added to the client pixel list,
- * but only the unique ones are returned to the client */
- ppix = (Pixel *)realloc(pmap->clientPixelsRed[client],
- (pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
- if (!ppix)
- {
- for (p = ppixTemp; p < ppixTemp + npix; p++)
- pmap->red[*p].refcnt = 0;
- return (BadAlloc);
- }
- pmap->clientPixelsRed[client] = ppix;
- ppix += pmap->numPixelsRed[client];
- *pppixFirst = ppix;
- pDst = pixels;
- for (p = ppixTemp; p < ppixTemp + npix; p++)
- {
- *ppix++ = *p;
- if(p < ppixTemp + c)
- *pDst++ = *p;
- }
- pmap->numPixelsRed[client] += npix;
- pmap->freeRed -= npix;
- }
- free(ppixTemp);
- return (ok ? Success : BadAlloc);
-}
-
-/* Allocates count << planes pixels from colormap pmap for client. If
- * contig, then the plane mask is made of consecutive bits. Returns
- * all count << pixels in the array pixels. The first count of those
- * pixels are the unique pixels. *pMask has the mask to Or with the
- * unique pixels to get the rest of them.
- *
- * Returns True iff all pixels could be allocated
- * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
- * (see AllocShared for why we care)
- */
-static Bool
-AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes,
- Bool contig, Pixel *pixels, Pixel *pMask)
-{
- EntryPtr ent;
- Pixel pixel, base, entries, maxp, save;
- int dplanes, found;
- Pixel *ppix;
- Pixel mask;
- Pixel finalmask;
-
- dplanes = pmap->pVisual->nplanes;
-
- /* Easy case. Allocate pixels only */
- if (planes == 0)
- {
- /* allocate writable entries */
- ppix = pixels;
- ent = pentFirst;
- pixel = 0;
- while (--count >= 0)
- {
- /* Just find count unallocated cells */
- while (ent->refcnt)
- {
- ent++;
- pixel++;
- }
- ent->refcnt = AllocPrivate;
- *ppix++ = pixel;
- ent->fShared = FALSE;
- }
- *pMask = 0;
- return (TRUE);
- }
- else if (planes > dplanes)
- {
- return (FALSE);
- }
-
- /* General case count pixels * 2 ^ planes cells to be allocated */
-
- /* make room for new pixels */
- ent = pentFirst;
-
- /* first try for contiguous planes, since it's fastest */
- for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
- --dplanes >= 0;
- mask += mask, base += base)
- {
- ppix = pixels;
- found = 0;
- pixel = 0;
- entries = pmap->pVisual->ColormapEntries - mask;
- while (pixel < entries)
- {
- save = pixel;
- maxp = pixel + mask + base;
- /* check if all are free */
- while (pixel != maxp && ent[pixel].refcnt == 0)
- pixel += base;
- if (pixel == maxp)
- {
- /* this one works */
- *ppix++ = save;
- found++;
- if (found == count)
- {
- /* found enough, allocate them all */
- while (--count >= 0)
- {
- pixel = pixels[count];
- maxp = pixel + mask;
- while (1)
- {
- ent[pixel].refcnt = AllocPrivate;
- ent[pixel].fShared = FALSE;
- if (pixel == maxp)
- break;
- pixel += base;
- *ppix++ = pixel;
- }
- }
- *pMask = mask;
- return (TRUE);
- }
- }
- pixel = save + 1;
- if (pixel & mask)
- pixel += mask;
- }
- }
-
- dplanes = pmap->pVisual->nplanes;
- if (contig || planes == 1 || dplanes < 3)
- return (FALSE);
-
- /* this will be very slow for large maps, need a better algorithm */
-
- /*
- we can generate the smallest and largest numbers that fits in dplanes
- bits and contain exactly planes bits set as follows. First, we need to
- check that it is possible to generate such a mask at all.
- (Non-contiguous masks need one more bit than contiguous masks). Then
- the smallest such mask consists of the rightmost planes-1 bits set, then
- a zero, then a one in position planes + 1. The formula is
- (3 << (planes-1)) -1
- The largest such masks consists of the leftmost planes-1 bits set, then
- a zero, then a one bit in position dplanes-planes-1. If dplanes is
- smaller than 32 (the number of bits in a word) then the formula is:
- (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
- If dplanes = 32, then we can't calculate (1<<dplanes) and we have
- to use:
- ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
-
- << Thank you, Loretta>>>
-
- */
-
- finalmask =
- (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
- (((Pixel)1)<<(dplanes-planes-1));
- for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
- {
- /* next 3 magic statements count number of ones (HAKMEM #169) */
- pixel = (mask >> 1) & 033333333333;
- pixel = mask - pixel - ((pixel >> 1) & 033333333333);
- if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
- continue;
- ppix = pixels;
- found = 0;
- entries = pmap->pVisual->ColormapEntries - mask;
- base = lowbit (mask);
- for (pixel = 0; pixel < entries; pixel++)
- {
- if (pixel & mask)
- continue;
- maxp = 0;
- /* check if all are free */
- while (ent[pixel + maxp].refcnt == 0)
- {
- GetNextBitsOrBreak(maxp, mask, base);
- }
- if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
- continue;
- /* this one works */
- *ppix++ = pixel;
- found++;
- if (found < count)
- continue;
- /* found enough, allocate them all */
- while (--count >= 0)
- {
- pixel = (pixels)[count];
- maxp = 0;
- while (1)
- {
- ent[pixel + maxp].refcnt = AllocPrivate;
- ent[pixel + maxp].fShared = FALSE;
- GetNextBitsOrBreak(maxp, mask, base);
- *ppix++ = pixel + maxp;
- }
- }
-
- *pMask = mask;
- return (TRUE);
- }
- }
- return (FALSE);
-}
-
-/**
- *
- * \param ppixFirst First of the client's new pixels
- */
-static Bool
-AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b,
- Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst)
-{
- Pixel *pptr, *cptr;
- int npix, z, npixClientNew, npixShared;
- Pixel basemask, base, bits, common;
- SHAREDCOLOR *pshared, **ppshared, **psharedList;
-
- npixClientNew = c << (r + g + b);
- npixShared = (c << r) + (c << g) + (c << b);
- psharedList = malloc(npixShared * sizeof(SHAREDCOLOR *));
- if (!psharedList)
- return FALSE;
- ppshared = psharedList;
- for (z = npixShared; --z >= 0; )
- {
- if (!(ppshared[z] = malloc(sizeof(SHAREDCOLOR))))
- {
- for (z++ ; z < npixShared; z++)
- free(ppshared[z]);
- return FALSE;
- }
- }
- for(pptr = ppix, npix = c; --npix >= 0; pptr++)
- {
- basemask = ~(gmask | bmask);
- common = *pptr & basemask;
- if (rmask)
- {
- bits = 0;
- base = lowbit (rmask);
- while(1)
- {
- pshared = *ppshared++;
- pshared->refcnt = 1 << (g + b);
- for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
- {
- if ((*cptr & basemask) == (common | bits))
- {
- pmap->red[*cptr].fShared = TRUE;
- pmap->red[*cptr].co.shco.red = pshared;
- }
- }
- GetNextBitsOrBreak(bits, rmask, base);
- }
- }
- else
- {
- pshared = *ppshared++;
- pshared->refcnt = 1 << (g + b);
- for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
- {
- if ((*cptr & basemask) == common)
- {
- pmap->red[*cptr].fShared = TRUE;
- pmap->red[*cptr].co.shco.red = pshared;
- }
- }
- }
- basemask = ~(rmask | bmask);
- common = *pptr & basemask;
- if (gmask)
- {
- bits = 0;
- base = lowbit (gmask);
- while(1)
- {
- pshared = *ppshared++;
- pshared->refcnt = 1 << (r + b);
- for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
- {
- if ((*cptr & basemask) == (common | bits))
- {
- pmap->red[*cptr].co.shco.green = pshared;
- }
- }
- GetNextBitsOrBreak(bits, gmask, base);
- }
- }
- else
- {
- pshared = *ppshared++;
- pshared->refcnt = 1 << (g + b);
- for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
- {
- if ((*cptr & basemask) == common)
- {
- pmap->red[*cptr].co.shco.green = pshared;
- }
- }
- }
- basemask = ~(rmask | gmask);
- common = *pptr & basemask;
- if (bmask)
- {
- bits = 0;
- base = lowbit (bmask);
- while(1)
- {
- pshared = *ppshared++;
- pshared->refcnt = 1 << (r + g);
- for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
- {
- if ((*cptr & basemask) == (common | bits))
- {
- pmap->red[*cptr].co.shco.blue = pshared;
- }
- }
- GetNextBitsOrBreak(bits, bmask, base);
- }
- }
- else
- {
- pshared = *ppshared++;
- pshared->refcnt = 1 << (g + b);
- for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
- {
- if ((*cptr & basemask) == common)
- {
- pmap->red[*cptr].co.shco.blue = pshared;
- }
- }
- }
- }
- free(psharedList);
- return TRUE;
-}
-
-
-/** FreeColors
- * Free colors and/or cells (probably slow for large numbers)
- */
-int
-FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask)
-{
- int rval, result, class;
- Pixel rmask;
-
- class = pmap->class;
- if (pmap->flags & AllAllocated)
- return(BadAccess);
- if ((class | DynamicClass) == DirectColor)
- {
- rmask = mask & RGBMASK(pmap->pVisual);
- result = FreeCo(pmap, client, REDMAP, count, pixels,
- mask & pmap->pVisual->redMask);
- /* If any of the three calls fails, we must report that, if more
- * than one fails, it's ok that we report the last one */
- rval = FreeCo(pmap, client, GREENMAP, count, pixels,
- mask & pmap->pVisual->greenMask);
- if(rval != Success)
- result = rval;
- rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
- mask & pmap->pVisual->blueMask);
- if(rval != Success)
- result = rval;
- }
- else
- {
- rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
- result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
- }
- if ((mask != rmask) && count)
- {
- clients[client]->errorValue = *pixels | mask;
- result = BadValue;
- }
- /* XXX should worry about removing any RT_CMAPENTRY resource */
- return (result);
-}
-
-/**
- * Helper for FreeColors -- frees all combinations of *newpixels and mask bits
- * which the client has allocated in channel colormap cells of pmap.
- * doesn't change newpixels if it doesn't need to
- *
- * \param pmap which colormap head
- * \param color which sub-map, eg, RED, BLUE, PSEUDO
- * \param npixIn number of pixels passed in
- * \param ppixIn number of base pixels
- * \param mask mask client gave us
- */
-static int
-FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask)
-{
- Pixel *ppixClient, pixTest;
- int npixClient, npixNew, npix;
- Pixel bits, base, cmask, rgbbad;
- Pixel *pptr, *cptr;
- int n, zapped;
- int errVal = Success;
- int offset, numents;
-
- if (npixIn == 0)
- return (errVal);
- bits = 0;
- zapped = 0;
- base = lowbit (mask);
-
- switch(color)
- {
- case REDMAP:
- cmask = pmap->pVisual->redMask;
- rgbbad = ~RGBMASK(pmap->pVisual);
- offset = pmap->pVisual->offsetRed;
- numents = (cmask >> offset) + 1;
- ppixClient = pmap->clientPixelsRed[client];
- npixClient = pmap->numPixelsRed[client];
- break;
- case GREENMAP:
- cmask = pmap->pVisual->greenMask;
- rgbbad = ~RGBMASK(pmap->pVisual);
- offset = pmap->pVisual->offsetGreen;
- numents = (cmask >> offset) + 1;
- ppixClient = pmap->clientPixelsGreen[client];
- npixClient = pmap->numPixelsGreen[client];
- break;
- case BLUEMAP:
- cmask = pmap->pVisual->blueMask;
- rgbbad = ~RGBMASK(pmap->pVisual);
- offset = pmap->pVisual->offsetBlue;
- numents = (cmask >> offset) + 1;
- ppixClient = pmap->clientPixelsBlue[client];
- npixClient = pmap->numPixelsBlue[client];
- break;
- default: /* so compiler can see that everything gets initialized */
- case PSEUDOMAP:
- cmask = ~((Pixel)0);
- rgbbad = 0;
- offset = 0;
- numents = pmap->pVisual->ColormapEntries;
- ppixClient = pmap->clientPixelsRed[client];
- npixClient = pmap->numPixelsRed[client];
- break;
- }
-
-
- /* zap all pixels which match */
- while (1)
- {
- /* go through pixel list */
- for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
- {
- pixTest = ((*pptr | bits) & cmask) >> offset;
- if ((pixTest >= numents) || (*pptr & rgbbad))
- {
- clients[client]->errorValue = *pptr | bits;
- errVal = BadValue;
- continue;
- }
-
- /* find match in client list */
- for (cptr = ppixClient, npix = npixClient;
- --npix >= 0 && *cptr != pixTest;
- cptr++) ;
-
- if (npix >= 0)
- {
- if (pmap->class & DynamicClass)
- {
- FreeCell(pmap, pixTest, color);
- }
- *cptr = ~((Pixel)0);
- zapped++;
- }
- else
- errVal = BadAccess;
- }
- /* generate next bits value */
- GetNextBitsOrBreak(bits, mask, base);
- }
-
- /* delete freed pixels from client pixel list */
- if (zapped)
- {
- npixNew = npixClient - zapped;
- if (npixNew)
- {
- /* Since the list can only get smaller, we can do a copy in
- * place and then realloc to a smaller size */
- pptr = cptr = ppixClient;
-
- /* If we have all the new pixels, we don't have to examine the
- * rest of the old ones */
- for(npix = 0; npix < npixNew; cptr++)
- {
- if (*cptr != ~((Pixel)0))
- {
- *pptr++ = *cptr;
- npix++;
- }
- }
- pptr = (Pixel *)realloc(ppixClient, npixNew * sizeof(Pixel));
- if (pptr)
- ppixClient = pptr;
- npixClient = npixNew;
- }
- else
- {
- npixClient = 0;
- free(ppixClient);
- ppixClient = (Pixel *)NULL;
- }
- switch(color)
- {
- case PSEUDOMAP:
- case REDMAP:
- pmap->clientPixelsRed[client] = ppixClient;
- pmap->numPixelsRed[client] = npixClient;
- break;
- case GREENMAP:
- pmap->clientPixelsGreen[client] = ppixClient;
- pmap->numPixelsGreen[client] = npixClient;
- break;
- case BLUEMAP:
- pmap->clientPixelsBlue[client] = ppixClient;
- pmap->numPixelsBlue[client] = npixClient;
- break;
- }
- }
- return (errVal);
-}
-
-
-
-/* Redefine color values */
-int
-StoreColors (ColormapPtr pmap, int count, xColorItem *defs, ClientPtr client)
-{
- Pixel pix;
- xColorItem *pdef;
- EntryPtr pent, pentT, pentLast;
- VisualPtr pVisual;
- SHAREDCOLOR *pred, *pgreen, *pblue;
- int n, ChgRed, ChgGreen, ChgBlue, idef;
- int class, errVal = Success;
- int ok;
-
-
- class = pmap->class;
- if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
- {
- return(BadAccess);
- }
- pVisual = pmap->pVisual;
-
- idef = 0;
- if((class | DynamicClass) == DirectColor)
- {
- int numred, numgreen, numblue;
- Pixel rgbbad;
-
- numred = NUMRED(pVisual);
- numgreen = NUMGREEN(pVisual);
- numblue = NUMBLUE(pVisual);
- rgbbad = ~RGBMASK(pVisual);
- for (pdef = defs, n = 0; n < count; pdef++, n++)
- {
- ok = TRUE;
- (*pmap->pScreen->ResolveColor)
- (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
-
- if (pdef->pixel & rgbbad)
- {
- errVal = BadValue;
- client->errorValue = pdef->pixel;
- continue;
- }
- pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
- if (pix >= numred)
- {
- errVal = BadValue;
- ok = FALSE;
- }
- else if (pmap->red[pix].refcnt != AllocPrivate)
- {
- errVal = BadAccess;
- ok = FALSE;
- }
- else if (pdef->flags & DoRed)
- {
- pmap->red[pix].co.local.red = pdef->red;
- }
- else
- {
- pdef->red = pmap->red[pix].co.local.red;
- }
-
- pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
- if (pix >= numgreen)
- {
- errVal = BadValue;
- ok = FALSE;
- }
- else if (pmap->green[pix].refcnt != AllocPrivate)
- {
- errVal = BadAccess;
- ok = FALSE;
- }
- else if (pdef->flags & DoGreen)
- {
- pmap->green[pix].co.local.green = pdef->green;
- }
- else
- {
- pdef->green = pmap->green[pix].co.local.green;
- }
-
- pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
- if (pix >= numblue)
- {
- errVal = BadValue;
- ok = FALSE;
- }
- else if (pmap->blue[pix].refcnt != AllocPrivate)
- {
- errVal = BadAccess;
- ok = FALSE;
- }
- else if (pdef->flags & DoBlue)
- {
- pmap->blue[pix].co.local.blue = pdef->blue;
- }
- else
- {
- pdef->blue = pmap->blue[pix].co.local.blue;
- }
- /* If this is an o.k. entry, then it gets added to the list
- * to be sent to the hardware. If not, skip it. Once we've
- * skipped one, we have to copy all the others.
- */
- if(ok)
- {
- if(idef != n)
- defs[idef] = defs[n];
- idef++;
- } else
- client->errorValue = pdef->pixel;
- }
- }
- else
- {
- for (pdef = defs, n = 0; n < count; pdef++, n++)
- {
-
- ok = TRUE;
- if (pdef->pixel >= pVisual->ColormapEntries)
- {
- client->errorValue = pdef->pixel;
- errVal = BadValue;
- ok = FALSE;
- }
- else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
- {
- errVal = BadAccess;
- ok = FALSE;
- }
-
- /* If this is an o.k. entry, then it gets added to the list
- * to be sent to the hardware. If not, skip it. Once we've
- * skipped one, we have to copy all the others.
- */
- if(ok)
- {
- if(idef != n)
- defs[idef] = defs[n];
- idef++;
- }
- else
- continue;
-
- (*pmap->pScreen->ResolveColor)
- (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
-
- pent = &pmap->red[pdef->pixel];
-
- if(pdef->flags & DoRed)
- {
- if(pent->fShared)
- {
- pent->co.shco.red->color = pdef->red;
- if (pent->co.shco.red->refcnt > 1)
- ok = FALSE;
- }
- else
- pent->co.local.red = pdef->red;
- }
- else
- {
- if(pent->fShared)
- pdef->red = pent->co.shco.red->color;
- else
- pdef->red = pent->co.local.red;
- }
- if(pdef->flags & DoGreen)
- {
- if(pent->fShared)
- {
- pent->co.shco.green->color = pdef->green;
- if (pent->co.shco.green->refcnt > 1)
- ok = FALSE;
- }
- else
- pent->co.local.green = pdef->green;
- }
- else
- {
- if(pent->fShared)
- pdef->green = pent->co.shco.green->color;
- else
- pdef->green = pent->co.local.green;
- }
- if(pdef->flags & DoBlue)
- {
- if(pent->fShared)
- {
- pent->co.shco.blue->color = pdef->blue;
- if (pent->co.shco.blue->refcnt > 1)
- ok = FALSE;
- }
- else
- pent->co.local.blue = pdef->blue;
- }
- else
- {
- if(pent->fShared)
- pdef->blue = pent->co.shco.blue->color;
- else
- pdef->blue = pent->co.local.blue;
- }
-
- if(!ok)
- {
- /* have to run through the colormap and change anybody who
- * shares this value */
- pred = pent->co.shco.red;
- pgreen = pent->co.shco.green;
- pblue = pent->co.shco.blue;
- ChgRed = pdef->flags & DoRed;
- ChgGreen = pdef->flags & DoGreen;
- ChgBlue = pdef->flags & DoBlue;
- pentLast = pmap->red + pVisual->ColormapEntries;
-
- for(pentT = pmap->red; pentT < pentLast; pentT++)
- {
- if(pentT->fShared && (pentT != pent))
- {
- xColorItem defChg;
-
- /* There are, alas, devices in this world too dumb
- * to read their own hardware colormaps. Sick, but
- * true. So we're going to be really nice and load
- * the xColorItem with the proper value for all the
- * fields. We will only set the flags for those
- * fields that actually change. Smart devices can
- * arrange to change only those fields. Dumb devices
- * can rest assured that we have provided for them,
- * and can change all three fields */
-
- defChg.flags = 0;
- if(ChgRed && pentT->co.shco.red == pred)
- {
- defChg.flags |= DoRed;
- }
- if(ChgGreen && pentT->co.shco.green == pgreen)
- {
- defChg.flags |= DoGreen;
- }
- if(ChgBlue && pentT->co.shco.blue == pblue)
- {
- defChg.flags |= DoBlue;
- }
- if(defChg.flags != 0)
- {
- defChg.pixel = pentT - pmap->red;
- defChg.red = pentT->co.shco.red->color;
- defChg.green = pentT->co.shco.green->color;
- defChg.blue = pentT->co.shco.blue->color;
- (*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
- }
- }
- }
-
- }
- }
- }
- /* Note that we use idef, the count of acceptable entries, and not
- * count, the count of proposed entries */
- if (idef != 0)
- ( *pmap->pScreen->StoreColors) (pmap, idef, defs);
- return (errVal);
-}
-
-int
-IsMapInstalled(Colormap map, WindowPtr pWin)
-{
- Colormap *pmaps;
- int imap, nummaps, found;
-
- pmaps = malloc(pWin->drawable.pScreen->maxInstalledCmaps*sizeof(Colormap));
- if(!pmaps)
- return(FALSE);
- nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
- (pWin->drawable.pScreen, pmaps);
- found = FALSE;
- for(imap = 0; imap < nummaps; imap++)
- {
- if(pmaps[imap] == map)
- {
- found = TRUE;
- break;
- }
- }
- free(pmaps);
- return (found);
-}
-
-struct colormap_lookup_data {
- ScreenPtr pScreen;
- VisualPtr visuals;
-};
-
-static void _colormap_find_resource(pointer value, XID id,
- pointer cdata)
-{
- struct colormap_lookup_data *cmap_data = cdata;
- VisualPtr visuals = cmap_data->visuals;
- ScreenPtr pScreen = cmap_data->pScreen;
- ColormapPtr cmap = value;
- int j;
-
- if (pScreen != cmap->pScreen)
- return;
-
- j = cmap->pVisual - pScreen->visuals;
- cmap->pVisual = &visuals[j];
-}
-
-/* something has realloced the visuals, instead of breaking
- ABI fix it up here - glx and compsite did this wrong */
-Bool
-ResizeVisualArray(ScreenPtr pScreen, int new_visual_count,
- DepthPtr depth)
-{
- struct colormap_lookup_data cdata;
- int numVisuals;
- VisualPtr visuals;
- XID *vids, vid;
- int first_new_vid, first_new_visual, i;
-
- first_new_vid = depth->numVids;
- first_new_visual = pScreen->numVisuals;
-
- vids = realloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID));
- if (!vids)
- return FALSE;
-
- /* its realloced now no going back if we fail the next one */
- depth->vids = vids;
-
- numVisuals = pScreen->numVisuals + new_visual_count;
- visuals = realloc(pScreen->visuals, numVisuals * sizeof(VisualRec));
- if (!visuals) {
- return FALSE;
- }
-
- cdata.visuals = visuals;
- cdata.pScreen = pScreen;
- FindClientResourcesByType(serverClient, RT_COLORMAP, _colormap_find_resource, &cdata);
-
- pScreen->visuals = visuals;
-
- for (i = 0; i < new_visual_count; i++) {
- vid = FakeClientID(0);
- pScreen->visuals[first_new_visual + i].vid = vid;
- vids[first_new_vid + i] = vid;
- }
-
- depth->numVids += new_visual_count;
- pScreen->numVisuals += new_visual_count;
-
- return TRUE;
-}
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "misc.h"
+#include "dix.h"
+#include "dixstruct.h"
+#include "colormapst.h"
+#include "os.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "windowstr.h"
+#include "privates.h"
+#include "xace.h"
+
+#ifdef _MSC_VER
+#define UpdateColors thisUpdateColors
+#endif
+
+static Pixel FindBestPixel(
+ EntryPtr /*pentFirst*/,
+ int /*size*/,
+ xrgb * /*prgb*/,
+ int /*channel*/
+);
+
+static int AllComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int RedComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int GreenComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int BlueComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static void FreePixels(
+ ColormapPtr /*pmap*/,
+ int /*client*/
+);
+
+static void CopyFree(
+ int /*channel*/,
+ int /*client*/,
+ ColormapPtr /*pmapSrc*/,
+ ColormapPtr /*pmapDst*/
+);
+
+static void FreeCell(
+ ColormapPtr /*pmap*/,
+ Pixel /*i*/,
+ int /*channel*/
+);
+
+static void UpdateColors(
+ ColormapPtr /*pmap*/
+);
+
+static int AllocDirect(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*prmask*/,
+ Pixel * /*pgmask*/,
+ Pixel * /*pbmask*/
+);
+
+static int AllocPseudo(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pmask*/,
+ Pixel ** /*pppixFirst*/
+);
+
+static Bool AllocCP(
+ ColormapPtr /*pmap*/,
+ EntryPtr /*pentFirst*/,
+ int /*count*/,
+ int /*planes*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pMask*/
+);
+
+static Bool AllocShared(
+ ColormapPtr /*pmap*/,
+ Pixel * /*ppix*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Pixel /*rmask*/,
+ Pixel /*gmask*/,
+ Pixel /*bmask*/,
+ Pixel * /*ppixFirst*/
+);
+
+static int FreeCo(
+ ColormapPtr /*pmap*/,
+ int /*client*/,
+ int /*color*/,
+ int /*npixIn*/,
+ Pixel * /*ppixIn*/,
+ Pixel /*mask*/
+);
+
+static int TellNoMap(
+ WindowPtr /*pwin*/,
+ Colormap * /*pmid*/
+);
+
+static void FindColorInRootCmap (
+ ColormapPtr /* pmap */,
+ EntryPtr /* pentFirst */,
+ int /* size */,
+ xrgb* /* prgb */,
+ Pixel* /* pPixel */,
+ int /* channel */,
+ ColorCompareProcPtr /* comp */
+);
+
+#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
+#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
+#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
+#if COMPOSITE
+#define ALPHAMASK(vis) ((vis)->nplanes < 32 ? 0 : \
+ (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask))
+#else
+#define ALPHAMASK(vis) 0
+#endif
+
+#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
+
+/* GetNextBitsOrBreak(bits, mask, base) --
+ * (Suggestion: First read the macro, then read this explanation.
+ *
+ * Either generate the next value to OR in to a pixel or break out of this
+ * while loop
+ *
+ * This macro is used when we're trying to generate all 2^n combinations of
+ * bits in mask. What we're doing here is counting in binary, except that
+ * the bits we use to count may not be contiguous. This macro will be
+ * called 2^n times, returning a different value in bits each time. Then
+ * it will cause us to break out of a surrounding loop. (It will always be
+ * called from within a while loop.)
+ * On call: mask is the value we want to find all the combinations for
+ * base has 1 bit set where the least significant bit of mask is set
+ *
+ * For example,if mask is 01010, base should be 0010 and we count like this:
+ * 00010 (see this isn't so hard),
+ * then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
+ * we add that to bits getting (0100 + 0100) =
+ * 01000 for our next value.
+ * then we add 0010 to get
+ * 01010 and we're done (easy as 1, 2, 3)
+ */
+#define GetNextBitsOrBreak(bits, mask, base) \
+ if((bits) == (mask)) \
+ break; \
+ (bits) += (base); \
+ while((bits) & ~(mask)) \
+ (bits) += ((bits) & ~(mask));
+/* ID of server as client */
+#define SERVER_ID 0
+
+typedef struct _colorResource
+{
+ Colormap mid;
+ int client;
+} colorResource;
+
+/* Invariants:
+ * refcnt == 0 means entry is empty
+ * refcnt > 0 means entry is useable by many clients, so it can't be changed
+ * refcnt == AllocPrivate means entry owned by one client only
+ * fShared should only be set if refcnt == AllocPrivate, and only in red map
+ */
+
+
+/**
+ * Create and initialize the color map
+ *
+ * \param mid resource to use for this colormap
+ * \param alloc 1 iff all entries are allocated writable
+ */
+int
+CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
+ ColormapPtr *ppcmap, int alloc, int client)
+{
+ int class, size;
+ unsigned long sizebytes;
+ ColormapPtr pmap;
+ EntryPtr pent;
+ int i;
+ Pixel *ppix, **pptr;
+
+ class = pVisual->class;
+ if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
+ return (BadMatch);
+
+ size = pVisual->ColormapEntries;
+ sizebytes = (size * sizeof(Entry)) +
+ (MAXCLIENTS * sizeof(Pixel *)) +
+ (MAXCLIENTS * sizeof(int));
+ if ((class | DynamicClass) == DirectColor)
+ sizebytes *= 3;
+ sizebytes += sizeof(ColormapRec);
+ pmap = malloc(sizebytes);
+ if (!pmap)
+ return (BadAlloc);
+#if defined(_XSERVER64)
+ pmap->pad0 = 0;
+ pmap->pad1 = 0;
+#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
+ pmap->pad2 = 0;
+#endif
+#endif
+ pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));
+ sizebytes = size * sizeof(Entry);
+ pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
+ pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->mid = mid;
+ pmap->flags = 0; /* start out with all flags clear */
+ if(mid == pScreen->defColormap)
+ pmap->flags |= IsDefault;
+ pmap->pScreen = pScreen;
+ pmap->pVisual = pVisual;
+ pmap->class = class;
+ if ((class | DynamicClass) == DirectColor)
+ size = NUMRED(pVisual);
+ pmap->freeRed = size;
+ bzero ((char *) pmap->red, (int)sizebytes);
+ bzero((char *) pmap->numPixelsRed, MAXCLIENTS * sizeof(int));
+ for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
+ *pptr = (Pixel *)NULL;
+ if (alloc == AllocAll)
+ {
+ if (class & DynamicClass)
+ pmap->flags |= AllAllocated;
+ for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeRed = 0;
+ ppix = malloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ free(pmap);
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsRed[client] = size;
+ }
+
+ if ((class | DynamicClass) == DirectColor)
+ {
+ pmap->freeGreen = NUMGREEN(pVisual);
+ pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
+ pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->freeBlue = NUMBLUE(pVisual);
+ pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
+ pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
+ (MAXCLIENTS * sizeof(Pixel *)));
+
+ bzero ((char *) pmap->green, (int)sizebytes);
+ bzero ((char *) pmap->blue, (int)sizebytes);
+
+ memmove((char *) pmap->clientPixelsGreen,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ memmove((char *) pmap->clientPixelsBlue,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ bzero((char *) pmap->numPixelsGreen, MAXCLIENTS * sizeof(int));
+ bzero((char *) pmap->numPixelsBlue, MAXCLIENTS * sizeof(int));
+
+ /* If every cell is allocated, mark its refcnt */
+ if (alloc == AllocAll)
+ {
+ size = pmap->freeGreen;
+ for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeGreen = 0;
+ ppix = malloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ free(pmap->clientPixelsRed[client]);
+ free(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsGreen[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsGreen[client] = size;
+
+ size = pmap->freeBlue;
+ for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeBlue = 0;
+ ppix = malloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ free(pmap->clientPixelsGreen[client]);
+ free(pmap->clientPixelsRed[client]);
+ free(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsBlue[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsBlue[client] = size;
+ }
+ }
+ pmap->devPrivates = NULL;
+ pmap->flags |= BeingCreated;
+
+ if (!AddResource(mid, RT_COLORMAP, (pointer)pmap))
+ return (BadAlloc);
+
+ /*
+ * Security creation/labeling check
+ */
+ i = XaceHook(XACE_RESOURCE_ACCESS, clients[client], mid, RT_COLORMAP,
+ pmap, RT_NONE, NULL, DixCreateAccess);
+ if (i != Success) {
+ FreeResource(mid, RT_NONE);
+ return i;
+ }
+
+ /* If the device wants a chance to initialize the colormap in any way,
+ * this is it. In specific, if this is a Static colormap, this is the
+ * time to fill in the colormap's values */
+ if (!(*pScreen->CreateColormap)(pmap))
+ {
+ FreeResource (mid, RT_NONE);
+ return BadAlloc;
+ }
+ pmap->flags &= ~BeingCreated;
+ *ppcmap = pmap;
+ return (Success);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeColormap (pointer value, XID mid)
+{
+ int i;
+ EntryPtr pent;
+ ColormapPtr pmap = (ColormapPtr)value;
+
+ if(CLIENT_ID(mid) != SERVER_ID)
+ {
+ (*pmap->pScreen->UninstallColormap) (pmap);
+ WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid);
+ }
+
+ /* This is the device's chance to undo anything it needs to, especially
+ * to free any storage it allocated */
+ (*pmap->pScreen->DestroyColormap)(pmap);
+
+ if(pmap->clientPixelsRed)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ free(pmap->clientPixelsRed[i]);
+ }
+
+ if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
+ {
+ for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
+ pent >= pmap->red;
+ pent--)
+ {
+ if(pent->fShared)
+ {
+ if (--pent->co.shco.red->refcnt == 0)
+ free(pent->co.shco.red);
+ if (--pent->co.shco.green->refcnt == 0)
+ free(pent->co.shco.green);
+ if (--pent->co.shco.blue->refcnt == 0)
+ free(pent->co.shco.blue);
+ }
+ }
+ }
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ {
+ free(pmap->clientPixelsGreen[i]);
+ free(pmap->clientPixelsBlue[i]);
+ }
+ }
+
+ dixFreePrivates(pmap->devPrivates);
+ free(pmap);
+ return(Success);
+}
+
+/* Tell window that pmid has disappeared */
+static int
+TellNoMap (WindowPtr pwin, Colormap *pmid)
+{
+ xEvent xE;
+
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = None;
+ xE.u.colormap.new = TRUE;
+ xE.u.colormap.state = ColormapUninstalled;
+#ifdef PANORAMIX
+ if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
+#endif
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ if (pwin->optional) {
+ pwin->optional->colormap = None;
+ CheckWindowOptionalNeed (pwin);
+ }
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got uninstalled */
+int
+TellLostMap (WindowPtr pwin, pointer value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapUninstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got installed */
+int
+TellGainedMap (WindowPtr pwin, pointer value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap (pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapInstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+
+int
+CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client)
+{
+ ColormapPtr pmap = (ColormapPtr) NULL;
+ int result, alloc, size;
+ Colormap midSrc;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+
+ pScreen = pSrc->pScreen;
+ pVisual = pSrc->pVisual;
+ midSrc = pSrc->mid;
+ alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
+ AllocAll : AllocNone;
+ size = pVisual->ColormapEntries;
+
+ /* If the create returns non-0, it failed */
+ result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
+ if(result != Success)
+ return(result);
+ if(alloc == AllocAll)
+ {
+ memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
+ memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
+ }
+ pSrc->flags &= ~AllAllocated;
+ FreePixels(pSrc, client);
+ UpdateColors(pmap);
+ return(Success);
+ }
+
+ CopyFree(REDMAP, client, pSrc, pmap);
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ CopyFree(GREENMAP, client, pSrc, pmap);
+ CopyFree(BLUEMAP, client, pSrc, pmap);
+ }
+ if (pmap->class & DynamicClass)
+ UpdateColors(pmap);
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return(Success);
+}
+
+/* Helper routine for freeing large numbers of cells from a map */
+static void
+CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst)
+{
+ int z, npix;
+ EntryPtr pentSrcFirst, pentDstFirst;
+ EntryPtr pentSrc, pentDst;
+ Pixel *ppix;
+ int nalloc;
+
+ switch(channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case REDMAP:
+ ppix = (pmapSrc->clientPixelsRed)[client];
+ npix = (pmapSrc->numPixelsRed)[client];
+ pentSrcFirst = pmapSrc->red;
+ pentDstFirst = pmapDst->red;
+ break;
+ case GREENMAP:
+ ppix = (pmapSrc->clientPixelsGreen)[client];
+ npix = (pmapSrc->numPixelsGreen)[client];
+ pentSrcFirst = pmapSrc->green;
+ pentDstFirst = pmapDst->green;
+ break;
+ case BLUEMAP:
+ ppix = (pmapSrc->clientPixelsBlue)[client];
+ npix = (pmapSrc->numPixelsBlue)[client];
+ pentSrcFirst = pmapSrc->blue;
+ pentDstFirst = pmapDst->blue;
+ break;
+ }
+ nalloc = 0;
+ if (pmapSrc->class & DynamicClass)
+ {
+ for(z = npix; --z >= 0; ppix++)
+ {
+ /* Copy entries */
+ pentSrc = pentSrcFirst + *ppix;
+ pentDst = pentDstFirst + *ppix;
+ if (pentDst->refcnt > 0)
+ {
+ pentDst->refcnt++;
+ }
+ else
+ {
+ *pentDst = *pentSrc;
+ nalloc++;
+ if (pentSrc->refcnt > 0)
+ pentDst->refcnt = 1;
+ else
+ pentSrc->fShared = FALSE;
+ }
+ FreeCell(pmapSrc, *ppix, channel);
+ }
+ }
+
+ /* Note that FreeCell has already fixed pmapSrc->free{Color} */
+ switch(channel)
+ {
+ case REDMAP:
+ pmapDst->freeRed -= nalloc;
+ (pmapDst->clientPixelsRed)[client] =
+ (pmapSrc->clientPixelsRed)[client];
+ (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
+ (pmapSrc->numPixelsRed)[client] = 0;
+ break;
+ case GREENMAP:
+ pmapDst->freeGreen -= nalloc;
+ (pmapDst->clientPixelsGreen)[client] =
+ (pmapSrc->clientPixelsGreen)[client];
+ (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
+ (pmapSrc->numPixelsGreen)[client] = 0;
+ break;
+ case BLUEMAP:
+ pmapDst->freeBlue -= nalloc;
+ pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
+ pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
+ pmapSrc->numPixelsBlue[client] = 0;
+ break;
+ }
+}
+
+/* Free the ith entry in a color map. Must handle freeing of
+ * colors allocated through AllocColorPlanes */
+static void
+FreeCell (ColormapPtr pmap, Pixel i, int channel)
+{
+ EntryPtr pent;
+ int *pCount;
+
+
+ switch (channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ case REDMAP:
+ pent = (EntryPtr) &pmap->red[i];
+ pCount = &pmap->freeRed;
+ break;
+ case GREENMAP:
+ pent = (EntryPtr) &pmap->green[i];
+ pCount = &pmap->freeGreen;
+ break;
+ case BLUEMAP:
+ pent = (EntryPtr) &pmap->blue[i];
+ pCount = &pmap->freeBlue;
+ break;
+ }
+ /* If it's not privately allocated and it's not time to free it, just
+ * decrement the count */
+ if (pent->refcnt > 1)
+ pent->refcnt--;
+ else
+ {
+ /* If the color type is shared, find the sharedcolor. If decremented
+ * refcnt is 0, free the shared cell. */
+ if (pent->fShared)
+ {
+ if(--pent->co.shco.red->refcnt == 0)
+ free(pent->co.shco.red);
+ if(--pent->co.shco.green->refcnt == 0)
+ free(pent->co.shco.green);
+ if(--pent->co.shco.blue->refcnt == 0)
+ free(pent->co.shco.blue);
+ pent->fShared = FALSE;
+ }
+ pent->refcnt = 0;
+ *pCount += 1;
+ }
+}
+
+static void
+UpdateColors (ColormapPtr pmap)
+{
+ xColorItem *defs;
+ xColorItem *pdef;
+ EntryPtr pent;
+ VisualPtr pVisual;
+ int i, n, size;
+
+ pVisual = pmap->pVisual;
+ size = pVisual->ColormapEntries;
+ defs = malloc(size * sizeof(xColorItem));
+ if (!defs)
+ return;
+ n = 0;
+ pdef = defs;
+ if (pmap->class == DirectColor)
+ {
+ for (i = 0; i < size; i++)
+ {
+ if (!pmap->red[i].refcnt &&
+ !pmap->green[i].refcnt &&
+ !pmap->blue[i].refcnt)
+ continue;
+ pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
+ ((Pixel)i << pVisual->offsetGreen) |
+ ((Pixel)i << pVisual->offsetBlue);
+ pdef->red = pmap->red[i].co.local.red;
+ pdef->green = pmap->green[i].co.local.green;
+ pdef->blue = pmap->blue[i].co.local.blue;
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ else
+ {
+ for (i = 0, pent = pmap->red; i < size; i++, pent++)
+ {
+ if (!pent->refcnt)
+ continue;
+ pdef->pixel = i;
+ if(pent->fShared)
+ {
+ pdef->red = pent->co.shco.red->color;
+ pdef->green = pent->co.shco.green->color;
+ pdef->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ pdef->red = pent->co.local.red;
+ pdef->green = pent->co.local.green;
+ pdef->blue = pent->co.local.blue;
+ }
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ if (n)
+ (*pmap->pScreen->StoreColors)(pmap, n, defs);
+ free(defs);
+}
+
+/* Get a read-only color from a ColorMap (probably slow for large maps)
+ * Returns by changing the value in pred, pgreen, pblue and pPix
+ */
+int
+AllocColor (ColormapPtr pmap,
+ unsigned short *pred, unsigned short *pgreen, unsigned short *pblue,
+ Pixel *pPix, int client)
+{
+ Pixel pixR, pixG, pixB;
+ int entries;
+ xrgb rgb;
+ int class;
+ VisualPtr pVisual;
+ int npix;
+ Pixel *ppix;
+
+ pVisual = pmap->pVisual;
+ (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
+ rgb.red = *pred;
+ rgb.green = *pgreen;
+ rgb.blue = *pblue;
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ /* If the colormap is being created, then we want to be able to change
+ * the colormap, even if it's a static type. Otherwise, we'd never be
+ * able to initialize static colormaps
+ */
+ if(pmap->flags & BeingCreated)
+ class |= DynamicClass;
+
+ /* If this is one of the static storage classes, and we're not initializing
+ * it, the best we can do is to find the closest color entry to the
+ * requested one and return that.
+ */
+ switch (class) {
+ case StaticColor:
+ case StaticGray:
+ /* Look up all three components in the same pmap */
+ *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->red[pixR].co.local.green;
+ *pblue = pmap->red[pixR].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ *pPix = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue) |
+ ALPHAMASK(pVisual);
+
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->green[pixG].co.local.green;
+ *pblue = pmap->blue[pixB].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ npix = pmap->numPixelsGreen[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixG;
+ pmap->clientPixelsGreen[client] = ppix;
+ npix = pmap->numPixelsBlue[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixB;
+ pmap->clientPixelsBlue[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ pmap->numPixelsGreen[client]++;
+ pmap->numPixelsBlue[client]++;
+ break;
+
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap;
+ dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
+ RT_COLORMAP, clients[client], DixReadAccess);
+
+ if (pmap->class == prootmap->class)
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ pPix, PSEUDOMAP, AllComp);
+ }
+ if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
+ client, AllComp) != Success)
+ return (BadAlloc);
+ break;
+
+ case DirectColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap;
+ dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
+ RT_COLORMAP, clients[client], DixReadAccess);
+
+ if (pmap->class == prootmap->class)
+ {
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ &pixR, REDMAP, RedComp);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb,
+ &pixG, GREENMAP, GreenComp);
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb,
+ &pixB, BLUEMAP, BlueComp);
+ *pPix = pixR | pixG | pixB;
+ }
+ }
+
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ client, RedComp) != Success)
+ return (BadAlloc);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, client, GreenComp) != Success)
+ {
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ client, BlueComp) != Success)
+ {
+ (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ *pPix = pixR | pixG | pixB | ALPHAMASK(pVisual);
+
+ break;
+ }
+
+ /* if this is the client's first pixel in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((pmap->numPixelsRed[client] == 1) &&
+ (CLIENT_ID(pmap->mid) != client) &&
+ !(pmap->flags & BeingCreated))
+ {
+ colorResource *pcr;
+
+ pcr = malloc(sizeof(colorResource));
+ if (!pcr)
+ {
+ (void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
+ return (BadAlloc);
+ }
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ return (BadAlloc);
+ }
+ return (Success);
+}
+
+/*
+ * FakeAllocColor -- fake an AllocColor request by
+ * returning a free pixel if availible, otherwise returning
+ * the closest matching pixel. This is used by the mi
+ * software sprite code to recolor cursors. A nice side-effect
+ * is that this routine will never return failure.
+ */
+
+void
+FakeAllocColor (ColormapPtr pmap, xColorItem *item)
+{
+ Pixel pixR, pixG, pixB;
+ Pixel temp;
+ int entries;
+ xrgb rgb;
+ int class;
+ VisualPtr pVisual;
+
+ pVisual = pmap->pVisual;
+ rgb.red = item->red;
+ rgb.green = item->green;
+ rgb.blue = item->blue;
+ (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ switch (class) {
+ case GrayScale:
+ case PseudoColor:
+ temp = 0;
+ item->pixel = 0;
+ if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
+ -1, AllComp) == Success) {
+ item->pixel = temp;
+ break;
+ }
+ /* fall through ... */
+ case StaticColor:
+ case StaticGray:
+ item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ break;
+
+ case DirectColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ -1, RedComp) != Success)
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
+ << pVisual->offsetRed;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, -1, GreenComp) != Success)
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
+ GREENMAP) << pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ -1, BlueComp) != Success)
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
+ << pVisual->offsetBlue;
+ item->pixel = pixR | pixG | pixB;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ item->pixel = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue);
+ break;
+ }
+}
+
+/* free a pixel value obtained from FakeAllocColor */
+void
+FakeFreeColor(ColormapPtr pmap, Pixel pixel)
+{
+ VisualPtr pVisual;
+ Pixel pixR, pixG, pixB;
+
+ switch (pmap->class) {
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->red[pixel].refcnt == AllocTemporary)
+ pmap->red[pixel].refcnt = 0;
+ break;
+ case DirectColor:
+ pVisual = pmap->pVisual;
+ pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pmap->red[pixR].refcnt == AllocTemporary)
+ pmap->red[pixR].refcnt = 0;
+ if (pmap->green[pixG].refcnt == AllocTemporary)
+ pmap->green[pixG].refcnt = 0;
+ if (pmap->blue[pixB].refcnt == AllocTemporary)
+ pmap->blue[pixB].refcnt = 0;
+ break;
+ }
+}
+
+typedef unsigned short BigNumUpper;
+typedef unsigned long BigNumLower;
+
+#define BIGNUMLOWERBITS 24
+#define BIGNUMUPPERBITS 16
+#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
+#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
+#define UPPERPART(i) ((i) >> BIGNUMLOWERBITS)
+#define LOWERPART(i) ((i) & (BIGNUMLOWER - 1))
+
+typedef struct _bignum {
+ BigNumUpper upper;
+ BigNumLower lower;
+} BigNumRec, *BigNumPtr;
+
+#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
+ ((x)->upper == (y)->upper && (x)->lower > (y)->lower))
+
+#define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \
+ ((r)->lower = LOWERPART(u)))
+
+#define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \
+ ((r)->lower = BIGNUMLOWER-1))
+
+static void
+BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
+{
+ BigNumLower lower, carry = 0;
+
+ lower = x->lower + y->lower;
+ if (lower >= BIGNUMLOWER) {
+ lower -= BIGNUMLOWER;
+ carry = 1;
+ }
+ r->lower = lower;
+ r->upper = x->upper + y->upper + carry;
+}
+
+static Pixel
+FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel)
+{
+ EntryPtr pent;
+ Pixel pixel, final;
+ long dr, dg, db;
+ unsigned long sq;
+ BigNumRec minval, sum, temp;
+
+ final = 0;
+ MaxBigNum(&minval);
+ /* look for the minimal difference */
+ for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
+ {
+ dr = dg = db = 0;
+ switch(channel)
+ {
+ case PSEUDOMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ db = (long) pent->co.local.blue - prgb->blue;
+ case REDMAP:
+ dr = (long) pent->co.local.red - prgb->red;
+ break;
+ case GREENMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ break;
+ case BLUEMAP:
+ db = (long) pent->co.local.blue - prgb->blue;
+ break;
+ }
+ sq = dr * dr;
+ UnsignedToBigNum (sq, &sum);
+ sq = dg * dg;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ sq = db * db;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ if (BigNumGreater (&minval, &sum))
+ {
+ final = pixel;
+ minval = sum;
+ }
+ }
+ return(final);
+}
+
+static void
+FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size,
+ xrgb *prgb, Pixel *pPixel, int channel,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Pixel pixel;
+ int count;
+
+ if ((pixel = *pPixel) >= size)
+ pixel = 0;
+ for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
+ {
+ if (pent->refcnt > 0 && (*comp) (pent, prgb))
+ {
+ switch (channel)
+ {
+ case REDMAP:
+ pixel <<= pmap->pVisual->offsetRed;
+ break;
+ case GREENMAP:
+ pixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ pixel <<= pmap->pVisual->offsetBlue;
+ break;
+ default: /* PSEUDOMAP */
+ break;
+ }
+ *pPixel = pixel;
+ }
+ }
+}
+
+/* Tries to find a color in pmap that exactly matches the one requested in prgb
+ * if it can't it allocates one.
+ * Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
+ * load *pPixel with that value, otherwise set it to 0
+ */
+int
+FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb,
+ Pixel *pPixel, int channel, int client,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Bool foundFree;
+ Pixel pixel, Free = 0;
+ int npix, count, *nump = NULL;
+ Pixel **pixp = NULL, *ppix;
+ xColorItem def;
+
+ foundFree = FALSE;
+
+ if((pixel = *pPixel) >= size)
+ pixel = 0;
+ /* see if there is a match, and also look for a free entry */
+ for (pent = pentFirst + pixel, count = size; --count >= 0; )
+ {
+ if (pent->refcnt > 0)
+ {
+ if ((*comp) (pent, prgb))
+ {
+ if (client >= 0)
+ pent->refcnt++;
+ *pPixel = pixel;
+ switch(channel)
+ {
+ case REDMAP:
+ *pPixel <<= pmap->pVisual->offsetRed;
+ case PSEUDOMAP:
+ break;
+ case GREENMAP:
+ *pPixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ *pPixel <<= pmap->pVisual->offsetBlue;
+ break;
+ }
+ goto gotit;
+ }
+ }
+ else if (!foundFree && pent->refcnt == 0)
+ {
+ Free = pixel;
+ foundFree = TRUE;
+ /* If we're initializing the colormap, then we are looking for
+ * the first free cell we can find, not to minimize the number
+ * of entries we use. So don't look any further. */
+ if(pmap->flags & BeingCreated)
+ break;
+ }
+ pixel++;
+ if(pixel >= size)
+ {
+ pent = pentFirst;
+ pixel = 0;
+ }
+ else
+ pent++;
+ }
+
+ /* If we got here, we didn't find a match. If we also didn't find
+ * a free entry, we're out of luck. Otherwise, we'll usurp a free
+ * entry and fill it in */
+ if (!foundFree)
+ return (BadAlloc);
+ pent = pentFirst + Free;
+ pent->fShared = FALSE;
+ pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
+
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ pent->co.local.red = prgb->red;
+ pent->co.local.green = prgb->green;
+ pent->co.local.blue = prgb->blue;
+ def.red = prgb->red;
+ def.green = prgb->green;
+ def.blue = prgb->blue;
+ def.flags = (DoRed|DoGreen|DoBlue);
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free;
+ break;
+
+ case REDMAP:
+ pent->co.local.red = prgb->red;
+ def.red = prgb->red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoRed;
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free << pmap->pVisual->offsetRed;
+ break;
+
+ case GREENMAP:
+ pent->co.local.green = prgb->green;
+ def.red = pmap->red[0].co.local.red;
+ def.green = prgb->green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoGreen;
+ if (client >= 0)
+ pmap->freeGreen--;
+ def.pixel = Free << pmap->pVisual->offsetGreen;
+ break;
+
+ case BLUEMAP:
+ pent->co.local.blue = prgb->blue;
+ def.red = pmap->red[0].co.local.red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = prgb->blue;
+ def.flags = DoBlue;
+ if (client >= 0)
+ pmap->freeBlue--;
+ def.pixel = Free << pmap->pVisual->offsetBlue;
+ break;
+ }
+ (*pmap->pScreen->StoreColors) (pmap, 1, &def);
+ pixel = Free;
+ *pPixel = def.pixel;
+
+gotit:
+ if (pmap->flags & BeingCreated || client == -1)
+ return(Success);
+ /* Now remember the pixel, for freeing later */
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ nump = pmap->numPixelsRed;
+ pixp = pmap->clientPixelsRed;
+ break;
+
+ case GREENMAP:
+ nump = pmap->numPixelsGreen;
+ pixp = pmap->clientPixelsGreen;
+ break;
+
+ case BLUEMAP:
+ nump = pmap->numPixelsBlue;
+ pixp = pmap->clientPixelsBlue;
+ break;
+ }
+ npix = nump[client];
+ ppix = (Pixel *) realloc(pixp[client], (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ {
+ pent->refcnt--;
+ if (!pent->fShared)
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->freeRed++;
+ break;
+ case GREENMAP:
+ pmap->freeGreen++;
+ break;
+ case BLUEMAP:
+ pmap->freeBlue++;
+ break;
+ }
+ return(BadAlloc);
+ }
+ ppix[npix] = pixel;
+ pixp[client] = ppix;
+ nump[client]++;
+
+ return(Success);
+}
+
+/* Comparison functions -- passed to FindColor to determine if an
+ * entry is already the color we're looking for or not */
+static int
+AllComp (EntryPtr pent, xrgb *prgb)
+{
+ if((pent->co.local.red == prgb->red) &&
+ (pent->co.local.green == prgb->green) &&
+ (pent->co.local.blue == prgb->blue) )
+ return (1);
+ return (0);
+}
+
+static int
+RedComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.red == prgb->red)
+ return (1);
+ return (0);
+}
+
+static int
+GreenComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.green == prgb->green)
+ return (1);
+ return (0);
+}
+
+static int
+BlueComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.blue == prgb->blue)
+ return (1);
+ return (0);
+}
+
+
+/* Read the color value of a cell */
+
+int
+QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList, ClientPtr client)
+{
+ Pixel *ppix, pixel;
+ xrgb *prgb;
+ VisualPtr pVisual;
+ EntryPtr pent;
+ Pixel i;
+ int errVal = Success;
+
+ pVisual = pmap->pVisual;
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel & rgbbad) {
+ client->errorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ i = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (i >= numred)
+ {
+ client->errorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->red = pmap->red[i].co.local.red;
+ i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (i >= numgreen)
+ {
+ client->errorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->green = pmap->green[i].co.local.green;
+ i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (i >= numblue)
+ {
+ client->errorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->blue = pmap->blue[i].co.local.blue;
+ }
+ }
+ else
+ {
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel >= pVisual->ColormapEntries)
+ {
+ client->errorValue = pixel;
+ errVal = BadValue;
+ }
+ else
+ {
+ pent = (EntryPtr)&pmap->red[pixel];
+ if (pent->fShared)
+ {
+ prgb->red = pent->co.shco.red->color;
+ prgb->green = pent->co.shco.green->color;
+ prgb->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ prgb->red = pent->co.local.red;
+ prgb->green = pent->co.local.green;
+ prgb->blue = pent->co.local.blue;
+ }
+ }
+ }
+ }
+ return (errVal);
+}
+
+static void
+FreePixels(ColormapPtr pmap, int client)
+{
+ Pixel *ppix, *ppixStart;
+ int n;
+ int class;
+
+ class = pmap->class;
+ ppixStart = pmap->clientPixelsRed[client];
+ if (class & DynamicClass)
+ {
+ n = pmap->numPixelsRed[client];
+ for (ppix = ppixStart; --n >= 0; )
+ {
+ FreeCell(pmap, *ppix, REDMAP);
+ ppix++;
+ }
+ }
+
+ free(ppixStart);
+ pmap->clientPixelsRed[client] = (Pixel *) NULL;
+ pmap->numPixelsRed[client] = 0;
+ if ((class | DynamicClass) == DirectColor)
+ {
+ ppixStart = pmap->clientPixelsGreen[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
+ FreeCell(pmap, *ppix++, GREENMAP);
+ free(ppixStart);
+ pmap->clientPixelsGreen[client] = (Pixel *) NULL;
+ pmap->numPixelsGreen[client] = 0;
+
+ ppixStart = pmap->clientPixelsBlue[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
+ FreeCell(pmap, *ppix++, BLUEMAP);
+ free(ppixStart);
+ pmap->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmap->numPixelsBlue[client] = 0;
+ }
+}
+
+/**
+ * Frees all of a client's colors and cells.
+ *
+ * \param value must conform to DeleteType
+ * \unused fakeid
+ */
+int
+FreeClientPixels (pointer value, XID fakeid)
+{
+ pointer pmap;
+ colorResource *pcr = value;
+ int rc;
+
+ rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient,
+ DixRemoveAccess);
+ if (rc == Success)
+ FreePixels((ColormapPtr)pmap, pcr->client);
+ free(pcr);
+ return Success;
+}
+
+int
+AllocColorCells (int client, ColormapPtr pmap, int colors, int planes,
+ Bool contig, Pixel *ppix, Pixel *masks)
+{
+ Pixel rmask, gmask, bmask, *ppixFirst, r, g, b;
+ int n, class;
+ int ok;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (pmap->class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = malloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (pmap->class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, planes, planes, planes,
+ contig, ppix, &rmask, &gmask, &bmask);
+ if(ok == Success)
+ {
+ for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
+ {
+ while(!(rmask & r))
+ r += r;
+ while(!(gmask & g))
+ g += g;
+ while(!(bmask & b))
+ b += b;
+ *masks++ = r | g | b;
+ }
+ }
+ }
+ else
+ {
+ ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
+ &ppixFirst);
+ if(ok == Success)
+ {
+ for (r = 1, n = planes; --n >= 0; r += r)
+ {
+ while(!(rmask & r))
+ r += r;
+ *masks++ = r;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ free(pcr);
+
+ return (ok);
+}
+
+
+int
+AllocColorPlanes (int client, ColormapPtr pmap, int colors,
+ int r, int g, int b, Bool contig, Pixel *pixels,
+ Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ int ok;
+ Pixel mask, *ppixFirst;
+ Pixel shift;
+ int i;
+ int class;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = malloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
+ prmask, pgmask, pbmask);
+ }
+ else
+ {
+ /* Allocate the proper pixels */
+ /* XXX This is sort of bad, because of contig is set, we force all
+ * r + g + b bits to be contiguous. Should only force contiguity
+ * per mask
+ */
+ ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
+ &mask, &ppixFirst);
+
+ if(ok == Success)
+ {
+ /* now split that mask into three */
+ *prmask = *pgmask = *pbmask = 0;
+ shift = 1;
+ for (i = r; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *prmask |= shift;
+ }
+ for (i = g; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pgmask |= shift;
+ }
+ for (i = b; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pbmask |= shift;
+ }
+
+ /* set up the shared color cells */
+ if (!AllocShared(pmap, pixels, colors, r, g, b,
+ *prmask, *pgmask, *pbmask, ppixFirst))
+ {
+ (void)FreeColors(pmap, client, colors, pixels, mask);
+ ok = BadAlloc;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ free(pcr);
+
+ return (ok);
+}
+
+static int
+AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig,
+ Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ Pixel *ppixRed, *ppixGreen, *ppixBlue;
+ Pixel *ppix, *pDst, *p;
+ int npix, npixR, npixG, npixB;
+ Bool okR, okG, okB;
+ Pixel *rpix = 0, *gpix = 0, *bpix = 0;
+
+ npixR = c << r;
+ npixG = c << g;
+ npixB = c << b;
+ if ((r >= 32) || (g >= 32) || (b >= 32) ||
+ (npixR > pmap->freeRed) || (npixR < c) ||
+ (npixG > pmap->freeGreen) || (npixG < c) ||
+ (npixB > pmap->freeBlue) || (npixB < c))
+ return BadAlloc;
+
+ /* start out with empty pixels */
+ for(p = pixels; p < pixels + c; p++)
+ *p = 0;
+
+ ppixRed = malloc(npixR * sizeof(Pixel));
+ ppixGreen = malloc(npixG * sizeof(Pixel));
+ ppixBlue = malloc(npixB * sizeof(Pixel));
+ if (!ppixRed || !ppixGreen || !ppixBlue)
+ {
+ if (ppixBlue) free(ppixBlue);
+ if (ppixGreen) free(ppixGreen);
+ if (ppixRed) free(ppixRed);
+ return(BadAlloc);
+ }
+
+ okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
+ okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
+ okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
+
+ if (okR && okG && okB)
+ {
+ rpix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + (c << r)) *
+ sizeof(Pixel));
+ if (rpix)
+ pmap->clientPixelsRed[client] = rpix;
+ gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
+ (pmap->numPixelsGreen[client] + (c << g)) *
+ sizeof(Pixel));
+ if (gpix)
+ pmap->clientPixelsGreen[client] = gpix;
+ bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
+ (pmap->numPixelsBlue[client] + (c << b)) *
+ sizeof(Pixel));
+ if (bpix)
+ pmap->clientPixelsBlue[client] = bpix;
+ }
+
+ if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
+ {
+ if (okR)
+ for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
+ pmap->red[*ppix].refcnt = 0;
+ if (okG)
+ for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
+ pmap->green[*ppix].refcnt = 0;
+ if (okB)
+ for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
+ pmap->blue[*ppix].refcnt = 0;
+ free(ppixBlue);
+ free(ppixGreen);
+ free(ppixRed);
+ return(BadAlloc);
+ }
+
+ *prmask <<= pmap->pVisual->offsetRed;
+ *pgmask <<= pmap->pVisual->offsetGreen;
+ *pbmask <<= pmap->pVisual->offsetBlue;
+
+ ppix = rpix + pmap->numPixelsRed[client];
+ for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixRed + c)
+ *pDst++ |= *p << pmap->pVisual->offsetRed;
+ }
+ pmap->numPixelsRed[client] += npixR;
+ pmap->freeRed -= npixR;
+
+ ppix = gpix + pmap->numPixelsGreen[client];
+ for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixGreen + c)
+ *pDst++ |= *p << pmap->pVisual->offsetGreen;
+ }
+ pmap->numPixelsGreen[client] += npixG;
+ pmap->freeGreen -= npixG;
+
+ ppix = bpix + pmap->numPixelsBlue[client];
+ for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixBlue + c)
+ *pDst++ |= *p << pmap->pVisual->offsetBlue;
+ }
+ pmap->numPixelsBlue[client] += npixB;
+ pmap->freeBlue -= npixB;
+
+
+ for (pDst = pixels; pDst < pixels + c; pDst++)
+ *pDst |= ALPHAMASK(pmap->pVisual);
+
+ free(ppixBlue);
+ free(ppixGreen);
+ free(ppixRed);
+
+ return (Success);
+}
+
+static int
+AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig,
+ Pixel *pixels, Pixel *pmask, Pixel **pppixFirst)
+{
+ Pixel *ppix, *p, *pDst, *ppixTemp;
+ int npix;
+ Bool ok;
+
+ npix = c << r;
+ if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
+ return(BadAlloc);
+ if(!(ppixTemp = malloc(npix * sizeof(Pixel))))
+ return(BadAlloc);
+ ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
+
+ if (ok)
+ {
+
+ /* all the allocated pixels are added to the client pixel list,
+ * but only the unique ones are returned to the client */
+ ppix = (Pixel *)realloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
+ if (!ppix)
+ {
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ pmap->red[*p].refcnt = 0;
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ ppix += pmap->numPixelsRed[client];
+ *pppixFirst = ppix;
+ pDst = pixels;
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixTemp + c)
+ *pDst++ = *p;
+ }
+ pmap->numPixelsRed[client] += npix;
+ pmap->freeRed -= npix;
+ }
+ free(ppixTemp);
+ return (ok ? Success : BadAlloc);
+}
+
+/* Allocates count << planes pixels from colormap pmap for client. If
+ * contig, then the plane mask is made of consecutive bits. Returns
+ * all count << pixels in the array pixels. The first count of those
+ * pixels are the unique pixels. *pMask has the mask to Or with the
+ * unique pixels to get the rest of them.
+ *
+ * Returns True iff all pixels could be allocated
+ * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
+ * (see AllocShared for why we care)
+ */
+static Bool
+AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes,
+ Bool contig, Pixel *pixels, Pixel *pMask)
+{
+ EntryPtr ent;
+ Pixel pixel, base, entries, maxp, save;
+ int dplanes, found;
+ Pixel *ppix;
+ Pixel mask;
+ Pixel finalmask;
+
+ dplanes = pmap->pVisual->nplanes;
+
+ /* Easy case. Allocate pixels only */
+ if (planes == 0)
+ {
+ /* allocate writable entries */
+ ppix = pixels;
+ ent = pentFirst;
+ pixel = 0;
+ while (--count >= 0)
+ {
+ /* Just find count unallocated cells */
+ while (ent->refcnt)
+ {
+ ent++;
+ pixel++;
+ }
+ ent->refcnt = AllocPrivate;
+ *ppix++ = pixel;
+ ent->fShared = FALSE;
+ }
+ *pMask = 0;
+ return (TRUE);
+ }
+ else if (planes > dplanes)
+ {
+ return (FALSE);
+ }
+
+ /* General case count pixels * 2 ^ planes cells to be allocated */
+
+ /* make room for new pixels */
+ ent = pentFirst;
+
+ /* first try for contiguous planes, since it's fastest */
+ for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
+ --dplanes >= 0;
+ mask += mask, base += base)
+ {
+ ppix = pixels;
+ found = 0;
+ pixel = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ while (pixel < entries)
+ {
+ save = pixel;
+ maxp = pixel + mask + base;
+ /* check if all are free */
+ while (pixel != maxp && ent[pixel].refcnt == 0)
+ pixel += base;
+ if (pixel == maxp)
+ {
+ /* this one works */
+ *ppix++ = save;
+ found++;
+ if (found == count)
+ {
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = pixels[count];
+ maxp = pixel + mask;
+ while (1)
+ {
+ ent[pixel].refcnt = AllocPrivate;
+ ent[pixel].fShared = FALSE;
+ if (pixel == maxp)
+ break;
+ pixel += base;
+ *ppix++ = pixel;
+ }
+ }
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ pixel = save + 1;
+ if (pixel & mask)
+ pixel += mask;
+ }
+ }
+
+ dplanes = pmap->pVisual->nplanes;
+ if (contig || planes == 1 || dplanes < 3)
+ return (FALSE);
+
+ /* this will be very slow for large maps, need a better algorithm */
+
+ /*
+ we can generate the smallest and largest numbers that fits in dplanes
+ bits and contain exactly planes bits set as follows. First, we need to
+ check that it is possible to generate such a mask at all.
+ (Non-contiguous masks need one more bit than contiguous masks). Then
+ the smallest such mask consists of the rightmost planes-1 bits set, then
+ a zero, then a one in position planes + 1. The formula is
+ (3 << (planes-1)) -1
+ The largest such masks consists of the leftmost planes-1 bits set, then
+ a zero, then a one bit in position dplanes-planes-1. If dplanes is
+ smaller than 32 (the number of bits in a word) then the formula is:
+ (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
+ If dplanes = 32, then we can't calculate (1<<dplanes) and we have
+ to use:
+ ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
+
+ << Thank you, Loretta>>>
+
+ */
+
+ finalmask =
+ (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
+ (((Pixel)1)<<(dplanes-planes-1));
+ for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
+ {
+ /* next 3 magic statements count number of ones (HAKMEM #169) */
+ pixel = (mask >> 1) & 033333333333;
+ pixel = mask - pixel - ((pixel >> 1) & 033333333333);
+ if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
+ continue;
+ ppix = pixels;
+ found = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ base = lowbit (mask);
+ for (pixel = 0; pixel < entries; pixel++)
+ {
+ if (pixel & mask)
+ continue;
+ maxp = 0;
+ /* check if all are free */
+ while (ent[pixel + maxp].refcnt == 0)
+ {
+ GetNextBitsOrBreak(maxp, mask, base);
+ }
+ if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
+ continue;
+ /* this one works */
+ *ppix++ = pixel;
+ found++;
+ if (found < count)
+ continue;
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = (pixels)[count];
+ maxp = 0;
+ while (1)
+ {
+ ent[pixel + maxp].refcnt = AllocPrivate;
+ ent[pixel + maxp].fShared = FALSE;
+ GetNextBitsOrBreak(maxp, mask, base);
+ *ppix++ = pixel + maxp;
+ }
+ }
+
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ return (FALSE);
+}
+
+/**
+ *
+ * \param ppixFirst First of the client's new pixels
+ */
+static Bool
+AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b,
+ Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst)
+{
+ Pixel *pptr, *cptr;
+ int npix, z, npixClientNew, npixShared;
+ Pixel basemask, base, bits, common;
+ SHAREDCOLOR *pshared, **ppshared, **psharedList;
+
+ npixClientNew = c << (r + g + b);
+ npixShared = (c << r) + (c << g) + (c << b);
+ psharedList = malloc(npixShared * sizeof(SHAREDCOLOR *));
+ if (!psharedList)
+ return FALSE;
+ ppshared = psharedList;
+ for (z = npixShared; --z >= 0; )
+ {
+ if (!(ppshared[z] = malloc(sizeof(SHAREDCOLOR))))
+ {
+ for (z++ ; z < npixShared; z++)
+ free(ppshared[z]);
+ return FALSE;
+ }
+ }
+ for(pptr = ppix, npix = c; --npix >= 0; pptr++)
+ {
+ basemask = ~(gmask | bmask);
+ common = *pptr & basemask;
+ if (rmask)
+ {
+ bits = 0;
+ base = lowbit (rmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, rmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | bmask);
+ common = *pptr & basemask;
+ if (gmask)
+ {
+ bits = 0;
+ base = lowbit (gmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, gmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | gmask);
+ common = *pptr & basemask;
+ if (bmask)
+ {
+ bits = 0;
+ base = lowbit (bmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + g);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, bmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ }
+ }
+ free(psharedList);
+ return TRUE;
+}
+
+
+/** FreeColors
+ * Free colors and/or cells (probably slow for large numbers)
+ */
+int
+FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask)
+{
+ int rval, result, class;
+ Pixel rmask;
+
+ class = pmap->class;
+ if (pmap->flags & AllAllocated)
+ return(BadAccess);
+ if ((class | DynamicClass) == DirectColor)
+ {
+ rmask = mask & RGBMASK(pmap->pVisual);
+ result = FreeCo(pmap, client, REDMAP, count, pixels,
+ mask & pmap->pVisual->redMask);
+ /* If any of the three calls fails, we must report that, if more
+ * than one fails, it's ok that we report the last one */
+ rval = FreeCo(pmap, client, GREENMAP, count, pixels,
+ mask & pmap->pVisual->greenMask);
+ if(rval != Success)
+ result = rval;
+ rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
+ mask & pmap->pVisual->blueMask);
+ if(rval != Success)
+ result = rval;
+ }
+ else
+ {
+ rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
+ result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
+ }
+ if ((mask != rmask) && count)
+ {
+ clients[client]->errorValue = *pixels | mask;
+ result = BadValue;
+ }
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return (result);
+}
+
+/**
+ * Helper for FreeColors -- frees all combinations of *newpixels and mask bits
+ * which the client has allocated in channel colormap cells of pmap.
+ * doesn't change newpixels if it doesn't need to
+ *
+ * \param pmap which colormap head
+ * \param color which sub-map, eg, RED, BLUE, PSEUDO
+ * \param npixIn number of pixels passed in
+ * \param ppixIn number of base pixels
+ * \param mask mask client gave us
+ */
+static int
+FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask)
+{
+ Pixel *ppixClient, pixTest;
+ int npixClient, npixNew, npix;
+ Pixel bits, base, cmask, rgbbad;
+ Pixel *pptr, *cptr;
+ int n, zapped;
+ int errVal = Success;
+ int offset, numents;
+
+ if (npixIn == 0)
+ return (errVal);
+ bits = 0;
+ zapped = 0;
+ base = lowbit (mask);
+
+ switch(color)
+ {
+ case REDMAP:
+ cmask = pmap->pVisual->redMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetRed;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ case GREENMAP:
+ cmask = pmap->pVisual->greenMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetGreen;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsGreen[client];
+ npixClient = pmap->numPixelsGreen[client];
+ break;
+ case BLUEMAP:
+ cmask = pmap->pVisual->blueMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetBlue;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsBlue[client];
+ npixClient = pmap->numPixelsBlue[client];
+ break;
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ cmask = ~((Pixel)0);
+ rgbbad = 0;
+ offset = 0;
+ numents = pmap->pVisual->ColormapEntries;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ }
+
+
+ /* zap all pixels which match */
+ while (1)
+ {
+ /* go through pixel list */
+ for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
+ {
+ pixTest = ((*pptr | bits) & cmask) >> offset;
+ if ((pixTest >= numents) || (*pptr & rgbbad))
+ {
+ clients[client]->errorValue = *pptr | bits;
+ errVal = BadValue;
+ continue;
+ }
+
+ /* find match in client list */
+ for (cptr = ppixClient, npix = npixClient;
+ --npix >= 0 && *cptr != pixTest;
+ cptr++) ;
+
+ if (npix >= 0)
+ {
+ if (pmap->class & DynamicClass)
+ {
+ FreeCell(pmap, pixTest, color);
+ }
+ *cptr = ~((Pixel)0);
+ zapped++;
+ }
+ else
+ errVal = BadAccess;
+ }
+ /* generate next bits value */
+ GetNextBitsOrBreak(bits, mask, base);
+ }
+
+ /* delete freed pixels from client pixel list */
+ if (zapped)
+ {
+ npixNew = npixClient - zapped;
+ if (npixNew)
+ {
+ /* Since the list can only get smaller, we can do a copy in
+ * place and then realloc to a smaller size */
+ pptr = cptr = ppixClient;
+
+ /* If we have all the new pixels, we don't have to examine the
+ * rest of the old ones */
+ for(npix = 0; npix < npixNew; cptr++)
+ {
+ if (*cptr != ~((Pixel)0))
+ {
+ *pptr++ = *cptr;
+ npix++;
+ }
+ }
+ pptr = (Pixel *)realloc(ppixClient, npixNew * sizeof(Pixel));
+ if (pptr)
+ ppixClient = pptr;
+ npixClient = npixNew;
+ }
+ else
+ {
+ npixClient = 0;
+ free(ppixClient);
+ ppixClient = (Pixel *)NULL;
+ }
+ switch(color)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->clientPixelsRed[client] = ppixClient;
+ pmap->numPixelsRed[client] = npixClient;
+ break;
+ case GREENMAP:
+ pmap->clientPixelsGreen[client] = ppixClient;
+ pmap->numPixelsGreen[client] = npixClient;
+ break;
+ case BLUEMAP:
+ pmap->clientPixelsBlue[client] = ppixClient;
+ pmap->numPixelsBlue[client] = npixClient;
+ break;
+ }
+ }
+ return (errVal);
+}
+
+
+
+/* Redefine color values */
+int
+StoreColors (ColormapPtr pmap, int count, xColorItem *defs, ClientPtr client)
+{
+ Pixel pix;
+ xColorItem *pdef;
+ EntryPtr pent, pentT, pentLast;
+ VisualPtr pVisual;
+ SHAREDCOLOR *pred, *pgreen, *pblue;
+ int n, ChgRed, ChgGreen, ChgBlue, idef;
+ int class, errVal = Success;
+ int ok;
+
+
+ class = pmap->class;
+ if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
+ {
+ return(BadAccess);
+ }
+ pVisual = pmap->pVisual;
+
+ idef = 0;
+ if((class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+ ok = TRUE;
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ if (pdef->pixel & rgbbad)
+ {
+ errVal = BadValue;
+ client->errorValue = pdef->pixel;
+ continue;
+ }
+ pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (pix >= numred)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoRed)
+ {
+ pmap->red[pix].co.local.red = pdef->red;
+ }
+ else
+ {
+ pdef->red = pmap->red[pix].co.local.red;
+ }
+
+ pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (pix >= numgreen)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->green[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoGreen)
+ {
+ pmap->green[pix].co.local.green = pdef->green;
+ }
+ else
+ {
+ pdef->green = pmap->green[pix].co.local.green;
+ }
+
+ pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pix >= numblue)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->blue[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoBlue)
+ {
+ pmap->blue[pix].co.local.blue = pdef->blue;
+ }
+ else
+ {
+ pdef->blue = pmap->blue[pix].co.local.blue;
+ }
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ } else
+ client->errorValue = pdef->pixel;
+ }
+ }
+ else
+ {
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+
+ ok = TRUE;
+ if (pdef->pixel >= pVisual->ColormapEntries)
+ {
+ client->errorValue = pdef->pixel;
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ }
+ else
+ continue;
+
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ pent = &pmap->red[pdef->pixel];
+
+ if(pdef->flags & DoRed)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.red->color = pdef->red;
+ if (pent->co.shco.red->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.red = pdef->red;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->red = pent->co.shco.red->color;
+ else
+ pdef->red = pent->co.local.red;
+ }
+ if(pdef->flags & DoGreen)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.green->color = pdef->green;
+ if (pent->co.shco.green->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.green = pdef->green;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->green = pent->co.shco.green->color;
+ else
+ pdef->green = pent->co.local.green;
+ }
+ if(pdef->flags & DoBlue)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.blue->color = pdef->blue;
+ if (pent->co.shco.blue->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.blue = pdef->blue;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->blue = pent->co.shco.blue->color;
+ else
+ pdef->blue = pent->co.local.blue;
+ }
+
+ if(!ok)
+ {
+ /* have to run through the colormap and change anybody who
+ * shares this value */
+ pred = pent->co.shco.red;
+ pgreen = pent->co.shco.green;
+ pblue = pent->co.shco.blue;
+ ChgRed = pdef->flags & DoRed;
+ ChgGreen = pdef->flags & DoGreen;
+ ChgBlue = pdef->flags & DoBlue;
+ pentLast = pmap->red + pVisual->ColormapEntries;
+
+ for(pentT = pmap->red; pentT < pentLast; pentT++)
+ {
+ if(pentT->fShared && (pentT != pent))
+ {
+ xColorItem defChg;
+
+ /* There are, alas, devices in this world too dumb
+ * to read their own hardware colormaps. Sick, but
+ * true. So we're going to be really nice and load
+ * the xColorItem with the proper value for all the
+ * fields. We will only set the flags for those
+ * fields that actually change. Smart devices can
+ * arrange to change only those fields. Dumb devices
+ * can rest assured that we have provided for them,
+ * and can change all three fields */
+
+ defChg.flags = 0;
+ if(ChgRed && pentT->co.shco.red == pred)
+ {
+ defChg.flags |= DoRed;
+ }
+ if(ChgGreen && pentT->co.shco.green == pgreen)
+ {
+ defChg.flags |= DoGreen;
+ }
+ if(ChgBlue && pentT->co.shco.blue == pblue)
+ {
+ defChg.flags |= DoBlue;
+ }
+ if(defChg.flags != 0)
+ {
+ defChg.pixel = pentT - pmap->red;
+ defChg.red = pentT->co.shco.red->color;
+ defChg.green = pentT->co.shco.green->color;
+ defChg.blue = pentT->co.shco.blue->color;
+ (*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ /* Note that we use idef, the count of acceptable entries, and not
+ * count, the count of proposed entries */
+ if (idef != 0)
+ ( *pmap->pScreen->StoreColors) (pmap, idef, defs);
+ return (errVal);
+}
+
+int
+IsMapInstalled(Colormap map, WindowPtr pWin)
+{
+ Colormap *pmaps;
+ int imap, nummaps, found;
+
+ pmaps = malloc(pWin->drawable.pScreen->maxInstalledCmaps*sizeof(Colormap));
+ if(!pmaps)
+ return(FALSE);
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, pmaps);
+ found = FALSE;
+ for(imap = 0; imap < nummaps; imap++)
+ {
+ if(pmaps[imap] == map)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ free(pmaps);
+ return (found);
+}
+
+struct colormap_lookup_data {
+ ScreenPtr pScreen;
+ VisualPtr visuals;
+};
+
+static void _colormap_find_resource(pointer value, XID id,
+ pointer cdata)
+{
+ struct colormap_lookup_data *cmap_data = cdata;
+ VisualPtr visuals = cmap_data->visuals;
+ ScreenPtr pScreen = cmap_data->pScreen;
+ ColormapPtr cmap = value;
+ int j;
+
+ if (pScreen != cmap->pScreen)
+ return;
+
+ j = cmap->pVisual - pScreen->visuals;
+ cmap->pVisual = &visuals[j];
+}
+
+/* something has realloced the visuals, instead of breaking
+ ABI fix it up here - glx and compsite did this wrong */
+Bool
+ResizeVisualArray(ScreenPtr pScreen, int new_visual_count,
+ DepthPtr depth)
+{
+ struct colormap_lookup_data cdata;
+ int numVisuals;
+ VisualPtr visuals;
+ XID *vids, vid;
+ int first_new_vid, first_new_visual, i;
+
+ first_new_vid = depth->numVids;
+ first_new_visual = pScreen->numVisuals;
+
+ vids = realloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID));
+ if (!vids)
+ return FALSE;
+
+ /* its realloced now no going back if we fail the next one */
+ depth->vids = vids;
+
+ numVisuals = pScreen->numVisuals + new_visual_count;
+ visuals = realloc(pScreen->visuals, numVisuals * sizeof(VisualRec));
+ if (!visuals) {
+ return FALSE;
+ }
+
+ cdata.visuals = visuals;
+ cdata.pScreen = pScreen;
+ FindClientResourcesByType(serverClient, RT_COLORMAP, _colormap_find_resource, &cdata);
+
+ pScreen->visuals = visuals;
+
+ for (i = 0; i < new_visual_count; i++) {
+ vid = FakeClientID(0);
+ pScreen->visuals[first_new_visual + i].vid = vid;
+ vids[first_new_vid + i] = vid;
+ }
+
+ depth->numVids += new_visual_count;
+ pScreen->numVisuals += new_visual_count;
+
+ return TRUE;
+}
diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c
index b738d4112..6281f25cd 100644
--- a/xorg-server/dix/gc.c
+++ b/xorg-server/dix/gc.c
@@ -1,1158 +1,1159 @@
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-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 Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL 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.
-
-******************************************************************/
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "resource.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "dixfontstr.h"
-#include "scrnintstr.h"
-#include "region.h"
-
-#include "privates.h"
-#include "dix.h"
-#include "xace.h"
-#include <assert.h>
-
-extern FontPtr defaultFont;
-
-static Bool CreateDefaultTile(GCPtr pGC);
-
-static unsigned char DefaultDash[2] = {4, 4};
-
-void
-ValidateGC(DrawablePtr pDraw, GC *pGC)
-{
- (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
- pGC->stateChanges = 0;
- pGC->serialNumber = pDraw->serialNumber;
-}
-
-
-/*
- * ChangeGC/ChangeGCXIDs:
- *
- * The client performing the gc change must be passed so that access
- * checks can be performed on any tiles, stipples, or fonts that are
- * specified. ddxen can call this too; they should normally pass
- * NullClient for the client since any access checking should have
- * already been done at a higher level.
- *
- * If you have any XIDs, you must use ChangeGCXIDs:
- *
- * CARD32 v[2];
- * v[0] = FillTiled;
- * v[1] = pid;
- * ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v);
- *
- * However, if you need to pass a pointer to a pixmap or font, you must
- * use ChangeGC:
- *
- * ChangeGCVal v[2];
- * v[0].val = FillTiled;
- * v[1].ptr = pPixmap;
- * ChangeGC(client, pGC, GCFillStyle|GCTile, v);
- *
- * If you have neither XIDs nor pointers, you can use either function,
- * but ChangeGC will do less work.
- *
- * ChangeGCVal v[2];
- * v[0].val = foreground;
- * v[1].val = background;
- * ChangeGC(client, pGC, GCForeground|GCBackground, v);
- */
-
-#define NEXTVAL(_type, _var) { \
- _var = (_type)(pUnion->val); pUnion++; \
- }
-
-#define NEXT_PTR(_type, _var) { \
- _var = (_type)pUnion->ptr; pUnion++; }
-
-int
-ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
-{
- BITS32 index2;
- int error = 0;
- PixmapPtr pPixmap;
- BITS32 maskQ;
-
- assert(pUnion);
- pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
-
- maskQ = mask; /* save these for when we walk the GCque */
- while (mask && !error)
- {
- index2 = (BITS32) lowbit (mask);
- mask &= ~index2;
- pGC->stateChanges |= index2;
- switch (index2)
- {
- case GCFunction:
- {
- CARD8 newalu;
- NEXTVAL(CARD8, newalu);
- if (newalu <= GXset)
- pGC->alu = newalu;
- else
- {
- if (client)
- client->errorValue = newalu;
- error = BadValue;
- }
- break;
- }
- case GCPlaneMask:
- NEXTVAL(unsigned long, pGC->planemask);
- break;
- case GCForeground:
- NEXTVAL(unsigned long, pGC->fgPixel);
- /*
- * this is for CreateGC
- */
- if (!pGC->tileIsPixel && !pGC->tile.pixmap)
- {
- pGC->tileIsPixel = TRUE;
- pGC->tile.pixel = pGC->fgPixel;
- }
- break;
- case GCBackground:
- NEXTVAL(unsigned long, pGC->bgPixel);
- break;
- case GCLineWidth: /* ??? line width is a CARD16 */
- NEXTVAL(CARD16, pGC->lineWidth);
- break;
- case GCLineStyle:
- {
- unsigned int newlinestyle;
- NEXTVAL(unsigned int, newlinestyle);
- if (newlinestyle <= LineDoubleDash)
- pGC->lineStyle = newlinestyle;
- else
- {
- if (client)
- client->errorValue = newlinestyle;
- error = BadValue;
- }
- break;
- }
- case GCCapStyle:
- {
- unsigned int newcapstyle;
- NEXTVAL(unsigned int, newcapstyle);
- if (newcapstyle <= CapProjecting)
- pGC->capStyle = newcapstyle;
- else
- {
- if (client)
- client->errorValue = newcapstyle;
- error = BadValue;
- }
- break;
- }
- case GCJoinStyle:
- {
- unsigned int newjoinstyle;
- NEXTVAL(unsigned int, newjoinstyle);
- if (newjoinstyle <= JoinBevel)
- pGC->joinStyle = newjoinstyle;
- else
- {
- if (client)
- client->errorValue = newjoinstyle;
- error = BadValue;
- }
- break;
- }
- case GCFillStyle:
- {
- unsigned int newfillstyle;
- NEXTVAL(unsigned int, newfillstyle);
- if (newfillstyle <= FillOpaqueStippled)
- pGC->fillStyle = newfillstyle;
- else
- {
- if (client)
- client->errorValue = newfillstyle;
- error = BadValue;
- }
- break;
- }
- case GCFillRule:
- {
- unsigned int newfillrule;
- NEXTVAL(unsigned int, newfillrule);
- if (newfillrule <= WindingRule)
- pGC->fillRule = newfillrule;
- else
- {
- if (client)
- client->errorValue = newfillrule;
- error = BadValue;
- }
- break;
- }
- case GCTile:
- NEXT_PTR(PixmapPtr, pPixmap);
- if ((pPixmap->drawable.depth != pGC->depth) ||
- (pPixmap->drawable.pScreen != pGC->pScreen))
- {
- error = BadMatch;
- }
- else
- {
- pPixmap->refcnt++;
- if (!pGC->tileIsPixel)
- (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
- pGC->tileIsPixel = FALSE;
- pGC->tile.pixmap = pPixmap;
- }
- break;
- case GCStipple:
- NEXT_PTR(PixmapPtr, pPixmap);
- if ((pPixmap->drawable.depth != 1) ||
- (pPixmap->drawable.pScreen != pGC->pScreen))
- {
- error = BadMatch;
- }
- else
- {
- pPixmap->refcnt++;
- if (pGC->stipple)
- (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
- pGC->stipple = pPixmap;
- }
- break;
- case GCTileStipXOrigin:
- NEXTVAL(INT16, pGC->patOrg.x);
- break;
- case GCTileStipYOrigin:
- NEXTVAL(INT16, pGC->patOrg.y);
- break;
- case GCFont:
- {
- FontPtr pFont;
- NEXT_PTR(FontPtr, pFont);
- pFont->refcnt++;
- if (pGC->font)
- CloseFont(pGC->font, (Font)0);
- pGC->font = pFont;
- break;
- }
- case GCSubwindowMode:
- {
- unsigned int newclipmode;
- NEXTVAL(unsigned int, newclipmode);
- if (newclipmode <= IncludeInferiors)
- pGC->subWindowMode = newclipmode;
- else
- {
- if (client)
- client->errorValue = newclipmode;
- error = BadValue;
- }
- break;
- }
- case GCGraphicsExposures:
- {
- unsigned int newge;
- NEXTVAL(unsigned int, newge);
- if (newge <= xTrue)
- pGC->graphicsExposures = newge;
- else
- {
- if (client)
- client->errorValue = newge;
- error = BadValue;
- }
- break;
- }
- case GCClipXOrigin:
- NEXTVAL(INT16, pGC->clipOrg.x);
- break;
- case GCClipYOrigin:
- NEXTVAL(INT16, pGC->clipOrg.y);
- break;
- case GCClipMask:
- NEXT_PTR(PixmapPtr, pPixmap);
- if (pPixmap)
- {
- if ((pPixmap->drawable.depth != 1) ||
- (pPixmap->drawable.pScreen != pGC->pScreen))
- {
- error = BadMatch;
- break;
- }
- pPixmap->refcnt++;
- }
- (*pGC->funcs->ChangeClip)(pGC, pPixmap ? CT_PIXMAP : CT_NONE,
- (pointer)pPixmap, 0);
- break;
- case GCDashOffset:
- NEXTVAL(INT16, pGC->dashOffset);
- break;
- case GCDashList:
- {
- CARD8 newdash;
- NEXTVAL(CARD8, newdash);
- if (newdash == 4)
- {
- if (pGC->dash != DefaultDash)
- {
- free(pGC->dash);
- pGC->numInDashList = 2;
- pGC->dash = DefaultDash;
- }
- }
- else if (newdash != 0)
- {
- unsigned char *dash;
-
- dash = malloc(2 * sizeof(unsigned char));
- if (dash)
- {
- if (pGC->dash != DefaultDash)
- free(pGC->dash);
- pGC->numInDashList = 2;
- pGC->dash = dash;
- dash[0] = newdash;
- dash[1] = newdash;
- }
- else
- error = BadAlloc;
- }
- else
- {
- if (client)
- client->errorValue = newdash;
- error = BadValue;
- }
- break;
- }
- case GCArcMode:
- {
- unsigned int newarcmode;
- NEXTVAL(unsigned int, newarcmode);
- if (newarcmode <= ArcPieSlice)
- pGC->arcMode = newarcmode;
- else
- {
- if (client)
- client->errorValue = newarcmode;
- error = BadValue;
- }
- break;
- }
- default:
- if (client)
- client->errorValue = maskQ;
- error = BadValue;
- break;
- }
- } /* end while mask && !error */
-
- if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
- {
- if (!CreateDefaultTile (pGC))
- {
- pGC->fillStyle = FillSolid;
- error = BadAlloc;
- }
- }
- (*pGC->funcs->ChangeGC)(pGC, maskQ);
- return error;
-}
-
-#undef NEXTVAL
-#undef NEXT_PTR
-
-static const struct {
- BITS32 mask;
- RESTYPE type;
- Mask access_mode;
-} xidfields[] = {
- { GCTile, RT_PIXMAP, DixReadAccess },
- { GCStipple, RT_PIXMAP, DixReadAccess },
- { GCFont, RT_FONT, DixUseAccess },
- { GCClipMask, RT_PIXMAP, DixReadAccess },
-};
-
-int
-ChangeGCXIDs(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32)
-{
- ChangeGCVal vals[GCLastBit + 1];
- int i;
- if (mask & ~GCAllBits)
- {
- client->errorValue = mask;
- return BadValue;
- }
- for (i = Ones(mask); i--; )
- vals[i].val = pC32[i];
- for (i = 0; i < sizeof(xidfields) / sizeof(*xidfields); ++i)
- {
- int offset, rc;
- if (!(mask & xidfields[i].mask))
- continue;
- offset = Ones(mask & (xidfields[i].mask - 1));
- if (xidfields[i].mask == GCClipMask && vals[offset].val == None)
- {
- vals[offset].ptr = NullPixmap;
- continue;
- }
- rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val,
- xidfields[i].type, client, xidfields[i].access_mode);
- if (rc != Success)
- {
- client->errorValue = vals[offset].val;
- if (rc == BadValue)
- rc = (xidfields[i].type == RT_PIXMAP) ? BadPixmap : BadFont;
- return rc;
- }
- }
- return ChangeGC(client, pGC, mask, vals);
-}
-
-/* CreateGC(pDrawable, mask, pval, pStatus)
- creates a default GC for the given drawable, using mask to fill
- in any non-default values.
- Returns a pointer to the new GC on success, NULL otherwise.
- returns status of non-default fields in pStatus
-BUG:
- should check for failure to create default tile
-
-*/
-GCPtr
-CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus,
- XID gcid, ClientPtr client)
-{
- GCPtr pGC;
-
- pGC = malloc(sizeof(GC));
- if (!pGC)
- {
- *pStatus = BadAlloc;
- return (GCPtr)NULL;
- }
-
- pGC->pScreen = pDrawable->pScreen;
- pGC->depth = pDrawable->depth;
- pGC->alu = GXcopy; /* dst <- src */
- pGC->planemask = ~0;
- pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
- pGC->funcs = 0;
- pGC->devPrivates = NULL;
- pGC->fgPixel = 0;
- pGC->bgPixel = 1;
- pGC->lineWidth = 0;
- pGC->lineStyle = LineSolid;
- pGC->capStyle = CapButt;
- pGC->joinStyle = JoinMiter;
- pGC->fillStyle = FillSolid;
- pGC->fillRule = EvenOddRule;
- pGC->arcMode = ArcPieSlice;
- pGC->tile.pixel = 0;
- pGC->tile.pixmap = NullPixmap;
- if (mask & GCForeground)
- {
- /*
- * magic special case -- ChangeGC checks for this condition
- * and snags the Foreground value to create a pseudo default-tile
- */
- pGC->tileIsPixel = FALSE;
- }
- else
- {
- pGC->tileIsPixel = TRUE;
- }
-
- pGC->patOrg.x = 0;
- pGC->patOrg.y = 0;
- pGC->subWindowMode = ClipByChildren;
- pGC->graphicsExposures = TRUE;
- pGC->clipOrg.x = 0;
- pGC->clipOrg.y = 0;
- pGC->clientClipType = CT_NONE;
- pGC->clientClip = (pointer)NULL;
- pGC->numInDashList = 2;
- pGC->dash = DefaultDash;
- pGC->dashOffset = 0;
- pGC->lastWinOrg.x = 0;
- pGC->lastWinOrg.y = 0;
-
- /* use the default font and stipple */
- pGC->font = defaultFont;
- defaultFont->refcnt++;
- pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
- pGC->stipple->refcnt++;
-
- /* security creation/labeling check */
- *pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC,
- RT_NONE, NULL, DixCreateAccess|DixSetAttrAccess);
- if (*pStatus != Success)
- goto out;
-
- pGC->stateChanges = GCAllBits;
- if (!(*pGC->pScreen->CreateGC)(pGC))
- *pStatus = BadAlloc;
- else if (mask)
- *pStatus = ChangeGCXIDs(client, pGC, mask, pval);
- else
- *pStatus = Success;
-
-out:
- if (*pStatus != Success)
- {
- if (!pGC->tileIsPixel && !pGC->tile.pixmap)
- pGC->tileIsPixel = TRUE; /* undo special case */
- FreeGC(pGC, (XID)0);
- pGC = (GCPtr)NULL;
- }
-
- return (pGC);
-}
-
-static Bool
-CreateDefaultTile (GCPtr pGC)
-{
- ChangeGCVal tmpval[3];
- PixmapPtr pTile;
- GCPtr pgcScratch;
- xRectangle rect;
- CARD16 w, h;
-
- w = 1;
- h = 1;
- (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
- pTile = (PixmapPtr)
- (*pGC->pScreen->CreatePixmap)(pGC->pScreen,
- w, h, pGC->depth, 0);
- pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
- if (!pTile || !pgcScratch)
- {
- if (pTile)
- (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
- if (pgcScratch)
- FreeScratchGC(pgcScratch);
- return FALSE;
- }
- tmpval[0].val = GXcopy;
- tmpval[1].val = pGC->tile.pixel;
- tmpval[2].val = FillSolid;
- (void)ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval);
- ValidateGC((DrawablePtr)pTile, pgcScratch);
- rect.x = 0;
- rect.y = 0;
- rect.width = w;
- rect.height = h;
- (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
- /* Always remember to free the scratch graphics context after use. */
- FreeScratchGC(pgcScratch);
-
- pGC->tileIsPixel = FALSE;
- pGC->tile.pixmap = pTile;
- return TRUE;
-}
-
-int
-CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask)
-{
- BITS32 index2;
- BITS32 maskQ;
- int error = 0;
-
- if (pgcSrc == pgcDst)
- return Success;
- pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
- pgcDst->stateChanges |= mask;
- maskQ = mask;
- while (mask)
- {
- index2 = (BITS32) lowbit (mask);
- mask &= ~index2;
- switch (index2)
- {
- case GCFunction:
- pgcDst->alu = pgcSrc->alu;
- break;
- case GCPlaneMask:
- pgcDst->planemask = pgcSrc->planemask;
- break;
- case GCForeground:
- pgcDst->fgPixel = pgcSrc->fgPixel;
- break;
- case GCBackground:
- pgcDst->bgPixel = pgcSrc->bgPixel;
- break;
- case GCLineWidth:
- pgcDst->lineWidth = pgcSrc->lineWidth;
- break;
- case GCLineStyle:
- pgcDst->lineStyle = pgcSrc->lineStyle;
- break;
- case GCCapStyle:
- pgcDst->capStyle = pgcSrc->capStyle;
- break;
- case GCJoinStyle:
- pgcDst->joinStyle = pgcSrc->joinStyle;
- break;
- case GCFillStyle:
- pgcDst->fillStyle = pgcSrc->fillStyle;
- break;
- case GCFillRule:
- pgcDst->fillRule = pgcSrc->fillRule;
- break;
- case GCTile:
- {
- if (EqualPixUnion(pgcDst->tileIsPixel,
- pgcDst->tile,
- pgcSrc->tileIsPixel,
- pgcSrc->tile))
- {
- break;
- }
- if (!pgcDst->tileIsPixel)
- (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
- pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
- pgcDst->tile = pgcSrc->tile;
- if (!pgcDst->tileIsPixel)
- pgcDst->tile.pixmap->refcnt++;
- break;
- }
- case GCStipple:
- {
- if (pgcDst->stipple == pgcSrc->stipple)
- break;
- if (pgcDst->stipple)
- (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
- pgcDst->stipple = pgcSrc->stipple;
- if (pgcDst->stipple)
- pgcDst->stipple->refcnt ++;
- break;
- }
- case GCTileStipXOrigin:
- pgcDst->patOrg.x = pgcSrc->patOrg.x;
- break;
- case GCTileStipYOrigin:
- pgcDst->patOrg.y = pgcSrc->patOrg.y;
- break;
- case GCFont:
- if (pgcDst->font == pgcSrc->font)
- break;
- if (pgcDst->font)
- CloseFont(pgcDst->font, (Font)0);
- if ((pgcDst->font = pgcSrc->font) != NullFont)
- (pgcDst->font)->refcnt++;
- break;
- case GCSubwindowMode:
- pgcDst->subWindowMode = pgcSrc->subWindowMode;
- break;
- case GCGraphicsExposures:
- pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
- break;
- case GCClipXOrigin:
- pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
- break;
- case GCClipYOrigin:
- pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
- break;
- case GCClipMask:
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
- break;
- case GCDashOffset:
- pgcDst->dashOffset = pgcSrc->dashOffset;
- break;
- case GCDashList:
- if (pgcSrc->dash == DefaultDash)
- {
- if (pgcDst->dash != DefaultDash)
- {
- free(pgcDst->dash);
- pgcDst->numInDashList = pgcSrc->numInDashList;
- pgcDst->dash = pgcSrc->dash;
- }
- }
- else
- {
- unsigned char *dash;
- unsigned int i;
-
- dash = malloc(pgcSrc->numInDashList * sizeof(unsigned char));
- if (dash)
- {
- if (pgcDst->dash != DefaultDash)
- free(pgcDst->dash);
- pgcDst->numInDashList = pgcSrc->numInDashList;
- pgcDst->dash = dash;
- for (i=0; i<pgcSrc->numInDashList; i++)
- dash[i] = pgcSrc->dash[i];
- }
- else
- error = BadAlloc;
- }
- break;
- case GCArcMode:
- pgcDst->arcMode = pgcSrc->arcMode;
- break;
- default:
- FatalError ("CopyGC: Unhandled mask!\n");
- }
- }
- if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
- {
- if (!CreateDefaultTile (pgcDst))
- {
- pgcDst->fillStyle = FillSolid;
- error = BadAlloc;
- }
- }
- (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
- return error;
-}
-
-/**
- * does the diX part of freeing the characteristics in the GC.
- *
- * \param value must conform to DeleteType
- */
-int
-FreeGC(pointer value, XID gid)
-{
- GCPtr pGC = (GCPtr)value;
-
- CloseFont(pGC->font, (Font)0);
- (* pGC->funcs->DestroyClip)(pGC);
-
- if (!pGC->tileIsPixel)
- (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
- if (pGC->stipple)
- (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
-
- (*pGC->funcs->DestroyGC) (pGC);
- if (pGC->dash != DefaultDash)
- free(pGC->dash);
- dixFreePrivates(pGC->devPrivates);
- free(pGC);
- return(Success);
-}
-
-/* CreateScratchGC(pScreen, depth)
- like CreateGC, but doesn't do the default tile or stipple,
-since we can't create them without already having a GC. any code
-using the tile or stipple has to set them explicitly anyway,
-since the state of the scratch gc is unknown. This is OK
-because ChangeGC() has to be able to deal with NULL tiles and
-stipples anyway (in case the CreateGC() call has provided a
-value for them -- we can't set the default tile until the
-client-supplied attributes are installed, since the fgPixel
-is what fills the default tile. (maybe this comment should
-go with CreateGC() or ChangeGC().)
-*/
-
-GCPtr
-CreateScratchGC(ScreenPtr pScreen, unsigned depth)
-{
- GCPtr pGC;
-
- pGC = malloc(sizeof(GC));
- if (!pGC)
- return (GCPtr)NULL;
-
- pGC->pScreen = pScreen;
- pGC->depth = depth;
- pGC->alu = GXcopy; /* dst <- src */
- pGC->planemask = ~0;
- pGC->serialNumber = 0;
- pGC->devPrivates = NULL;
- pGC->fgPixel = 0;
- pGC->bgPixel = 1;
- pGC->lineWidth = 0;
- pGC->lineStyle = LineSolid;
- pGC->capStyle = CapButt;
- pGC->joinStyle = JoinMiter;
- pGC->fillStyle = FillSolid;
- pGC->fillRule = EvenOddRule;
- pGC->arcMode = ArcPieSlice;
- pGC->font = defaultFont;
- if ( pGC->font) /* necessary, because open of default font could fail */
- pGC->font->refcnt++;
- pGC->tileIsPixel = TRUE;
- pGC->tile.pixel = 0;
- pGC->tile.pixmap = NullPixmap;
- pGC->stipple = NullPixmap;
- pGC->patOrg.x = 0;
- pGC->patOrg.y = 0;
- pGC->subWindowMode = ClipByChildren;
- pGC->graphicsExposures = TRUE;
- pGC->clipOrg.x = 0;
- pGC->clipOrg.y = 0;
- pGC->clientClipType = CT_NONE;
- pGC->dashOffset = 0;
- pGC->numInDashList = 2;
- pGC->dash = DefaultDash;
- pGC->lastWinOrg.x = 0;
- pGC->lastWinOrg.y = 0;
-
- pGC->stateChanges = GCAllBits;
- if (!(*pScreen->CreateGC)(pGC))
- {
- FreeGC(pGC, (XID)0);
- pGC = (GCPtr)NULL;
- }
- return pGC;
-}
-
-void
-FreeGCperDepth(int screenNum)
-{
- int i;
- ScreenPtr pScreen;
- GCPtr *ppGC;
-
- pScreen = screenInfo.screens[screenNum];
- ppGC = pScreen->GCperDepth;
-
- for (i = 0; i <= pScreen->numDepths; i++)
- (void)FreeGC(ppGC[i], (XID)0);
- pScreen->rgf = ~0L;
-}
-
-
-Bool
-CreateGCperDepth(int screenNum)
-{
- int i;
- ScreenPtr pScreen;
- DepthPtr pDepth;
- 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)))
- return FALSE;
- ppGC[0]->graphicsExposures = FALSE;
- /* Make sure we don't overflow GCperDepth[] */
- if( pScreen->numDepths > MAXFORMATS )
- return FALSE;
-
- pDepth = pScreen->allowedDepths;
- for (i=0; i<pScreen->numDepths; i++, pDepth++)
- {
- if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
- {
- for (; i >= 0; i--)
- (void)FreeGC(ppGC[i], (XID)0);
- return FALSE;
- }
- ppGC[i+1]->graphicsExposures = FALSE;
- }
- return TRUE;
-}
-
-Bool
-CreateDefaultStipple(int screenNum)
-{
- ScreenPtr pScreen;
- ChangeGCVal tmpval[3];
- xRectangle rect;
- CARD16 w, h;
- GCPtr pgcScratch;
-
- pScreen = screenInfo.screens[screenNum];
-
- w = 16;
- h = 16;
- (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
- if (!(pScreen->PixmapPerDepth[0] =
- (*pScreen->CreatePixmap)(pScreen, w, h, 1, 0)))
- return FALSE;
- /* fill stipple with 1 */
- tmpval[0].val = GXcopy;
- tmpval[1].val = 1;
- tmpval[2].val = FillSolid;
- pgcScratch = GetScratchGC(1, pScreen);
- if (!pgcScratch)
- {
- (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
- return FALSE;
- }
- (void)ChangeGC(NullClient, pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
- ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
- rect.x = 0;
- rect.y = 0;
- rect.width = w;
- rect.height = h;
- (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
- pgcScratch, 1, &rect);
- FreeScratchGC(pgcScratch);
- return TRUE;
-}
-
-void
-FreeDefaultStipple(int screenNum)
-{
- ScreenPtr pScreen = screenInfo.screens[screenNum];
- (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
-}
-
-int
-SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
-{
- long i;
- unsigned char *p, *indash;
- BITS32 maskQ = 0;
-
- i = ndash;
- p = pdash;
- while (i--)
- {
- if (!*p++)
- {
- /* dash segment must be > 0 */
- return BadValue;
- }
- }
-
- if (ndash & 1)
- p = malloc(2 * ndash * sizeof(unsigned char));
- else
- p = malloc(ndash * sizeof(unsigned char));
- if (!p)
- return BadAlloc;
-
- pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
- if (offset != pGC->dashOffset)
- {
- pGC->dashOffset = offset;
- pGC->stateChanges |= GCDashOffset;
- maskQ |= GCDashOffset;
- }
-
- if (pGC->dash != DefaultDash)
- free(pGC->dash);
- pGC->numInDashList = ndash;
- pGC->dash = p;
- if (ndash & 1)
- {
- pGC->numInDashList += ndash;
- indash = pdash;
- i = ndash;
- while (i--)
- *p++ = *indash++;
- }
- while(ndash--)
- *p++ = *pdash++;
- pGC->stateChanges |= GCDashList;
- maskQ |= GCDashList;
-
- if (pGC->funcs->ChangeGC)
- (*pGC->funcs->ChangeGC) (pGC, maskQ);
- return Success;
-}
-
-int
-VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
-{
- xRectangle *prectP, *prectN;
- int i;
-
- switch(ordering)
- {
- case Unsorted:
- return CT_UNSORTED;
- case YSorted:
- if(nrects > 1)
- {
- for(i = 1, prectP = prects, prectN = prects + 1;
- i < nrects;
- i++, prectP++, prectN++)
- if(prectN->y < prectP->y)
- return -1;
- }
- return CT_YSORTED;
- case YXSorted:
- if(nrects > 1)
- {
- for(i = 1, prectP = prects, prectN = prects + 1;
- i < nrects;
- i++, prectP++, prectN++)
- if((prectN->y < prectP->y) ||
- ( (prectN->y == prectP->y) &&
- (prectN->x < prectP->x) ) )
- return -1;
- }
- return CT_YXSORTED;
- case YXBanded:
- if(nrects > 1)
- {
- for(i = 1, prectP = prects, prectN = prects + 1;
- i < nrects;
- i++, prectP++, prectN++)
- if((prectN->y != prectP->y &&
- prectN->y < prectP->y + (int) prectP->height) ||
- ((prectN->y == prectP->y) &&
- (prectN->height != prectP->height ||
- prectN->x < prectP->x + (int) prectP->width)))
- return -1;
- }
- return CT_YXBANDED;
- }
- return -1;
-}
-
-int
-SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
- xRectangle *prects, int ordering)
-{
- int newct, size;
- xRectangle *prectsNew;
-
- newct = VerifyRectOrder(nrects, prects, ordering);
- if (newct < 0)
- return(BadMatch);
- size = nrects * sizeof(xRectangle);
- prectsNew = malloc(size);
- if (!prectsNew && size)
- return BadAlloc;
-
- pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
- pGC->clipOrg.x = xOrigin;
- pGC->stateChanges |= GCClipXOrigin;
-
- pGC->clipOrg.y = yOrigin;
- pGC->stateChanges |= GCClipYOrigin;
-
- if (size)
- memmove((char *)prectsNew, (char *)prects, size);
- (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects);
- if (pGC->funcs->ChangeGC)
- (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
- return Success;
-}
-
-
-/*
- sets reasonable defaults
- if we can get a pre-allocated one, use it and mark it as used.
- if we can't, create one out of whole cloth (The Velveteen GC -- if
- you use it often enough it will become real.)
-*/
-GCPtr
-GetScratchGC(unsigned depth, ScreenPtr pScreen)
-{
- int i;
- GCPtr pGC;
-
- for (i=0; i<=pScreen->numDepths; i++)
- if ( pScreen->GCperDepth[i]->depth == depth &&
- !(pScreen->rgf & (1L << (i+1)))
- )
- {
- pScreen->rgf |= (1L << (i+1));
- pGC = (pScreen->GCperDepth[i]);
-
- pGC->alu = GXcopy;
- pGC->planemask = ~0;
- pGC->serialNumber = 0;
- pGC->fgPixel = 0;
- pGC->bgPixel = 1;
- pGC->lineWidth = 0;
- pGC->lineStyle = LineSolid;
- pGC->capStyle = CapButt;
- pGC->joinStyle = JoinMiter;
- pGC->fillStyle = FillSolid;
- pGC->fillRule = EvenOddRule;
- pGC->arcMode = ArcChord;
- pGC->patOrg.x = 0;
- pGC->patOrg.y = 0;
- pGC->subWindowMode = ClipByChildren;
- pGC->graphicsExposures = FALSE;
- pGC->clipOrg.x = 0;
- pGC->clipOrg.y = 0;
- if (pGC->clientClipType != CT_NONE)
- (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
- pGC->stateChanges = GCAllBits;
- return pGC;
- }
- /* if we make it this far, need to roll our own */
- pGC = CreateScratchGC(pScreen, depth);
- if (pGC)
- pGC->graphicsExposures = FALSE;
- return pGC;
-}
-
-/*
- if the gc to free is in the table of pre-existing ones,
-mark it as available.
- if not, free it for real
-*/
-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);
-}
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+#include "dixstruct.h"
+
+#include "privates.h"
+#include "dix.h"
+#include "xace.h"
+#include <assert.h>
+
+extern FontPtr defaultFont;
+
+static Bool CreateDefaultTile(GCPtr pGC);
+
+static unsigned char DefaultDash[2] = {4, 4};
+
+void
+ValidateGC(DrawablePtr pDraw, GC *pGC)
+{
+ (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
+ pGC->stateChanges = 0;
+ pGC->serialNumber = pDraw->serialNumber;
+}
+
+
+/*
+ * ChangeGC/ChangeGCXIDs:
+ *
+ * The client performing the gc change must be passed so that access
+ * checks can be performed on any tiles, stipples, or fonts that are
+ * specified. ddxen can call this too; they should normally pass
+ * NullClient for the client since any access checking should have
+ * already been done at a higher level.
+ *
+ * If you have any XIDs, you must use ChangeGCXIDs:
+ *
+ * CARD32 v[2];
+ * v[0] = FillTiled;
+ * v[1] = pid;
+ * ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v);
+ *
+ * However, if you need to pass a pointer to a pixmap or font, you must
+ * use ChangeGC:
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = FillTiled;
+ * v[1].ptr = pPixmap;
+ * ChangeGC(client, pGC, GCFillStyle|GCTile, v);
+ *
+ * If you have neither XIDs nor pointers, you can use either function,
+ * but ChangeGC will do less work.
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = foreground;
+ * v[1].val = background;
+ * ChangeGC(client, pGC, GCForeground|GCBackground, v);
+ */
+
+#define NEXTVAL(_type, _var) { \
+ _var = (_type)(pUnion->val); pUnion++; \
+ }
+
+#define NEXT_PTR(_type, _var) { \
+ _var = (_type)pUnion->ptr; pUnion++; }
+
+int
+ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
+{
+ BITS32 index2;
+ int error = 0;
+ PixmapPtr pPixmap;
+ BITS32 maskQ;
+
+ assert(pUnion);
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ maskQ = mask; /* save these for when we walk the GCque */
+ while (mask && !error)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ pGC->stateChanges |= index2;
+ switch (index2)
+ {
+ case GCFunction:
+ {
+ CARD8 newalu;
+ NEXTVAL(CARD8, newalu);
+ if (newalu <= GXset)
+ pGC->alu = newalu;
+ else
+ {
+ if (client)
+ client->errorValue = newalu;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCPlaneMask:
+ NEXTVAL(unsigned long, pGC->planemask);
+ break;
+ case GCForeground:
+ NEXTVAL(unsigned long, pGC->fgPixel);
+ /*
+ * this is for CreateGC
+ */
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ {
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = pGC->fgPixel;
+ }
+ break;
+ case GCBackground:
+ NEXTVAL(unsigned long, pGC->bgPixel);
+ break;
+ case GCLineWidth: /* ??? line width is a CARD16 */
+ NEXTVAL(CARD16, pGC->lineWidth);
+ break;
+ case GCLineStyle:
+ {
+ unsigned int newlinestyle;
+ NEXTVAL(unsigned int, newlinestyle);
+ if (newlinestyle <= LineDoubleDash)
+ pGC->lineStyle = newlinestyle;
+ else
+ {
+ if (client)
+ client->errorValue = newlinestyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCCapStyle:
+ {
+ unsigned int newcapstyle;
+ NEXTVAL(unsigned int, newcapstyle);
+ if (newcapstyle <= CapProjecting)
+ pGC->capStyle = newcapstyle;
+ else
+ {
+ if (client)
+ client->errorValue = newcapstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCJoinStyle:
+ {
+ unsigned int newjoinstyle;
+ NEXTVAL(unsigned int, newjoinstyle);
+ if (newjoinstyle <= JoinBevel)
+ pGC->joinStyle = newjoinstyle;
+ else
+ {
+ if (client)
+ client->errorValue = newjoinstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillStyle:
+ {
+ unsigned int newfillstyle;
+ NEXTVAL(unsigned int, newfillstyle);
+ if (newfillstyle <= FillOpaqueStippled)
+ pGC->fillStyle = newfillstyle;
+ else
+ {
+ if (client)
+ client->errorValue = newfillstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillRule:
+ {
+ unsigned int newfillrule;
+ NEXTVAL(unsigned int, newfillrule);
+ if (newfillrule <= WindingRule)
+ pGC->fillRule = newfillrule;
+ else
+ {
+ if (client)
+ client->errorValue = newfillrule;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCTile:
+ NEXT_PTR(PixmapPtr, pPixmap);
+ if ((pPixmap->drawable.depth != pGC->depth) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pPixmap;
+ }
+ break;
+ case GCStipple:
+ NEXT_PTR(PixmapPtr, pPixmap);
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+ pGC->stipple = pPixmap;
+ }
+ break;
+ case GCTileStipXOrigin:
+ NEXTVAL(INT16, pGC->patOrg.x);
+ break;
+ case GCTileStipYOrigin:
+ NEXTVAL(INT16, pGC->patOrg.y);
+ break;
+ case GCFont:
+ {
+ FontPtr pFont;
+ NEXT_PTR(FontPtr, pFont);
+ pFont->refcnt++;
+ if (pGC->font)
+ CloseFont(pGC->font, (Font)0);
+ pGC->font = pFont;
+ break;
+ }
+ case GCSubwindowMode:
+ {
+ unsigned int newclipmode;
+ NEXTVAL(unsigned int, newclipmode);
+ if (newclipmode <= IncludeInferiors)
+ pGC->subWindowMode = newclipmode;
+ else
+ {
+ if (client)
+ client->errorValue = newclipmode;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCGraphicsExposures:
+ {
+ unsigned int newge;
+ NEXTVAL(unsigned int, newge);
+ if (newge <= xTrue)
+ pGC->graphicsExposures = newge;
+ else
+ {
+ if (client)
+ client->errorValue = newge;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCClipXOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.x);
+ break;
+ case GCClipYOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.y);
+ break;
+ case GCClipMask:
+ NEXT_PTR(PixmapPtr, pPixmap);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ break;
+ }
+ pPixmap->refcnt++;
+ }
+ (*pGC->funcs->ChangeClip)(pGC, pPixmap ? CT_PIXMAP : CT_NONE,
+ (pointer)pPixmap, 0);
+ break;
+ case GCDashOffset:
+ NEXTVAL(INT16, pGC->dashOffset);
+ break;
+ case GCDashList:
+ {
+ CARD8 newdash;
+ NEXTVAL(CARD8, newdash);
+ if (newdash == 4)
+ {
+ if (pGC->dash != DefaultDash)
+ {
+ free(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ }
+ }
+ else if (newdash != 0)
+ {
+ unsigned char *dash;
+
+ dash = malloc(2 * sizeof(unsigned char));
+ if (dash)
+ {
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = dash;
+ dash[0] = newdash;
+ dash[1] = newdash;
+ }
+ else
+ error = BadAlloc;
+ }
+ else
+ {
+ if (client)
+ client->errorValue = newdash;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCArcMode:
+ {
+ unsigned int newarcmode;
+ NEXTVAL(unsigned int, newarcmode);
+ if (newarcmode <= ArcPieSlice)
+ pGC->arcMode = newarcmode;
+ else
+ {
+ if (client)
+ client->errorValue = newarcmode;
+ error = BadValue;
+ }
+ break;
+ }
+ default:
+ if (client)
+ client->errorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ } /* end while mask && !error */
+
+ if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pGC))
+ {
+ pGC->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pGC->funcs->ChangeGC)(pGC, maskQ);
+ return error;
+}
+
+#undef NEXTVAL
+#undef NEXT_PTR
+
+static const struct {
+ BITS32 mask;
+ RESTYPE type;
+ Mask access_mode;
+} xidfields[] = {
+ { GCTile, RT_PIXMAP, DixReadAccess },
+ { GCStipple, RT_PIXMAP, DixReadAccess },
+ { GCFont, RT_FONT, DixUseAccess },
+ { GCClipMask, RT_PIXMAP, DixReadAccess },
+};
+
+int
+ChangeGCXIDs(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32)
+{
+ ChangeGCVal vals[GCLastBit + 1];
+ int i;
+ if (mask & ~GCAllBits)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ for (i = Ones(mask); i--; )
+ vals[i].val = pC32[i];
+ for (i = 0; i < sizeof(xidfields) / sizeof(*xidfields); ++i)
+ {
+ int offset, rc;
+ if (!(mask & xidfields[i].mask))
+ continue;
+ offset = Ones(mask & (xidfields[i].mask - 1));
+ if (xidfields[i].mask == GCClipMask && vals[offset].val == None)
+ {
+ vals[offset].ptr = NullPixmap;
+ continue;
+ }
+ rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val,
+ xidfields[i].type, client, xidfields[i].access_mode);
+ if (rc != Success)
+ {
+ client->errorValue = vals[offset].val;
+ if (rc == BadValue)
+ rc = (xidfields[i].type == RT_PIXMAP) ? BadPixmap : BadFont;
+ return rc;
+ }
+ }
+ return ChangeGC(client, pGC, mask, vals);
+}
+
+/* CreateGC(pDrawable, mask, pval, pStatus)
+ creates a default GC for the given drawable, using mask to fill
+ in any non-default values.
+ Returns a pointer to the new GC on success, NULL otherwise.
+ returns status of non-default fields in pStatus
+BUG:
+ should check for failure to create default tile
+
+*/
+GCPtr
+CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus,
+ XID gcid, ClientPtr client)
+{
+ GCPtr pGC;
+
+ pGC = malloc(sizeof(GC));
+ if (!pGC)
+ {
+ *pStatus = BadAlloc;
+ return (GCPtr)NULL;
+ }
+
+ pGC->pScreen = pDrawable->pScreen;
+ pGC->depth = pDrawable->depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pGC->funcs = 0;
+ pGC->devPrivates = NULL;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ pGC->tile.pixel = 0;
+ pGC->tile.pixmap = NullPixmap;
+ if (mask & GCForeground)
+ {
+ /*
+ * magic special case -- ChangeGC checks for this condition
+ * and snags the Foreground value to create a pseudo default-tile
+ */
+ pGC->tileIsPixel = FALSE;
+ }
+ else
+ {
+ pGC->tileIsPixel = TRUE;
+ }
+
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = (pointer)NULL;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->dashOffset = 0;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ /* use the default font and stipple */
+ pGC->font = defaultFont;
+ defaultFont->refcnt++;
+ pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
+ pGC->stipple->refcnt++;
+
+ /* security creation/labeling check */
+ *pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC,
+ RT_NONE, NULL, DixCreateAccess|DixSetAttrAccess);
+ if (*pStatus != Success)
+ goto out;
+
+ pGC->stateChanges = GCAllBits;
+ if (!(*pGC->pScreen->CreateGC)(pGC))
+ *pStatus = BadAlloc;
+ else if (mask)
+ *pStatus = ChangeGCXIDs(client, pGC, mask, pval);
+ else
+ *pStatus = Success;
+
+out:
+ if (*pStatus != Success)
+ {
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ pGC->tileIsPixel = TRUE; /* undo special case */
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+
+ return (pGC);
+}
+
+static Bool
+CreateDefaultTile (GCPtr pGC)
+{
+ ChangeGCVal tmpval[3];
+ PixmapPtr pTile;
+ GCPtr pgcScratch;
+ xRectangle rect;
+ CARD16 w, h;
+
+ w = 1;
+ h = 1;
+ (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
+ pTile = (PixmapPtr)
+ (*pGC->pScreen->CreatePixmap)(pGC->pScreen,
+ w, h, pGC->depth, 0);
+ pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
+ if (!pTile || !pgcScratch)
+ {
+ if (pTile)
+ (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
+ if (pgcScratch)
+ FreeScratchGC(pgcScratch);
+ return FALSE;
+ }
+ tmpval[0].val = GXcopy;
+ tmpval[1].val = pGC->tile.pixel;
+ tmpval[2].val = FillSolid;
+ (void)ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval);
+ ValidateGC((DrawablePtr)pTile, pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
+ /* Always remember to free the scratch graphics context after use. */
+ FreeScratchGC(pgcScratch);
+
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pTile;
+ return TRUE;
+}
+
+int
+CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask)
+{
+ BITS32 index2;
+ BITS32 maskQ;
+ int error = 0;
+
+ if (pgcSrc == pgcDst)
+ return Success;
+ pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgcDst->stateChanges |= mask;
+ maskQ = mask;
+ while (mask)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ switch (index2)
+ {
+ case GCFunction:
+ pgcDst->alu = pgcSrc->alu;
+ break;
+ case GCPlaneMask:
+ pgcDst->planemask = pgcSrc->planemask;
+ break;
+ case GCForeground:
+ pgcDst->fgPixel = pgcSrc->fgPixel;
+ break;
+ case GCBackground:
+ pgcDst->bgPixel = pgcSrc->bgPixel;
+ break;
+ case GCLineWidth:
+ pgcDst->lineWidth = pgcSrc->lineWidth;
+ break;
+ case GCLineStyle:
+ pgcDst->lineStyle = pgcSrc->lineStyle;
+ break;
+ case GCCapStyle:
+ pgcDst->capStyle = pgcSrc->capStyle;
+ break;
+ case GCJoinStyle:
+ pgcDst->joinStyle = pgcSrc->joinStyle;
+ break;
+ case GCFillStyle:
+ pgcDst->fillStyle = pgcSrc->fillStyle;
+ break;
+ case GCFillRule:
+ pgcDst->fillRule = pgcSrc->fillRule;
+ break;
+ case GCTile:
+ {
+ if (EqualPixUnion(pgcDst->tileIsPixel,
+ pgcDst->tile,
+ pgcSrc->tileIsPixel,
+ pgcSrc->tile))
+ {
+ break;
+ }
+ if (!pgcDst->tileIsPixel)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
+ pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
+ pgcDst->tile = pgcSrc->tile;
+ if (!pgcDst->tileIsPixel)
+ pgcDst->tile.pixmap->refcnt++;
+ break;
+ }
+ case GCStipple:
+ {
+ if (pgcDst->stipple == pgcSrc->stipple)
+ break;
+ if (pgcDst->stipple)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
+ pgcDst->stipple = pgcSrc->stipple;
+ if (pgcDst->stipple)
+ pgcDst->stipple->refcnt ++;
+ break;
+ }
+ case GCTileStipXOrigin:
+ pgcDst->patOrg.x = pgcSrc->patOrg.x;
+ break;
+ case GCTileStipYOrigin:
+ pgcDst->patOrg.y = pgcSrc->patOrg.y;
+ break;
+ case GCFont:
+ if (pgcDst->font == pgcSrc->font)
+ break;
+ if (pgcDst->font)
+ CloseFont(pgcDst->font, (Font)0);
+ if ((pgcDst->font = pgcSrc->font) != NullFont)
+ (pgcDst->font)->refcnt++;
+ break;
+ case GCSubwindowMode:
+ pgcDst->subWindowMode = pgcSrc->subWindowMode;
+ break;
+ case GCGraphicsExposures:
+ pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
+ break;
+ case GCClipXOrigin:
+ pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
+ break;
+ case GCClipYOrigin:
+ pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
+ break;
+ case GCClipMask:
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ break;
+ case GCDashOffset:
+ pgcDst->dashOffset = pgcSrc->dashOffset;
+ break;
+ case GCDashList:
+ if (pgcSrc->dash == DefaultDash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ {
+ free(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = pgcSrc->dash;
+ }
+ }
+ else
+ {
+ unsigned char *dash;
+ unsigned int i;
+
+ dash = malloc(pgcSrc->numInDashList * sizeof(unsigned char));
+ if (dash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ free(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = dash;
+ for (i=0; i<pgcSrc->numInDashList; i++)
+ dash[i] = pgcSrc->dash[i];
+ }
+ else
+ error = BadAlloc;
+ }
+ break;
+ case GCArcMode:
+ pgcDst->arcMode = pgcSrc->arcMode;
+ break;
+ default:
+ FatalError ("CopyGC: Unhandled mask!\n");
+ }
+ }
+ if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pgcDst))
+ {
+ pgcDst->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
+ return error;
+}
+
+/**
+ * does the diX part of freeing the characteristics in the GC.
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeGC(pointer value, XID gid)
+{
+ GCPtr pGC = (GCPtr)value;
+
+ CloseFont(pGC->font, (Font)0);
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ dixFreePrivates(pGC->devPrivates);
+ free(pGC);
+ return(Success);
+}
+
+/* CreateScratchGC(pScreen, depth)
+ like CreateGC, but doesn't do the default tile or stipple,
+since we can't create them without already having a GC. any code
+using the tile or stipple has to set them explicitly anyway,
+since the state of the scratch gc is unknown. This is OK
+because ChangeGC() has to be able to deal with NULL tiles and
+stipples anyway (in case the CreateGC() call has provided a
+value for them -- we can't set the default tile until the
+client-supplied attributes are installed, since the fgPixel
+is what fills the default tile. (maybe this comment should
+go with CreateGC() or ChangeGC().)
+*/
+
+GCPtr
+CreateScratchGC(ScreenPtr pScreen, unsigned depth)
+{
+ GCPtr pGC;
+
+ pGC = malloc(sizeof(GC));
+ if (!pGC)
+ return (GCPtr)NULL;
+
+ pGC->pScreen = pScreen;
+ pGC->depth = depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+ pGC->devPrivates = NULL;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ pGC->font = defaultFont;
+ if ( pGC->font) /* necessary, because open of default font could fail */
+ pGC->font->refcnt++;
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->tile.pixmap = NullPixmap;
+ pGC->stipple = NullPixmap;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->dashOffset = 0;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ pGC->stateChanges = GCAllBits;
+ if (!(*pScreen->CreateGC)(pGC))
+ {
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+ return pGC;
+}
+
+void
+FreeGCperDepth(int screenNum)
+{
+ int i;
+ ScreenPtr pScreen;
+ GCPtr *ppGC;
+
+ pScreen = screenInfo.screens[screenNum];
+ ppGC = pScreen->GCperDepth;
+
+ for (i = 0; i <= pScreen->numDepths; i++)
+ (void)FreeGC(ppGC[i], (XID)0);
+ pScreen->rgf = ~0L;
+}
+
+
+Bool
+CreateGCperDepth(int screenNum)
+{
+ int i;
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ 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)))
+ return FALSE;
+ ppGC[0]->graphicsExposures = FALSE;
+ /* Make sure we don't overflow GCperDepth[] */
+ if( pScreen->numDepths > MAXFORMATS )
+ return FALSE;
+
+ pDepth = pScreen->allowedDepths;
+ for (i=0; i<pScreen->numDepths; i++, pDepth++)
+ {
+ if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
+ {
+ for (; i >= 0; i--)
+ (void)FreeGC(ppGC[i], (XID)0);
+ return FALSE;
+ }
+ ppGC[i+1]->graphicsExposures = FALSE;
+ }
+ return TRUE;
+}
+
+Bool
+CreateDefaultStipple(int screenNum)
+{
+ ScreenPtr pScreen;
+ ChangeGCVal tmpval[3];
+ xRectangle rect;
+ CARD16 w, h;
+ GCPtr pgcScratch;
+
+ pScreen = screenInfo.screens[screenNum];
+
+ w = 16;
+ h = 16;
+ (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
+ if (!(pScreen->PixmapPerDepth[0] =
+ (*pScreen->CreatePixmap)(pScreen, w, h, 1, 0)))
+ return FALSE;
+ /* fill stipple with 1 */
+ tmpval[0].val = GXcopy;
+ tmpval[1].val = 1;
+ tmpval[2].val = FillSolid;
+ pgcScratch = GetScratchGC(1, pScreen);
+ if (!pgcScratch)
+ {
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+ return FALSE;
+ }
+ (void)ChangeGC(NullClient, pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
+ ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
+ pgcScratch, 1, &rect);
+ FreeScratchGC(pgcScratch);
+ return TRUE;
+}
+
+void
+FreeDefaultStipple(int screenNum)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+}
+
+int
+SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
+{
+ long i;
+ unsigned char *p, *indash;
+ BITS32 maskQ = 0;
+
+ i = ndash;
+ p = pdash;
+ while (i--)
+ {
+ if (!*p++)
+ {
+ /* dash segment must be > 0 */
+ return BadValue;
+ }
+ }
+
+ if (ndash & 1)
+ p = malloc(2 * ndash * sizeof(unsigned char));
+ else
+ p = malloc(ndash * sizeof(unsigned char));
+ if (!p)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ if (offset != pGC->dashOffset)
+ {
+ pGC->dashOffset = offset;
+ pGC->stateChanges |= GCDashOffset;
+ maskQ |= GCDashOffset;
+ }
+
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ pGC->numInDashList = ndash;
+ pGC->dash = p;
+ if (ndash & 1)
+ {
+ pGC->numInDashList += ndash;
+ indash = pdash;
+ i = ndash;
+ while (i--)
+ *p++ = *indash++;
+ }
+ while(ndash--)
+ *p++ = *pdash++;
+ pGC->stateChanges |= GCDashList;
+ maskQ |= GCDashList;
+
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, maskQ);
+ return Success;
+}
+
+int
+VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
+{
+ xRectangle *prectP, *prectN;
+ int i;
+
+ switch(ordering)
+ {
+ case Unsorted:
+ return CT_UNSORTED;
+ case YSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if(prectN->y < prectP->y)
+ return -1;
+ }
+ return CT_YSORTED;
+ case YXSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y < prectP->y) ||
+ ( (prectN->y == prectP->y) &&
+ (prectN->x < prectP->x) ) )
+ return -1;
+ }
+ return CT_YXSORTED;
+ case YXBanded:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y != prectP->y &&
+ prectN->y < prectP->y + (int) prectP->height) ||
+ ((prectN->y == prectP->y) &&
+ (prectN->height != prectP->height ||
+ prectN->x < prectP->x + (int) prectP->width)))
+ return -1;
+ }
+ return CT_YXBANDED;
+ }
+ return -1;
+}
+
+int
+SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
+ xRectangle *prects, int ordering)
+{
+ int newct, size;
+ xRectangle *prectsNew;
+
+ newct = VerifyRectOrder(nrects, prects, ordering);
+ if (newct < 0)
+ return(BadMatch);
+ size = nrects * sizeof(xRectangle);
+ prectsNew = malloc(size);
+ if (!prectsNew && size)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->clipOrg.x = xOrigin;
+ pGC->stateChanges |= GCClipXOrigin;
+
+ pGC->clipOrg.y = yOrigin;
+ pGC->stateChanges |= GCClipYOrigin;
+
+ if (size)
+ memmove((char *)prectsNew, (char *)prects, size);
+ (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects);
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
+ return Success;
+}
+
+
+/*
+ sets reasonable defaults
+ if we can get a pre-allocated one, use it and mark it as used.
+ if we can't, create one out of whole cloth (The Velveteen GC -- if
+ you use it often enough it will become real.)
+*/
+GCPtr
+GetScratchGC(unsigned depth, ScreenPtr pScreen)
+{
+ int i;
+ GCPtr pGC;
+
+ for (i=0; i<=pScreen->numDepths; i++)
+ if ( pScreen->GCperDepth[i]->depth == depth &&
+ !(pScreen->rgf & (1L << (i+1)))
+ )
+ {
+ pScreen->rgf |= (1L << (i+1));
+ pGC = (pScreen->GCperDepth[i]);
+
+ pGC->alu = GXcopy;
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcChord;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = FALSE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ if (pGC->clientClipType != CT_NONE)
+ (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
+ pGC->stateChanges = GCAllBits;
+ return pGC;
+ }
+ /* if we make it this far, need to roll our own */
+ pGC = CreateScratchGC(pScreen, depth);
+ if (pGC)
+ pGC->graphicsExposures = FALSE;
+ return pGC;
+}
+
+/*
+ if the gc to free is in the table of pre-existing ones,
+mark it as available.
+ if not, free it for real
+*/
+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);
+}
diff --git a/xorg-server/hw/xfree86/common/Makefile.am b/xorg-server/hw/xfree86/common/Makefile.am
index ad27210cd..821a2b500 100644
--- a/xorg-server/hw/xfree86/common/Makefile.am
+++ b/xorg-server/hw/xfree86/common/Makefile.am
@@ -41,6 +41,7 @@ libcommon_la_SOURCES = xf86Configure.c xf86ShowOpts.c xf86Bus.c xf86Config.c \
xf86Mode.c xorgHelper.c \
$(XVSOURCES) $(BUSSOURCES) $(RANDRSOURCES)
nodist_libcommon_la_SOURCES = xf86DefModeSet.c xf86Build.h
+libcommon_la_LIBADD = $(top_builddir)/config/libconfig.la
INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \
-I$(srcdir)/../loader -I$(srcdir)/../parser \
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index 64be079ca..29c917f21 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -1,1138 +1,1140 @@
-/*
- * Copyright © 2007, 2008 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Soft-
- * ware"), to deal in the Software without restriction, including without
- * limitation the rights to use, copy, modify, merge, publish, distribute,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, provided that the above copyright
- * notice(s) and this permission notice appear in all copies of the Soft-
- * ware and that both the above copyright notice(s) and this permission
- * notice appear in supporting documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
- * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
- * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
- * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
- * QUENTIAL 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 PERFOR-
- * MANCE OF THIS SOFTWARE.
- *
- * Except as contained in this notice, the name of a copyright holder shall
- * not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization of
- * the copyright holder.
- *
- * Authors:
- * Kristian Høgsberg (krh@redhat.com)
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <errno.h>
-#include <xf86drm.h>
-#include "xf86Module.h"
-#include "list.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "dixstruct.h"
-#include "dri2.h"
-#include "xf86VGAarbiter.h"
-
-#include "xf86.h"
-
-CARD8 dri2_major; /* version of DRI2 supported by DDX */
-CARD8 dri2_minor;
-
-static int dri2ScreenPrivateKeyIndex;
-static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
-static int dri2WindowPrivateKeyIndex;
-static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
-static int dri2PixmapPrivateKeyIndex;
-static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
-static RESTYPE dri2DrawableRes;
-
-typedef struct _DRI2Screen *DRI2ScreenPtr;
-
-typedef struct _DRI2Drawable {
- DRI2ScreenPtr dri2_screen;
- DrawablePtr drawable;
- struct list reference_list;
- int width;
- int height;
- DRI2BufferPtr *buffers;
- int bufferCount;
- unsigned int swapsPending;
- ClientPtr blockedClient;
- Bool blockedOnMsc;
- int swap_interval;
- CARD64 swap_count;
- int64_t target_sbc; /* -1 means no SBC wait outstanding */
- CARD64 last_swap_target; /* most recently queued swap target */
- CARD64 last_swap_msc; /* msc at completion of most recent swap */
- CARD64 last_swap_ust; /* ust at completion of most recent swap */
- int swap_limit; /* for N-buffering */
-} DRI2DrawableRec, *DRI2DrawablePtr;
-
-typedef struct _DRI2Screen {
- ScreenPtr screen;
- int refcnt;
- unsigned int numDrivers;
- const char **driverNames;
- const char *deviceName;
- int fd;
- unsigned int lastSequence;
-
- DRI2CreateBufferProcPtr CreateBuffer;
- DRI2DestroyBufferProcPtr DestroyBuffer;
- DRI2CopyRegionProcPtr CopyRegion;
- DRI2ScheduleSwapProcPtr ScheduleSwap;
- DRI2GetMSCProcPtr GetMSC;
- DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
-
- HandleExposuresProcPtr HandleExposures;
-
- ConfigNotifyProcPtr ConfigNotify;
-} DRI2ScreenRec;
-
-static DRI2ScreenPtr
-DRI2GetScreen(ScreenPtr pScreen)
-{
- return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
-}
-
-static DRI2DrawablePtr
-DRI2GetDrawable(DrawablePtr pDraw)
-{
- WindowPtr pWin;
- PixmapPtr pPixmap;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr) pDraw;
- return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
- } else {
- pPixmap = (PixmapPtr) pDraw;
- return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
- }
-}
-
-static DRI2DrawablePtr
-DRI2AllocateDrawable(DrawablePtr pDraw)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- CARD64 ust;
- WindowPtr pWin;
- PixmapPtr pPixmap;
-
- pPriv = malloc(sizeof *pPriv);
- if (pPriv == NULL)
- return NULL;
-
- pPriv->dri2_screen = ds;
- pPriv->drawable = pDraw;
- pPriv->width = pDraw->width;
- pPriv->height = pDraw->height;
- pPriv->buffers = NULL;
- pPriv->bufferCount = 0;
- pPriv->swapsPending = 0;
- pPriv->blockedClient = NULL;
- pPriv->blockedOnMsc = FALSE;
- pPriv->swap_count = 0;
- pPriv->target_sbc = -1;
- pPriv->swap_interval = 1;
- /* Initialize last swap target from DDX if possible */
- if (!ds->GetMSC || !(*ds->GetMSC)(pDraw, &ust, &pPriv->last_swap_target))
- pPriv->last_swap_target = 0;
-
- pPriv->swap_limit = 1; /* default to double buffering */
- pPriv->last_swap_msc = 0;
- pPriv->last_swap_ust = 0;
- list_init(&pPriv->reference_list);
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr) pDraw;
- dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
- } else {
- pPixmap = (PixmapPtr) pDraw;
- dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
- }
-
- return pPriv;
-}
-
-typedef struct DRI2DrawableRefRec {
- XID id;
- XID dri2_id;
- DRI2InvalidateProcPtr invalidate;
- void *priv;
- struct list link;
-} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
-
-static DRI2DrawableRefPtr
-DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
-{
- DRI2DrawableRefPtr ref;
-
- list_for_each_entry(ref, &pPriv->reference_list, link) {
- if (ref->id == id)
- return ref;
- }
-
- return NULL;
-}
-
-static int
-DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
- DRI2InvalidateProcPtr invalidate, void *priv)
-{
- DRI2DrawableRefPtr ref;
-
- ref = malloc(sizeof *ref);
- if (ref == NULL)
- return BadAlloc;
-
- if (!AddResource(dri2_id, dri2DrawableRes, pPriv))
- return BadAlloc;
- if (!DRI2LookupDrawableRef(pPriv, id))
- if (!AddResource(id, dri2DrawableRes, pPriv))
- return BadAlloc;
-
- ref->id = id;
- ref->dri2_id = dri2_id;
- ref->invalidate = invalidate;
- ref->priv = priv;
- list_add(&ref->link, &pPriv->reference_list);
-
- return Success;
-}
-
-int
-DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
- DRI2InvalidateProcPtr invalidate, void *priv)
-{
- DRI2DrawablePtr pPriv;
- XID dri2_id;
- int rc;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- pPriv = DRI2AllocateDrawable(pDraw);
- if (pPriv == NULL)
- return BadAlloc;
-
- dri2_id = FakeClientID(client->index);
- rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
- if (rc != Success)
- return rc;
-
- return Success;
-}
-
-static int DRI2DrawableGone(pointer p, XID id)
-{
- DRI2DrawablePtr pPriv = p;
- DRI2ScreenPtr ds = pPriv->dri2_screen;
- DRI2DrawableRefPtr ref, next;
- WindowPtr pWin;
- PixmapPtr pPixmap;
- DrawablePtr pDraw;
- int i;
-
- list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
- if (ref->dri2_id == id) {
- list_del(&ref->link);
- /* If this was the last ref under this X drawable XID,
- * unregister the X drawable resource. */
- if (!DRI2LookupDrawableRef(pPriv, ref->id))
- FreeResourceByType(ref->id, dri2DrawableRes, TRUE);
- free(ref);
- break;
- }
-
- if (ref->id == id) {
- list_del(&ref->link);
- FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
- free(ref);
- }
- }
-
- if (!list_is_empty(&pPriv->reference_list))
- return Success;
-
- pDraw = pPriv->drawable;
- if (pDraw->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr) pDraw;
- dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
- } else {
- pPixmap = (PixmapPtr) pDraw;
- dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
- }
-
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++)
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
-
- free(pPriv->buffers);
- }
-
- free(pPriv);
-
- return Success;
-}
-
-static int
-find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
-{
- int i;
-
- if (pPriv->buffers == NULL) {
- return -1;
- }
-
- for (i = 0; i < pPriv->bufferCount; i++) {
- if ((pPriv->buffers[i] != NULL)
- && (pPriv->buffers[i]->attachment == attachment)) {
- return i;
- }
- }
-
- return -1;
-}
-
-static Bool
-allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
- DRI2DrawablePtr pPriv,
- unsigned int attachment, unsigned int format,
- int dimensions_match, DRI2BufferPtr *buffer)
-{
- int old_buf = find_attachment(pPriv, attachment);
-
- if ((old_buf < 0)
- || !dimensions_match
- || (pPriv->buffers[old_buf]->format != format)) {
- *buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
- return TRUE;
-
- } else {
- *buffer = pPriv->buffers[old_buf];
- pPriv->buffers[old_buf] = NULL;
- return FALSE;
- }
-}
-
-static void
-update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
- DRI2BufferPtr *buffers, int *out_count, int *width, int *height)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- int i;
-
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++) {
- if (pPriv->buffers[i] != NULL) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- }
- }
-
- free(pPriv->buffers);
- }
-
- pPriv->buffers = buffers;
- pPriv->bufferCount = *out_count;
- pPriv->width = pDraw->width;
- pPriv->height = pDraw->height;
- *width = pPriv->width;
- *height = pPriv->height;
-}
-
-static DRI2BufferPtr *
-do_get_buffers(DrawablePtr pDraw, int *width, int *height,
- unsigned int *attachments, int count, int *out_count,
- int has_format)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
- DRI2BufferPtr *buffers;
- int need_real_front = 0;
- int need_fake_front = 0;
- int have_fake_front = 0;
- int front_format = 0;
- int dimensions_match;
- int buffers_changed = 0;
- int i;
-
- if (!pPriv) {
- *width = pDraw->width;
- *height = pDraw->height;
- *out_count = 0;
- return NULL;
- }
-
- dimensions_match = (pDraw->width == pPriv->width)
- && (pDraw->height == pPriv->height);
-
- buffers = malloc((count + 1) * sizeof(buffers[0]));
-
- for (i = 0; i < count; i++) {
- const unsigned attachment = *(attachments++);
- const unsigned format = (has_format) ? *(attachments++) : 0;
-
- if (allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
- format, dimensions_match,
- &buffers[i]))
- buffers_changed = 1;
-
- if (buffers[i] == NULL)
- goto err_out;
-
- /* If the drawable is a window and the front-buffer is requested,
- * silently add the fake front-buffer to the list of requested
- * attachments. The counting logic in the loop accounts for the case
- * where the client requests both the fake and real front-buffer.
- */
- if (attachment == DRI2BufferBackLeft) {
- need_real_front++;
- front_format = format;
- }
-
- if (attachment == DRI2BufferFrontLeft) {
- need_real_front--;
- front_format = format;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- need_fake_front++;
- }
- }
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- if (attachment == DRI2BufferFakeFrontLeft) {
- need_fake_front--;
- have_fake_front = 1;
- }
- }
- }
-
- if (need_real_front > 0) {
- if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFrontLeft,
- front_format, dimensions_match,
- &buffers[i++]))
- buffers_changed = 1;
-
- if (buffers[i] == NULL)
- goto err_out;
- }
-
- if (need_fake_front > 0) {
- if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFakeFrontLeft,
- front_format, dimensions_match,
- &buffers[i++]))
- buffers_changed = 1;
-
- if (buffers[i] == NULL)
- goto err_out;
-
- have_fake_front = 1;
- }
-
- *out_count = i;
-
- update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
-
- /* If the client is getting a fake front-buffer, pre-fill it with the
- * contents of the real front-buffer. This ensures correct operation of
- * applications that call glXWaitX before calling glDrawBuffer.
- */
- if (have_fake_front && buffers_changed) {
- BoxRec box;
- RegionRec region;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pPriv->width;
- box.y2 = pPriv->height;
- REGION_INIT(pDraw->pScreen, &region, &box, 0);
-
- DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
- DRI2BufferFrontLeft);
- }
-
- return pPriv->buffers;
-
-err_out:
-
- *out_count = 0;
-
- for (i = 0; i < count; i++) {
- if (buffers[i] != NULL)
- (*ds->DestroyBuffer)(pDraw, buffers[i]);
- }
-
- free(buffers);
- buffers = NULL;
-
- update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
-
- return buffers;
-}
-
-DRI2BufferPtr *
-DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
- unsigned int *attachments, int count, int *out_count)
-{
- return do_get_buffers(pDraw, width, height, attachments, count,
- out_count, FALSE);
-}
-
-DRI2BufferPtr *
-DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
- unsigned int *attachments, int count, int *out_count)
-{
- return do_get_buffers(pDraw, width, height, attachments, count,
- out_count, TRUE);
-}
-
-static void
-DRI2InvalidateDrawable(DrawablePtr pDraw)
-{
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
- DRI2DrawableRefPtr ref;
-
- if (!pPriv)
- return;
-
- list_for_each_entry(ref, &pPriv->reference_list, link)
- ref->invalidate(pDraw, ref->priv);
-}
-
-/*
- * In the direct rendered case, we throttle the clients that have more
- * than their share of outstanding swaps (and thus busy buffers) when a
- * new GetBuffers request is received. In the AIGLX case, we allow the
- * client to get the new buffers, but throttle when the next GLX request
- * comes in (see __glXDRIcontextWait()).
- */
-Bool
-DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return FALSE;
-
- /* Throttle to swap limit */
- if ((pPriv->swapsPending >= pPriv->swap_limit) &&
- !pPriv->blockedClient) {
- ResetCurrentRequest(client);
- client->sequence--;
- IgnoreClient(client);
- pPriv->blockedClient = client;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
-{
- if (pPriv->blockedClient == NULL) {
- IgnoreClient(client);
- pPriv->blockedClient = client;
- }
-}
-
-void
-DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return;
-
- __DRI2BlockClient(client, pPriv);
- pPriv->blockedOnMsc = TRUE;
-}
-
-int
-DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
- unsigned int dest, unsigned int src)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- DRI2BufferPtr pDestBuffer, pSrcBuffer;
- int i;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return BadDrawable;
-
- pDestBuffer = NULL;
- pSrcBuffer = NULL;
- for (i = 0; i < pPriv->bufferCount; i++)
- {
- if (pPriv->buffers[i]->attachment == dest)
- pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- if (pPriv->buffers[i]->attachment == src)
- pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- }
- if (pSrcBuffer == NULL || pDestBuffer == NULL)
- return BadValue;
-
- (*ds->CopyRegion)(pDraw, pRegion, pDestBuffer, pSrcBuffer);
-
- return Success;
-}
-
-/* Can this drawable be page flipped? */
-Bool
-DRI2CanFlip(DrawablePtr pDraw)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- WindowPtr pWin, pRoot;
- PixmapPtr pWinPixmap, pRootPixmap;
-
- if (pDraw->type == DRAWABLE_PIXMAP)
- return TRUE;
-
- pRoot = WindowTable[pScreen->myNum];
- pRootPixmap = pScreen->GetWindowPixmap(pRoot);
-
- pWin = (WindowPtr) pDraw;
- pWinPixmap = pScreen->GetWindowPixmap(pWin);
- if (pRootPixmap != pWinPixmap)
- return FALSE;
- if (!REGION_EQUAL(pScreen, &pWin->clipList, &pRoot->winSize))
- return FALSE;
-
- return TRUE;
-}
-
-/* Can we do a pixmap exchange instead of a blit? */
-Bool
-DRI2CanExchange(DrawablePtr pDraw)
-{
- return FALSE;
-}
-
-void
-DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
- unsigned int tv_sec, unsigned int tv_usec)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return;
-
- ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
- frame, pPriv->swap_count);
-
- if (pPriv->blockedClient)
- AttendClient(pPriv->blockedClient);
-
- pPriv->blockedClient = NULL;
- pPriv->blockedOnMsc = FALSE;
-}
-
-static void
-DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
- unsigned int tv_sec, unsigned int tv_usec)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return;
- }
-
- /*
- * Swap completed.
- * Wake the client iff:
- * - it was waiting on SBC
- * - was blocked due to GLX make current
- * - was blocked due to swap throttling
- * - is not blocked due to an MSC wait
- */
- if (pPriv->target_sbc != -1 &&
- pPriv->target_sbc <= pPriv->swap_count) {
- ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
- frame, pPriv->swap_count);
- pPriv->target_sbc = -1;
-
- AttendClient(pPriv->blockedClient);
- pPriv->blockedClient = NULL;
- } else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
- if (pPriv->blockedClient) {
- AttendClient(pPriv->blockedClient);
- pPriv->blockedClient = NULL;
- }
- }
-}
-
-void
-DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
- unsigned int tv_sec, unsigned int tv_usec, int type,
- DRI2SwapEventPtr swap_complete, void *swap_data)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2DrawablePtr pPriv;
- CARD64 ust = 0;
- BoxRec box;
- RegionRec region;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return;
- }
-
- pPriv->swapsPending--;
- pPriv->swap_count++;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pDraw->width;
- box.y2 = pDraw->height;
- REGION_INIT(pScreen, &region, &box, 0);
- DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
- DRI2BufferFrontLeft);
-
- ust = ((CARD64)tv_sec * 1000000) + tv_usec;
- if (swap_complete)
- swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
-
- pPriv->last_swap_msc = frame;
- pPriv->last_swap_ust = ust;
-
- DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
-}
-
-Bool
-DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
-{
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
-
- /* If we're currently waiting for a swap on this drawable, reset
- * the request and suspend the client. We only support one
- * blocked client per drawable. */
- if ((pPriv->swapsPending) &&
- pPriv->blockedClient == NULL) {
- ResetCurrentRequest(client);
- client->sequence--;
- __DRI2BlockClient(client, pPriv);
- return TRUE;
- }
-
- return FALSE;
-}
-
-int
-DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
- CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
- DRI2SwapEventPtr func, void *data)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
- int ret, i;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return BadDrawable;
- }
-
- for (i = 0; i < pPriv->bufferCount; i++) {
- if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft)
- pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft)
- pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
- }
- if (pSrcBuffer == NULL || pDestBuffer == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: drawable has no back or front?\n", __func__);
- return BadDrawable;
- }
-
- /* Old DDX or no swap interval, just blit */
- if (!ds->ScheduleSwap || !pPriv->swap_interval) {
- BoxRec box;
- RegionRec region;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pDraw->width;
- box.y2 = pDraw->height;
- REGION_INIT(pScreen, &region, &box, 0);
-
- pPriv->swapsPending++;
-
- (*ds->CopyRegion)(pDraw, &region, pDestBuffer, pSrcBuffer);
- DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
- func, data);
- return Success;
- }
-
- /*
- * In the simple glXSwapBuffers case, all params will be 0, and we just
- * need to schedule a swap for the last swap target + the swap interval.
- */
- if (target_msc == 0 && divisor == 0 && remainder == 0) {
- /*
- * Swap target for this swap is last swap target + swap interval since
- * we have to account for the current swap count, interval, and the
- * number of pending swaps.
- */
- *swap_target = pPriv->last_swap_target + pPriv->swap_interval;
- } else {
- /* glXSwapBuffersMscOML could have a 0 target_msc, honor it */
- *swap_target = target_msc;
- }
-
- pPriv->swapsPending++;
- ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
- swap_target, divisor, remainder, func, data);
- if (!ret) {
- pPriv->swapsPending--; /* didn't schedule */
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: driver failed to schedule swap\n", __func__);
- return BadDrawable;
- }
-
- pPriv->last_swap_target = *swap_target;
-
- /* According to spec, return expected swapbuffers count SBC after this swap
- * will complete.
- */
- *swap_target = pPriv->swap_count + pPriv->swapsPending;
-
- DRI2InvalidateDrawable(pDraw);
-
- return Success;
-}
-
-void
-DRI2SwapInterval(DrawablePtr pDrawable, int interval)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
-
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return;
- }
-
- /* fixme: check against arbitrary max? */
- pPriv->swap_interval = interval;
-}
-
-int
-DRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- Bool ret;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[DRI2] %s: bad drawable\n", __func__);
- return BadDrawable;
- }
-
- if (!ds->GetMSC) {
- *ust = 0;
- *msc = 0;
- *sbc = pPriv->swap_count;
- return Success;
- }
-
- /*
- * Spec needs to be updated to include unmapped or redirected
- * drawables
- */
-
- ret = (*ds->GetMSC)(pDraw, ust, msc);
- if (!ret)
- return BadDrawable;
-
- *sbc = pPriv->swap_count;
-
- return Success;
-}
-
-int
-DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
- CARD64 divisor, CARD64 remainder)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
- DRI2DrawablePtr pPriv;
- Bool ret;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return BadDrawable;
-
- /* Old DDX just completes immediately */
- if (!ds->ScheduleWaitMSC) {
- DRI2WaitMSCComplete(client, pDraw, target_msc, 0, 0);
-
- return Success;
- }
-
- ret = (*ds->ScheduleWaitMSC)(client, pDraw, target_msc, divisor, remainder);
- if (!ret)
- return BadDrawable;
-
- return Success;
-}
-
-int
-DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
- CARD64 *ust, CARD64 *msc, CARD64 *sbc)
-{
- DRI2DrawablePtr pPriv;
-
- pPriv = DRI2GetDrawable(pDraw);
- if (pPriv == NULL)
- return BadDrawable;
-
- /* target_sbc == 0 means to block until all pending swaps are
- * finished. Recalculate target_sbc to get that behaviour.
- */
- if (target_sbc == 0)
- target_sbc = pPriv->swap_count + pPriv->swapsPending;
-
- /* If current swap count already >= target_sbc,
- * return immediately with (ust, msc, sbc) triplet of
- * most recent completed swap.
- */
- if (pPriv->swap_count >= target_sbc) {
- *sbc = pPriv->swap_count;
- *msc = pPriv->last_swap_msc;
- *ust = pPriv->last_swap_ust;
- return Success;
- }
-
- pPriv->target_sbc = target_sbc;
- __DRI2BlockClient(client, pPriv);
-
- return Success;
-}
-
-Bool
-DRI2HasSwapControl(ScreenPtr pScreen)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-
- return (ds->ScheduleSwap && ds->GetMSC);
-}
-
-Bool
-DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
- const char **driverName, const char **deviceName)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-
- if (ds == NULL || driverType >= ds->numDrivers ||
- !ds->driverNames[driverType])
- return FALSE;
-
- *fd = ds->fd;
- *driverName = ds->driverNames[driverType];
- *deviceName = ds->deviceName;
-
- return TRUE;
-}
-
-Bool
-DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-
- if (ds == NULL || drmAuthMagic(ds->fd, magic))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
- WindowPtr pSib)
-{
- DrawablePtr pDraw = (DrawablePtr)pWin;
- ScreenPtr pScreen = pDraw->pScreen;
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
- DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
-
- if (ds->ConfigNotify) {
- pScreen->ConfigNotify = ds->ConfigNotify;
-
- (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
-
- ds->ConfigNotify = pScreen->ConfigNotify;
- pScreen->ConfigNotify = DRI2ConfigNotify;
- }
-
- if (!dd || (dd->width == w && dd->height == h))
- return;
-
- DRI2InvalidateDrawable(pDraw);
-}
-
-Bool
-DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
-{
- DRI2ScreenPtr ds;
- const char* driverTypeNames[] = {
- "DRI", /* DRI2DriverDRI */
- "VDPAU", /* DRI2DriverVDPAU */
- };
- unsigned int i;
- CARD8 cur_minor;
-
- if (info->version < 3)
- return FALSE;
-
- if (!xf86VGAarbiterAllowDRI(pScreen)) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "[DRI2] Direct rendering is not supported when VGA arb is necessary for the device\n");
- return FALSE;
- }
-
- ds = calloc(1, sizeof *ds);
- if (!ds)
- return FALSE;
-
- ds->screen = pScreen;
- ds->fd = info->fd;
- ds->deviceName = info->deviceName;
- dri2_major = 1;
-
- ds->CreateBuffer = info->CreateBuffer;
- ds->DestroyBuffer = info->DestroyBuffer;
- ds->CopyRegion = info->CopyRegion;
-
- if (info->version >= 4) {
- ds->ScheduleSwap = info->ScheduleSwap;
- ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
- ds->GetMSC = info->GetMSC;
- cur_minor = 3;
- } else {
- cur_minor = 1;
- }
-
- /* Initialize minor if needed and set to minimum provied by DDX */
- if (!dri2_minor || dri2_minor > cur_minor)
- dri2_minor = cur_minor;
-
- if (info->version == 3 || info->numDrivers == 0) {
- /* Driver too old: use the old-style driverName field */
- ds->numDrivers = 1;
- ds->driverNames = malloc(sizeof(*ds->driverNames));
- if (!ds->driverNames) {
- free(ds);
- return FALSE;
- }
- ds->driverNames[0] = info->driverName;
- } else {
- ds->numDrivers = info->numDrivers;
- ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames));
- if (!ds->driverNames) {
- free(ds);
- return FALSE;
- }
- memcpy(ds->driverNames, info->driverNames,
- info->numDrivers * sizeof(*ds->driverNames));
- }
-
- dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
-
- ds->ConfigNotify = pScreen->ConfigNotify;
- pScreen->ConfigNotify = DRI2ConfigNotify;
-
- xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
- for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) {
- if (i < ds->numDrivers && ds->driverNames[i]) {
- xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] %s driver: %s\n",
- driverTypeNames[i], ds->driverNames[i]);
- }
- }
-
- return TRUE;
-}
-
-void
-DRI2CloseScreen(ScreenPtr pScreen)
-{
- DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
-
- free(ds->driverNames);
- free(ds);
- dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
-}
-
-extern ExtensionModule dri2ExtensionModule;
-
-static pointer
-DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- static Bool setupDone = FALSE;
-
- dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
-
- if (!setupDone)
- {
- setupDone = TRUE;
- LoadExtension(&dri2ExtensionModule, FALSE);
- }
- else
- {
- if (errmaj)
- *errmaj = LDR_ONCEONLY;
- }
-
- return (pointer) 1;
-}
-
-static XF86ModuleVersionInfo DRI2VersRec =
-{
- "dri2",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- 1, 2, 0,
- ABI_CLASS_EXTENSION,
- ABI_EXTENSION_VERSION,
- MOD_CLASS_NONE,
- { 0, 0, 0, 0 }
-};
-
-_X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
-
-void
-DRI2Version(int *major, int *minor)
-{
- if (major != NULL)
- *major = DRI2VersRec.majorversion;
-
- if (minor != NULL)
- *minor = DRI2VersRec.minorversion;
-}
+/*
+ * Copyright © 2007, 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Soft-
+ * ware"), to deal in the Software without restriction, including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, provided that the above copyright
+ * notice(s) and this permission notice appear in all copies of the Soft-
+ * ware and that both the above copyright notice(s) and this permission
+ * notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+ * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+ * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
+ * QUENTIAL 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 PERFOR-
+ * MANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization of
+ * the copyright holder.
+ *
+ * Authors:
+ * Kristian Høgsberg (krh@redhat.com)
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <errno.h>
+#include <xf86drm.h>
+#include "xf86Module.h"
+#include "list.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "dixstruct.h"
+#include "dri2.h"
+#include "xf86VGAarbiter.h"
+
+#include "xf86.h"
+
+CARD8 dri2_major; /* version of DRI2 supported by DDX */
+CARD8 dri2_minor;
+
+static int dri2ScreenPrivateKeyIndex;
+static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
+static int dri2WindowPrivateKeyIndex;
+static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKeyIndex;
+static int dri2PixmapPrivateKeyIndex;
+static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKeyIndex;
+static RESTYPE dri2DrawableRes;
+
+typedef struct _DRI2Screen *DRI2ScreenPtr;
+
+typedef struct _DRI2Drawable {
+ DRI2ScreenPtr dri2_screen;
+ DrawablePtr drawable;
+ struct list reference_list;
+ int width;
+ int height;
+ DRI2BufferPtr *buffers;
+ int bufferCount;
+ unsigned int swapsPending;
+ ClientPtr blockedClient;
+ Bool blockedOnMsc;
+ int swap_interval;
+ CARD64 swap_count;
+ int64_t target_sbc; /* -1 means no SBC wait outstanding */
+ CARD64 last_swap_target; /* most recently queued swap target */
+ CARD64 last_swap_msc; /* msc at completion of most recent swap */
+ CARD64 last_swap_ust; /* ust at completion of most recent swap */
+ int swap_limit; /* for N-buffering */
+} DRI2DrawableRec, *DRI2DrawablePtr;
+
+typedef struct _DRI2Screen {
+ ScreenPtr screen;
+ int refcnt;
+ unsigned int numDrivers;
+ const char **driverNames;
+ const char *deviceName;
+ int fd;
+ unsigned int lastSequence;
+
+ DRI2CreateBufferProcPtr CreateBuffer;
+ DRI2DestroyBufferProcPtr DestroyBuffer;
+ DRI2CopyRegionProcPtr CopyRegion;
+ DRI2ScheduleSwapProcPtr ScheduleSwap;
+ DRI2GetMSCProcPtr GetMSC;
+ DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
+
+ HandleExposuresProcPtr HandleExposures;
+
+ ConfigNotifyProcPtr ConfigNotify;
+} DRI2ScreenRec;
+
+static DRI2ScreenPtr
+DRI2GetScreen(ScreenPtr pScreen)
+{
+ return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
+}
+
+static DRI2DrawablePtr
+DRI2GetDrawable(DrawablePtr pDraw)
+{
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr) pDraw;
+ return dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+ } else {
+ pPixmap = (PixmapPtr) pDraw;
+ return dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+ }
+}
+
+static DRI2DrawablePtr
+DRI2AllocateDrawable(DrawablePtr pDraw)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ CARD64 ust;
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+
+ pPriv = malloc(sizeof *pPriv);
+ if (pPriv == NULL)
+ return NULL;
+
+ pPriv->dri2_screen = ds;
+ pPriv->drawable = pDraw;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ pPriv->buffers = NULL;
+ pPriv->bufferCount = 0;
+ pPriv->swapsPending = 0;
+ pPriv->blockedClient = NULL;
+ pPriv->blockedOnMsc = FALSE;
+ pPriv->swap_count = 0;
+ pPriv->target_sbc = -1;
+ pPriv->swap_interval = 1;
+ /* Initialize last swap target from DDX if possible */
+ if (!ds->GetMSC || !(*ds->GetMSC)(pDraw, &ust, &pPriv->last_swap_target))
+ pPriv->last_swap_target = 0;
+
+ pPriv->swap_limit = 1; /* default to double buffering */
+ pPriv->last_swap_msc = 0;
+ pPriv->last_swap_ust = 0;
+ list_init(&pPriv->reference_list);
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
+ } else {
+ pPixmap = (PixmapPtr) pDraw;
+ dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, pPriv);
+ }
+
+ return pPriv;
+}
+
+typedef struct DRI2DrawableRefRec {
+ XID id;
+ XID dri2_id;
+ DRI2InvalidateProcPtr invalidate;
+ void *priv;
+ struct list link;
+} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
+
+static DRI2DrawableRefPtr
+DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
+{
+ DRI2DrawableRefPtr ref;
+
+ list_for_each_entry(ref, &pPriv->reference_list, link) {
+ if (ref->id == id)
+ return ref;
+ }
+
+ return NULL;
+}
+
+static int
+DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
+{
+ DRI2DrawableRefPtr ref;
+
+ ref = malloc(sizeof *ref);
+ if (ref == NULL)
+ return BadAlloc;
+
+ if (!AddResource(dri2_id, dri2DrawableRes, pPriv))
+ return BadAlloc;
+ if (!DRI2LookupDrawableRef(pPriv, id))
+ if (!AddResource(id, dri2DrawableRes, pPriv))
+ return BadAlloc;
+
+ ref->id = id;
+ ref->dri2_id = dri2_id;
+ ref->invalidate = invalidate;
+ ref->priv = priv;
+ list_add(&ref->link, &pPriv->reference_list);
+
+ return Success;
+}
+
+int
+DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
+{
+ DRI2DrawablePtr pPriv;
+ XID dri2_id;
+ int rc;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ pPriv = DRI2AllocateDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadAlloc;
+
+ dri2_id = FakeClientID(client->index);
+ rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
+ if (rc != Success)
+ return rc;
+
+ return Success;
+}
+
+static int DRI2DrawableGone(pointer p, XID id)
+{
+ DRI2DrawablePtr pPriv = p;
+ DRI2ScreenPtr ds = pPriv->dri2_screen;
+ DRI2DrawableRefPtr ref, next;
+ WindowPtr pWin;
+ PixmapPtr pPixmap;
+ DrawablePtr pDraw;
+ int i;
+
+ list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
+ if (ref->dri2_id == id) {
+ list_del(&ref->link);
+ /* If this was the last ref under this X drawable XID,
+ * unregister the X drawable resource. */
+ if (!DRI2LookupDrawableRef(pPriv, ref->id))
+ FreeResourceByType(ref->id, dri2DrawableRes, TRUE);
+ free(ref);
+ break;
+ }
+
+ if (ref->id == id) {
+ list_del(&ref->link);
+ FreeResourceByType(ref->dri2_id, dri2DrawableRes, TRUE);
+ free(ref);
+ }
+ }
+
+ if (!list_is_empty(&pPriv->reference_list))
+ return Success;
+
+ pDraw = pPriv->drawable;
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr) pDraw;
+ dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+ } else {
+ pPixmap = (PixmapPtr) pDraw;
+ dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
+ }
+
+ if (pPriv->buffers != NULL) {
+ for (i = 0; i < pPriv->bufferCount; i++)
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+
+ free(pPriv->buffers);
+ }
+
+ free(pPriv);
+
+ return Success;
+}
+
+static int
+find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
+{
+ int i;
+
+ if (pPriv->buffers == NULL) {
+ return -1;
+ }
+
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if ((pPriv->buffers[i] != NULL)
+ && (pPriv->buffers[i]->attachment == attachment)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static Bool
+allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
+ DRI2DrawablePtr pPriv,
+ unsigned int attachment, unsigned int format,
+ int dimensions_match, DRI2BufferPtr *buffer)
+{
+ int old_buf = find_attachment(pPriv, attachment);
+
+ if ((old_buf < 0)
+ || !dimensions_match
+ || (pPriv->buffers[old_buf]->format != format)) {
+ *buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
+ return TRUE;
+
+ } else {
+ *buffer = pPriv->buffers[old_buf];
+ pPriv->buffers[old_buf] = NULL;
+ return FALSE;
+ }
+}
+
+static void
+update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
+ DRI2BufferPtr *buffers, int *out_count, int *width, int *height)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ int i;
+
+ if (pPriv->buffers != NULL) {
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if (pPriv->buffers[i] != NULL) {
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ }
+ }
+
+ free(pPriv->buffers);
+ }
+
+ pPriv->buffers = buffers;
+ pPriv->bufferCount = *out_count;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ *width = pPriv->width;
+ *height = pPriv->height;
+}
+
+static DRI2BufferPtr *
+do_get_buffers(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count,
+ int has_format)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2BufferPtr *buffers;
+ int need_real_front = 0;
+ int need_fake_front = 0;
+ int have_fake_front = 0;
+ int front_format = 0;
+ int dimensions_match;
+ int buffers_changed = 0;
+ int i;
+
+ if (!pPriv) {
+ *width = pDraw->width;
+ *height = pDraw->height;
+ *out_count = 0;
+ return NULL;
+ }
+
+ dimensions_match = (pDraw->width == pPriv->width)
+ && (pDraw->height == pPriv->height);
+
+ buffers = malloc((count + 1) * sizeof(buffers[0]));
+
+ for (i = 0; i < count; i++) {
+ const unsigned attachment = *(attachments++);
+ const unsigned format = (has_format) ? *(attachments++) : 0;
+
+ if (allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
+ format, dimensions_match,
+ &buffers[i]))
+ buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
+
+ /* If the drawable is a window and the front-buffer is requested,
+ * silently add the fake front-buffer to the list of requested
+ * attachments. The counting logic in the loop accounts for the case
+ * where the client requests both the fake and real front-buffer.
+ */
+ if (attachment == DRI2BufferBackLeft) {
+ need_real_front++;
+ front_format = format;
+ }
+
+ if (attachment == DRI2BufferFrontLeft) {
+ need_real_front--;
+ front_format = format;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ need_fake_front++;
+ }
+ }
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ if (attachment == DRI2BufferFakeFrontLeft) {
+ need_fake_front--;
+ have_fake_front = 1;
+ }
+ }
+ }
+
+ if (need_real_front > 0) {
+ if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFrontLeft,
+ front_format, dimensions_match,
+ &buffers[i]))
+ buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
+ i++;
+ }
+
+ if (need_fake_front > 0) {
+ if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFakeFrontLeft,
+ front_format, dimensions_match,
+ &buffers[i]))
+ buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
+
+ i++;
+ have_fake_front = 1;
+ }
+
+ *out_count = i;
+
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
+
+ /* If the client is getting a fake front-buffer, pre-fill it with the
+ * contents of the real front-buffer. This ensures correct operation of
+ * applications that call glXWaitX before calling glDrawBuffer.
+ */
+ if (have_fake_front && buffers_changed) {
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pPriv->width;
+ box.y2 = pPriv->height;
+ REGION_INIT(pDraw->pScreen, &region, &box, 0);
+
+ DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+ }
+
+ return pPriv->buffers;
+
+err_out:
+
+ *out_count = 0;
+
+ for (i = 0; i < count; i++) {
+ if (buffers[i] != NULL)
+ (*ds->DestroyBuffer)(pDraw, buffers[i]);
+ }
+
+ free(buffers);
+ buffers = NULL;
+
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
+
+ return buffers;
+}
+
+DRI2BufferPtr *
+DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count)
+{
+ return do_get_buffers(pDraw, width, height, attachments, count,
+ out_count, FALSE);
+}
+
+DRI2BufferPtr *
+DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
+ unsigned int *attachments, int count, int *out_count)
+{
+ return do_get_buffers(pDraw, width, height, attachments, count,
+ out_count, TRUE);
+}
+
+static void
+DRI2InvalidateDrawable(DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2DrawableRefPtr ref;
+
+ if (!pPriv)
+ return;
+
+ list_for_each_entry(ref, &pPriv->reference_list, link)
+ ref->invalidate(pDraw, ref->priv);
+}
+
+/*
+ * In the direct rendered case, we throttle the clients that have more
+ * than their share of outstanding swaps (and thus busy buffers) when a
+ * new GetBuffers request is received. In the AIGLX case, we allow the
+ * client to get the new buffers, but throttle when the next GLX request
+ * comes in (see __glXDRIcontextWait()).
+ */
+Bool
+DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return FALSE;
+
+ /* Throttle to swap limit */
+ if ((pPriv->swapsPending >= pPriv->swap_limit) &&
+ !pPriv->blockedClient) {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ IgnoreClient(client);
+ pPriv->blockedClient = client;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
+{
+ if (pPriv->blockedClient == NULL) {
+ IgnoreClient(client);
+ pPriv->blockedClient = client;
+ }
+}
+
+void
+DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return;
+
+ __DRI2BlockClient(client, pPriv);
+ pPriv->blockedOnMsc = TRUE;
+}
+
+int
+DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
+ unsigned int dest, unsigned int src)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ DRI2BufferPtr pDestBuffer, pSrcBuffer;
+ int i;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ pDestBuffer = NULL;
+ pSrcBuffer = NULL;
+ for (i = 0; i < pPriv->bufferCount; i++)
+ {
+ if (pPriv->buffers[i]->attachment == dest)
+ pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ if (pPriv->buffers[i]->attachment == src)
+ pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ }
+ if (pSrcBuffer == NULL || pDestBuffer == NULL)
+ return BadValue;
+
+ (*ds->CopyRegion)(pDraw, pRegion, pDestBuffer, pSrcBuffer);
+
+ return Success;
+}
+
+/* Can this drawable be page flipped? */
+Bool
+DRI2CanFlip(DrawablePtr pDraw)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ WindowPtr pWin, pRoot;
+ PixmapPtr pWinPixmap, pRootPixmap;
+
+ if (pDraw->type == DRAWABLE_PIXMAP)
+ return TRUE;
+
+ pRoot = WindowTable[pScreen->myNum];
+ pRootPixmap = pScreen->GetWindowPixmap(pRoot);
+
+ pWin = (WindowPtr) pDraw;
+ pWinPixmap = pScreen->GetWindowPixmap(pWin);
+ if (pRootPixmap != pWinPixmap)
+ return FALSE;
+ if (!REGION_EQUAL(pScreen, &pWin->clipList, &pRoot->winSize))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Can we do a pixmap exchange instead of a blit? */
+Bool
+DRI2CanExchange(DrawablePtr pDraw)
+{
+ return FALSE;
+}
+
+void
+DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return;
+
+ ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
+ frame, pPriv->swap_count);
+
+ if (pPriv->blockedClient)
+ AttendClient(pPriv->blockedClient);
+
+ pPriv->blockedClient = NULL;
+ pPriv->blockedOnMsc = FALSE;
+}
+
+static void
+DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ /*
+ * Swap completed.
+ * Wake the client iff:
+ * - it was waiting on SBC
+ * - was blocked due to GLX make current
+ * - was blocked due to swap throttling
+ * - is not blocked due to an MSC wait
+ */
+ if (pPriv->target_sbc != -1 &&
+ pPriv->target_sbc <= pPriv->swap_count) {
+ ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
+ frame, pPriv->swap_count);
+ pPriv->target_sbc = -1;
+
+ AttendClient(pPriv->blockedClient);
+ pPriv->blockedClient = NULL;
+ } else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
+ if (pPriv->blockedClient) {
+ AttendClient(pPriv->blockedClient);
+ pPriv->blockedClient = NULL;
+ }
+ }
+}
+
+void
+DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec, int type,
+ DRI2SwapEventPtr swap_complete, void *swap_data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2DrawablePtr pPriv;
+ CARD64 ust = 0;
+ BoxRec box;
+ RegionRec region;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ pPriv->swapsPending--;
+ pPriv->swap_count++;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ REGION_INIT(pScreen, &region, &box, 0);
+ DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+
+ ust = ((CARD64)tv_sec * 1000000) + tv_usec;
+ if (swap_complete)
+ swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
+
+ pPriv->last_swap_msc = frame;
+ pPriv->last_swap_ust = ust;
+
+ DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
+}
+
+Bool
+DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+ /* If we're currently waiting for a swap on this drawable, reset
+ * the request and suspend the client. We only support one
+ * blocked client per drawable. */
+ if ((pPriv->swapsPending) &&
+ pPriv->blockedClient == NULL) {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ __DRI2BlockClient(client, pPriv);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int
+DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
+ DRI2SwapEventPtr func, void *data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
+ int ret, i;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return BadDrawable;
+ }
+
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft)
+ pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft)
+ pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ }
+ if (pSrcBuffer == NULL || pDestBuffer == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: drawable has no back or front?\n", __func__);
+ return BadDrawable;
+ }
+
+ /* Old DDX or no swap interval, just blit */
+ if (!ds->ScheduleSwap || !pPriv->swap_interval) {
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ REGION_INIT(pScreen, &region, &box, 0);
+
+ pPriv->swapsPending++;
+
+ (*ds->CopyRegion)(pDraw, &region, pDestBuffer, pSrcBuffer);
+ DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
+ func, data);
+ return Success;
+ }
+
+ /*
+ * In the simple glXSwapBuffers case, all params will be 0, and we just
+ * need to schedule a swap for the last swap target + the swap interval.
+ */
+ if (target_msc == 0 && divisor == 0 && remainder == 0) {
+ /*
+ * Swap target for this swap is last swap target + swap interval since
+ * we have to account for the current swap count, interval, and the
+ * number of pending swaps.
+ */
+ *swap_target = pPriv->last_swap_target + pPriv->swap_interval;
+ } else {
+ /* glXSwapBuffersMscOML could have a 0 target_msc, honor it */
+ *swap_target = target_msc;
+ }
+
+ pPriv->swapsPending++;
+ ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
+ swap_target, divisor, remainder, func, data);
+ if (!ret) {
+ pPriv->swapsPending--; /* didn't schedule */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: driver failed to schedule swap\n", __func__);
+ return BadDrawable;
+ }
+
+ pPriv->last_swap_target = *swap_target;
+
+ /* According to spec, return expected swapbuffers count SBC after this swap
+ * will complete.
+ */
+ *swap_target = pPriv->swap_count + pPriv->swapsPending;
+
+ DRI2InvalidateDrawable(pDraw);
+
+ return Success;
+}
+
+void
+DRI2SwapInterval(DrawablePtr pDrawable, int interval)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ /* fixme: check against arbitrary max? */
+ pPriv->swap_interval = interval;
+}
+
+int
+DRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ Bool ret;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return BadDrawable;
+ }
+
+ if (!ds->GetMSC) {
+ *ust = 0;
+ *msc = 0;
+ *sbc = pPriv->swap_count;
+ return Success;
+ }
+
+ /*
+ * Spec needs to be updated to include unmapped or redirected
+ * drawables
+ */
+
+ ret = (*ds->GetMSC)(pDraw, ust, msc);
+ if (!ret)
+ return BadDrawable;
+
+ *sbc = pPriv->swap_count;
+
+ return Success;
+}
+
+int
+DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ Bool ret;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ /* Old DDX just completes immediately */
+ if (!ds->ScheduleWaitMSC) {
+ DRI2WaitMSCComplete(client, pDraw, target_msc, 0, 0);
+
+ return Success;
+ }
+
+ ret = (*ds->ScheduleWaitMSC)(client, pDraw, target_msc, divisor, remainder);
+ if (!ret)
+ return BadDrawable;
+
+ return Success;
+}
+
+int
+DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
+ CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ /* target_sbc == 0 means to block until all pending swaps are
+ * finished. Recalculate target_sbc to get that behaviour.
+ */
+ if (target_sbc == 0)
+ target_sbc = pPriv->swap_count + pPriv->swapsPending;
+
+ /* If current swap count already >= target_sbc,
+ * return immediately with (ust, msc, sbc) triplet of
+ * most recent completed swap.
+ */
+ if (pPriv->swap_count >= target_sbc) {
+ *sbc = pPriv->swap_count;
+ *msc = pPriv->last_swap_msc;
+ *ust = pPriv->last_swap_ust;
+ return Success;
+ }
+
+ pPriv->target_sbc = target_sbc;
+ __DRI2BlockClient(client, pPriv);
+
+ return Success;
+}
+
+Bool
+DRI2HasSwapControl(ScreenPtr pScreen)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ return (ds->ScheduleSwap && ds->GetMSC);
+}
+
+Bool
+DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
+ const char **driverName, const char **deviceName)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ if (ds == NULL || driverType >= ds->numDrivers ||
+ !ds->driverNames[driverType])
+ return FALSE;
+
+ *fd = ds->fd;
+ *driverName = ds->driverNames[driverType];
+ *deviceName = ds->deviceName;
+
+ return TRUE;
+}
+
+Bool
+DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ if (ds == NULL || drmAuthMagic(ds->fd, magic))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
+ WindowPtr pSib)
+{
+ DrawablePtr pDraw = (DrawablePtr)pWin;
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
+
+ if (ds->ConfigNotify) {
+ pScreen->ConfigNotify = ds->ConfigNotify;
+
+ (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
+
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+ }
+
+ if (!dd || (dd->width == w && dd->height == h))
+ return;
+
+ DRI2InvalidateDrawable(pDraw);
+}
+
+Bool
+DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
+{
+ DRI2ScreenPtr ds;
+ const char* driverTypeNames[] = {
+ "DRI", /* DRI2DriverDRI */
+ "VDPAU", /* DRI2DriverVDPAU */
+ };
+ unsigned int i;
+ CARD8 cur_minor;
+
+ if (info->version < 3)
+ return FALSE;
+
+ if (!xf86VGAarbiterAllowDRI(pScreen)) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[DRI2] Direct rendering is not supported when VGA arb is necessary for the device\n");
+ return FALSE;
+ }
+
+ ds = calloc(1, sizeof *ds);
+ if (!ds)
+ return FALSE;
+
+ ds->screen = pScreen;
+ ds->fd = info->fd;
+ ds->deviceName = info->deviceName;
+ dri2_major = 1;
+
+ ds->CreateBuffer = info->CreateBuffer;
+ ds->DestroyBuffer = info->DestroyBuffer;
+ ds->CopyRegion = info->CopyRegion;
+
+ if (info->version >= 4) {
+ ds->ScheduleSwap = info->ScheduleSwap;
+ ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
+ ds->GetMSC = info->GetMSC;
+ cur_minor = 3;
+ } else {
+ cur_minor = 1;
+ }
+
+ /* Initialize minor if needed and set to minimum provied by DDX */
+ if (!dri2_minor || dri2_minor > cur_minor)
+ dri2_minor = cur_minor;
+
+ if (info->version == 3 || info->numDrivers == 0) {
+ /* Driver too old: use the old-style driverName field */
+ ds->numDrivers = 1;
+ ds->driverNames = malloc(sizeof(*ds->driverNames));
+ if (!ds->driverNames) {
+ free(ds);
+ return FALSE;
+ }
+ ds->driverNames[0] = info->driverName;
+ } else {
+ ds->numDrivers = info->numDrivers;
+ ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames));
+ if (!ds->driverNames) {
+ free(ds);
+ return FALSE;
+ }
+ memcpy(ds->driverNames, info->driverNames,
+ info->numDrivers * sizeof(*ds->driverNames));
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
+
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
+ for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) {
+ if (i < ds->numDrivers && ds->driverNames[i]) {
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] %s driver: %s\n",
+ driverTypeNames[i], ds->driverNames[i]);
+ }
+ }
+
+ return TRUE;
+}
+
+void
+DRI2CloseScreen(ScreenPtr pScreen)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+ free(ds->driverNames);
+ free(ds);
+ dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
+}
+
+extern ExtensionModule dri2ExtensionModule;
+
+static pointer
+DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone, "DRI2Drawable");
+
+ if (!setupDone)
+ {
+ setupDone = TRUE;
+ LoadExtension(&dri2ExtensionModule, FALSE);
+ }
+ else
+ {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ }
+
+ return (pointer) 1;
+}
+
+static XF86ModuleVersionInfo DRI2VersRec =
+{
+ "dri2",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 1, 2, 0,
+ ABI_CLASS_EXTENSION,
+ ABI_EXTENSION_VERSION,
+ MOD_CLASS_NONE,
+ { 0, 0, 0, 0 }
+};
+
+_X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
+
+void
+DRI2Version(int *major, int *minor)
+{
+ if (major != NULL)
+ *major = DRI2VersRec.majorversion;
+
+ if (minor != NULL)
+ *minor = DRI2VersRec.minorversion;
+}
diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m
index c9a0d669f..805ed9933 100644
--- a/xorg-server/hw/xquartz/X11Application.m
+++ b/xorg-server/hw/xquartz/X11Application.m
@@ -1030,20 +1030,32 @@ static inline int ensure_flag(int flags, int device_independent, int device_depe
if(isMouseOrTabletEvent) {
static NSPoint lastpt;
NSWindow *window = [e window];
- NSRect screen = [[[NSScreen screens] objectAtIndex:0] frame];;
-
+ NSRect screen = [[[NSScreen screens] objectAtIndex:0] frame];
+ BOOL hasUntrustedPointerDelta;
+
+ // NSEvents for tablets are not consistent wrt deltaXY between events, so we cannot rely on that
+ // Thus tablets will be subject to the warp-pointer bug worked around by the delta, but tablets
+ // are not normally used in cases where that bug would present itself, so this is a fair tradeoff
+ // <rdar://problem/7111003> deltaX and deltaY are incorrect for NSMouseMoved, NSTabletPointEventSubtype
+ // http://xquartz.macosforge.org/trac/ticket/288
+ hasUntrustedPointerDelta = isTabletEvent;
+
+ // The deltaXY for middle click events also appear erroneous after fast user switching
+ // <rdar://problem/7979468> deltaX and deltaY are incorrect for NSOtherMouseDown and NSOtherMouseUp after FUS
+ // http://xquartz.macosforge.org/trac/ticket/389
+ hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSOtherMouseDown || [e type] == NSOtherMouseUp;
+
+ // The deltaXY for scroll events correspond to the scroll delta, not the pointer delta
+ // <rdar://problem/7989690> deltaXY for wheel events are being sent as mouse movement
+ hasUntrustedPointerDelta = hasUntrustedPointerDelta || [e type] == NSScrollWheel;
+
if (window != nil) {
NSRect frame = [window frame];
location = [e locationInWindow];
location.x += frame.origin.x;
location.y += frame.origin.y;
lastpt = location;
- } else if(isTabletEvent) {
- // NSEvents for tablets are not consistent wrt deltaXY between events, so we cannot rely on that
- // Thus tablets will be subject to the warp-pointer bug worked around by the delta, but tablets
- // are not normally used in cases where that bug would present itself, so this is a fair tradeoff
- // <rdar://problem/7111003> deltaX and deltaY are incorrect for NSMouseMoved, NSTabletPointEventSubtype
- // http://xquartz.macosforge.org/trac/ticket/288
+ } else if(hasUntrustedPointerDelta) {
location = [e locationInWindow];
lastpt = location;
} else {
diff --git a/xorg-server/hw/xquartz/mach-startup/bundle-main.c b/xorg-server/hw/xquartz/mach-startup/bundle-main.c
index 42aa757ea..63a185fc8 100644
--- a/xorg-server/hw/xquartz/mach-startup/bundle-main.c
+++ b/xorg-server/hw/xquartz/mach-startup/bundle-main.c
@@ -75,7 +75,12 @@ extern int noPanoramiXExtension;
static char __crashreporter_info_buff__[4096] = {0};
static const char *__crashreporter_info__ = &__crashreporter_info_buff__[0];
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// This is actually a toolchain requirement, but I'm not sure the correct check,
+// but it should be fine to just only include it for Leopard and later. This line
+// just tells the linker to never strip this symbol (such as for space optimization)
asm (".desc ___crashreporter_info__, 0x10");
+#endif
static const char *__crashreporter_info__base = "X.Org X Server " XSERVER_VERSION " Build Date: " BUILD_DATE;
diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c
index a377be7e8..42a4efefa 100644
--- a/xorg-server/os/log.c
+++ b/xorg-server/os/log.c
@@ -1,617 +1,624 @@
-/*
-
-Copyright 1987, 1998 The Open Group
-
-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.
-
-The above copyright notice and this permission notice 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 OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
-Copyright 1994 Quarterdeck Office Systems.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-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 names of Digital and
-Quarterdeck not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL DIGITAL 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.
-
-*/
-
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/Xos.h>
-#include <stdio.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include <stdlib.h> /* for malloc() */
-#include <errno.h>
-
-#include "input.h"
-#include "site.h"
-#include "opaque.h"
-
-#ifdef WIN32
-#include <process.h>
-#ifndef _MSC_VER
-#define getpid(x) _getpid(x)
-#endif
-#endif
-
-#ifdef _MSC_VER
-#define S_ISREG(m) (((m)&_S_IFMT) == _S_IFREG)
-#endif
-
-#ifdef XF86BIGFONT
-#include "xf86bigfontsrv.h"
-#endif
-
-#ifdef DDXOSVERRORF
-void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
-#endif
-
-static FILE *logFile = NULL;
-static Bool logFlush = FALSE;
-static Bool logSync = FALSE;
-static int logVerbosity = DEFAULT_LOG_VERBOSITY;
-static int logFileVerbosity = DEFAULT_LOG_FILE_VERBOSITY;
-
-/* Buffer to information logged before the log file is opened. */
-static char *saveBuffer = NULL;
-static int bufferSize = 0, bufferUnused = 0, bufferPos = 0;
-static Bool needBuffer = TRUE;
-
-#ifdef __APPLE__
-static char __crashreporter_info_buff__[4096] = {0};
-static const char *__crashreporter_info__ = &__crashreporter_info_buff__[0];
-asm (".desc ___crashreporter_info__, 0x10");
-#endif
-
-/* Prefix strings for log messages. */
-#ifndef X_UNKNOWN_STRING
-#define X_UNKNOWN_STRING "(\?\?)"
-#endif
-#ifndef X_PROBE_STRING
-#define X_PROBE_STRING "(--)"
-#endif
-#ifndef X_CONFIG_STRING
-#define X_CONFIG_STRING "(**)"
-#endif
-#ifndef X_DEFAULT_STRING
-#define X_DEFAULT_STRING "(==)"
-#endif
-#ifndef X_CMDLINE_STRING
-#define X_CMDLINE_STRING "(++)"
-#endif
-#ifndef X_NOTICE_STRING
-#define X_NOTICE_STRING "(!!)"
-#endif
-#ifndef X_ERROR_STRING
-#define X_ERROR_STRING "(EE)"
-#endif
-#ifndef X_WARNING_STRING
-#define X_WARNING_STRING "(WW)"
-#endif
-#ifndef X_INFO_STRING
-#define X_INFO_STRING "(II)"
-#endif
-#ifndef X_NOT_IMPLEMENTED_STRING
-#define X_NOT_IMPLEMENTED_STRING "(NI)"
-#endif
-
-/*
- * LogInit is called to start logging to a file. It is also called (with
- * NULL arguments) when logging to a file is not wanted. It must always be
- * called, otherwise log messages will continue to accumulate in a buffer.
- *
- * %s, if present in the fname or backup strings, is expanded to the display
- * string.
- */
-
-const char *
-LogInit(const char *fname, const char *backup)
-{
- char *logFileName = NULL;
-
- if (fname && *fname) {
- /* malloc() can't be used yet. */
- logFileName = malloc(strlen(fname) + strlen(display) + 1);
- if (!logFileName)
- FatalError("Cannot allocate space for the log file name\n");
- sprintf(logFileName, fname, display);
-
- if (backup && *backup) {
- struct stat buf;
-
- if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) {
- char *suffix;
- char *oldLog;
-
- oldLog = malloc(strlen(logFileName) + strlen(backup) +
- strlen(display) + 1);
- suffix = malloc(strlen(backup) + strlen(display) + 1);
- if (!oldLog || !suffix)
- FatalError("Cannot allocate space for the log file name\n");
- sprintf(suffix, backup, display);
- sprintf(oldLog, "%s%s", logFileName, suffix);
- free(suffix);
- if (rename(logFileName, oldLog) == -1) {
- FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
- logFileName, oldLog);
- }
- free(oldLog);
- }
- }
- if ((logFile = fopen(logFileName, "w")) == NULL)
- FatalError("Cannot open log file \"%s\"\n", logFileName);
- setvbuf(logFile, NULL, _IONBF, 0);
-
- /* Flush saved log information. */
- if (saveBuffer && bufferSize > 0) {
- fwrite(saveBuffer, bufferPos, 1, logFile);
- fflush(logFile);
-#ifndef WIN32
- fsync(fileno(logFile));
-#endif
- }
- }
-
- /*
- * Unconditionally free the buffer, and flag that the buffer is no longer
- * needed.
- */
- if (saveBuffer && bufferSize > 0) {
- free(saveBuffer); /* Must be free(), not free() */
- saveBuffer = NULL;
- bufferSize = 0;
- }
- needBuffer = FALSE;
-
- return logFileName;
-}
-
-void
-LogClose(void)
-{
- if (logFile) {
- fclose(logFile);
- logFile = NULL;
- }
-}
-
-Bool
-LogSetParameter(LogParameter param, int value)
-{
- switch (param) {
- case XLOG_FLUSH:
- logFlush = value ? TRUE : FALSE;
- return TRUE;
- case XLOG_SYNC:
- logSync = value ? TRUE : FALSE;
- return TRUE;
- case XLOG_VERBOSITY:
- logVerbosity = value;
- return TRUE;
- case XLOG_FILE_VERBOSITY:
- logFileVerbosity = value;
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-/* This function does the actual log message writes. */
-
-void
-LogVWrite(int verb, const char *f, va_list args)
-{
- char tmpBuffer[1024];
- int len = 0;
- static Bool newline = TRUE;
-
- if (newline) {
- sprintf(tmpBuffer, "[%10.3f] ", GetTimeInMillis() / 1000.0);
- len = strlen(tmpBuffer);
- if (logFile)
- fwrite(tmpBuffer, len, 1, logFile);
- }
-
- /*
- * Since a va_list can only be processed once, write the string to a
- * buffer, and then write the buffer out to the appropriate output
- * stream(s).
- */
- if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
- vsnprintf(tmpBuffer, sizeof(tmpBuffer)-1, f, args);
- tmpBuffer[sizeof(tmpBuffer)-1]=0;
- len = strlen(tmpBuffer);
- }
- newline = (tmpBuffer[len-1] == '\n');
- if ((verb < 0 || logVerbosity >= verb) && len > 0)
- fwrite(tmpBuffer, len, 1, stderr);
- if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
- if (logFile) {
- fwrite(tmpBuffer, len, 1, logFile);
- if (logFlush) {
- fflush(logFile);
-#ifndef WIN32
- if (logSync)
- fsync(fileno(logFile));
-#endif
- }
- } else if (needBuffer) {
- /*
- * Note, this code is used before OsInit() has been called, so
- * malloc() and friends can't be used.
- */
- if (len > bufferUnused) {
- bufferSize += 1024;
- bufferUnused += 1024;
- if (saveBuffer)
- saveBuffer = realloc(saveBuffer, bufferSize);
- else
- saveBuffer = malloc(bufferSize);
- if (!saveBuffer)
- FatalError("realloc() failed while saving log messages\n");
- }
- bufferUnused -= len;
- memcpy(saveBuffer + bufferPos, tmpBuffer, len);
- bufferPos += len;
- }
- }
-}
-
-void
-LogWrite(int verb, const char *f, ...)
-{
- va_list args;
-
- va_start(args, f);
- LogVWrite(verb, f, args);
- va_end(args);
-}
-
-void
-LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
-{
- const char *s = X_UNKNOWN_STRING;
- char tmpBuf[1024];
-
- /* Ignore verbosity for X_ERROR */
- if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
- switch (type) {
- case X_PROBED:
- s = X_PROBE_STRING;
- break;
- case X_CONFIG:
- s = X_CONFIG_STRING;
- break;
- case X_DEFAULT:
- s = X_DEFAULT_STRING;
- break;
- case X_CMDLINE:
- s = X_CMDLINE_STRING;
- break;
- case X_NOTICE:
- s = X_NOTICE_STRING;
- break;
- case X_ERROR:
- s = X_ERROR_STRING;
- if (verb > 0)
- verb = 0;
- break;
- case X_WARNING:
- s = X_WARNING_STRING;
- break;
- case X_INFO:
- s = X_INFO_STRING;
- break;
- case X_NOT_IMPLEMENTED:
- s = X_NOT_IMPLEMENTED_STRING;
- break;
- case X_UNKNOWN:
- s = X_UNKNOWN_STRING;
- break;
- case X_NONE:
- s = NULL;
- break;
- }
-
- /* if s is not NULL we need a space before format */
- snprintf(tmpBuf, sizeof(tmpBuf), "%s%s%s", s ? s : "",
- s ? " " : "",
- format);
- LogVWrite(verb, tmpBuf, args);
- }
-}
-
-/* Log message with verbosity level specified. */
-void
-LogMessageVerb(MessageType type, int verb, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- LogVMessageVerb(type, verb, format, ap);
- va_end(ap);
-}
-
-/* Log a message with the standard verbosity level of 1. */
-void
-LogMessage(MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- LogVMessageVerb(type, 1, format, ap);
- va_end(ap);
-}
-
-void
-AbortServer(void) _X_NORETURN;
-
-void
-AbortServer(void)
-{
-#ifdef XF86BIGFONT
- XF86BigfontCleanup();
-#endif
- CloseWellKnownConnections();
- OsCleanup(TRUE);
- CloseDownDevices();
- AbortDDX();
- fflush(stderr);
- if (CoreDump)
- OsAbort();
- exit (1);
-}
-
-#define AUDIT_PREFIX "AUDIT: %s: %ld: "
-#ifndef AUDIT_TIMEOUT
-#define AUDIT_TIMEOUT ((CARD32)(120 * 1000)) /* 2 mn */
-#endif
-
-static int nrepeat = 0;
-static int oldlen = -1;
-static OsTimerPtr auditTimer = NULL;
-
-void
-FreeAuditTimer(void)
-{
- if (auditTimer != NULL) {
- /* Force output of pending messages */
- TimerForce(auditTimer);
- TimerFree(auditTimer);
- auditTimer = NULL;
- }
-}
-
-static char *
-AuditPrefix(void)
-{
- time_t tm;
- char *autime, *s;
- char *tmpBuf;
- int len;
-
- time(&tm);
- autime = ctime(&tm);
- if ((s = strchr(autime, '\n')))
- *s = '\0';
- len = strlen(AUDIT_PREFIX) + strlen(autime) + 10 + 1;
- tmpBuf = malloc(len);
- if (!tmpBuf)
- return NULL;
- snprintf(tmpBuf, len, AUDIT_PREFIX, autime, (unsigned long)getpid());
- return tmpBuf;
-}
-
-void
-AuditF(const char * f, ...)
-{
- va_list args;
-
- va_start(args, f);
-
- VAuditF(f, args);
- va_end(args);
-}
-
-static CARD32
-AuditFlush(OsTimerPtr timer, CARD32 now, pointer arg)
-{
- char *prefix;
-
- if (nrepeat > 0) {
- prefix = AuditPrefix();
- ErrorF("%slast message repeated %d times\n",
- prefix != NULL ? prefix : "", nrepeat);
- nrepeat = 0;
- if (prefix != NULL)
- free(prefix);
- return AUDIT_TIMEOUT;
- } else {
- /* if the timer expires without anything to print, flush the message */
- oldlen = -1;
- return 0;
- }
-}
-
-void
-VAuditF(const char *f, va_list args)
-{
- char *prefix;
- char buf[1024];
- int len;
- static char oldbuf[1024];
-
- prefix = AuditPrefix();
- len = vsnprintf(buf, sizeof(buf), f, args);
-
- if (len == oldlen && strcmp(buf, oldbuf) == 0) {
- /* Message already seen */
- nrepeat++;
- } else {
- /* new message */
- if (auditTimer != NULL)
- TimerForce(auditTimer);
- ErrorF("%s%s", prefix != NULL ? prefix : "", buf);
- strlcpy(oldbuf, buf, sizeof(oldbuf));
- oldlen = len;
- nrepeat = 0;
- auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT, AuditFlush, NULL);
- }
- if (prefix != NULL)
- free(prefix);
-}
-
-void
-FatalError(const char *f, ...)
-{
- va_list args;
- static Bool beenhere = FALSE;
-
- if (beenhere)
- ErrorF("\nFatalError re-entered, aborting\n");
- else
- ErrorF("\nFatal server error:\n");
-
- va_start(args, f);
-#ifdef __APPLE__
- (void)vsnprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__), f, args);
-#endif
- VErrorF(f, args);
- va_end(args);
- ErrorF("\n");
- if (!beenhere)
- OsVendorFatalError();
- if (!beenhere) {
- beenhere = TRUE;
- AbortServer();
- } else
- OsAbort();
- /*NOTREACHED*/
-}
-
-void
-VErrorF(const char *f, va_list args)
-{
-#ifdef DDXOSVERRORF
- if (OsVendorVErrorFProc)
- OsVendorVErrorFProc(f, args);
- else
- LogVWrite(-1, f, args);
-#else
- LogVWrite(-1, f, args);
-#endif
-}
-
-void
-ErrorF(const char * f, ...)
-{
- va_list args;
-
- va_start(args, f);
- VErrorF(f, args);
- va_end(args);
-}
-
-/* A perror() workalike. */
-
-void
-Error(char *str)
-{
- char *err = NULL;
- int saveErrno = errno;
-
- if (str) {
- err = malloc(strlen(strerror(saveErrno)) + strlen(str) + 2 + 1);
- if (!err)
- return;
- sprintf(err, "%s: ", str);
- strcat(err, strerror(saveErrno));
- LogWrite(-1, "%s", err);
- free(err);
- } else
- LogWrite(-1, "%s", strerror(saveErrno));
-}
-
-void
-LogPrintMarkers(void)
-{
- /* Show what the message marker symbols mean. */
- LogWrite(0, "Markers: ");
- LogMessageVerb(X_PROBED, 0, "probed, ");
- LogMessageVerb(X_CONFIG, 0, "from config file, ");
- LogMessageVerb(X_DEFAULT, 0, "default setting,\n\t");
- LogMessageVerb(X_CMDLINE, 0, "from command line, ");
- LogMessageVerb(X_NOTICE, 0, "notice, ");
- LogMessageVerb(X_INFO, 0, "informational,\n\t");
- LogMessageVerb(X_WARNING, 0, "warning, ");
- LogMessageVerb(X_ERROR, 0, "error, ");
- LogMessageVerb(X_NOT_IMPLEMENTED, 0, "not implemented, ");
- LogMessageVerb(X_UNKNOWN, 0, "unknown.\n");
-}
-
+/*
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice 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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+Copyright 1994 Quarterdeck Office Systems.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 names of Digital and
+Quarterdeck not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL DIGITAL 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.
+
+*/
+
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/Xos.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <stdlib.h> /* for malloc() */
+#include <errno.h>
+
+#include "input.h"
+#include "site.h"
+#include "opaque.h"
+
+#ifdef WIN32
+#include <process.h>
+#ifndef _MSC_VER
+#define getpid(x) _getpid(x)
+#endif
+#endif
+
+#ifdef _MSC_VER
+#define S_ISREG(m) (((m)&_S_IFMT) == _S_IFREG)
+#endif
+
+#ifdef XF86BIGFONT
+#include "xf86bigfontsrv.h"
+#endif
+
+#ifdef DDXOSVERRORF
+void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
+#endif
+
+static FILE *logFile = NULL;
+static Bool logFlush = FALSE;
+static Bool logSync = FALSE;
+static int logVerbosity = DEFAULT_LOG_VERBOSITY;
+static int logFileVerbosity = DEFAULT_LOG_FILE_VERBOSITY;
+
+/* Buffer to information logged before the log file is opened. */
+static char *saveBuffer = NULL;
+static int bufferSize = 0, bufferUnused = 0, bufferPos = 0;
+static Bool needBuffer = TRUE;
+
+#ifdef __APPLE__
+#include <AvailabilityMacros.h>
+
+static char __crashreporter_info_buff__[4096] = {0};
+static const char *__crashreporter_info__ = &__crashreporter_info_buff__[0];
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+// This is actually a toolchain requirement, but I'm not sure the correct check,
+// but it should be fine to just only include it for Leopard and later. This line
+// just tells the linker to never strip this symbol (such as for space optimization)
+asm (".desc ___crashreporter_info__, 0x10");
+#endif
+#endif
+
+/* Prefix strings for log messages. */
+#ifndef X_UNKNOWN_STRING
+#define X_UNKNOWN_STRING "(\?\?)"
+#endif
+#ifndef X_PROBE_STRING
+#define X_PROBE_STRING "(--)"
+#endif
+#ifndef X_CONFIG_STRING
+#define X_CONFIG_STRING "(**)"
+#endif
+#ifndef X_DEFAULT_STRING
+#define X_DEFAULT_STRING "(==)"
+#endif
+#ifndef X_CMDLINE_STRING
+#define X_CMDLINE_STRING "(++)"
+#endif
+#ifndef X_NOTICE_STRING
+#define X_NOTICE_STRING "(!!)"
+#endif
+#ifndef X_ERROR_STRING
+#define X_ERROR_STRING "(EE)"
+#endif
+#ifndef X_WARNING_STRING
+#define X_WARNING_STRING "(WW)"
+#endif
+#ifndef X_INFO_STRING
+#define X_INFO_STRING "(II)"
+#endif
+#ifndef X_NOT_IMPLEMENTED_STRING
+#define X_NOT_IMPLEMENTED_STRING "(NI)"
+#endif
+
+/*
+ * LogInit is called to start logging to a file. It is also called (with
+ * NULL arguments) when logging to a file is not wanted. It must always be
+ * called, otherwise log messages will continue to accumulate in a buffer.
+ *
+ * %s, if present in the fname or backup strings, is expanded to the display
+ * string.
+ */
+
+const char *
+LogInit(const char *fname, const char *backup)
+{
+ char *logFileName = NULL;
+
+ if (fname && *fname) {
+ /* malloc() can't be used yet. */
+ logFileName = malloc(strlen(fname) + strlen(display) + 1);
+ if (!logFileName)
+ FatalError("Cannot allocate space for the log file name\n");
+ sprintf(logFileName, fname, display);
+
+ if (backup && *backup) {
+ struct stat buf;
+
+ if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) {
+ char *suffix;
+ char *oldLog;
+
+ oldLog = malloc(strlen(logFileName) + strlen(backup) +
+ strlen(display) + 1);
+ suffix = malloc(strlen(backup) + strlen(display) + 1);
+ if (!oldLog || !suffix)
+ FatalError("Cannot allocate space for the log file name\n");
+ sprintf(suffix, backup, display);
+ sprintf(oldLog, "%s%s", logFileName, suffix);
+ free(suffix);
+ if (rename(logFileName, oldLog) == -1) {
+ FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
+ logFileName, oldLog);
+ }
+ free(oldLog);
+ }
+ }
+ if ((logFile = fopen(logFileName, "w")) == NULL)
+ FatalError("Cannot open log file \"%s\"\n", logFileName);
+ setvbuf(logFile, NULL, _IONBF, 0);
+
+ /* Flush saved log information. */
+ if (saveBuffer && bufferSize > 0) {
+ fwrite(saveBuffer, bufferPos, 1, logFile);
+ fflush(logFile);
+#ifndef WIN32
+ fsync(fileno(logFile));
+#endif
+ }
+ }
+
+ /*
+ * Unconditionally free the buffer, and flag that the buffer is no longer
+ * needed.
+ */
+ if (saveBuffer && bufferSize > 0) {
+ free(saveBuffer); /* Must be free(), not free() */
+ saveBuffer = NULL;
+ bufferSize = 0;
+ }
+ needBuffer = FALSE;
+
+ return logFileName;
+}
+
+void
+LogClose(void)
+{
+ if (logFile) {
+ fclose(logFile);
+ logFile = NULL;
+ }
+}
+
+Bool
+LogSetParameter(LogParameter param, int value)
+{
+ switch (param) {
+ case XLOG_FLUSH:
+ logFlush = value ? TRUE : FALSE;
+ return TRUE;
+ case XLOG_SYNC:
+ logSync = value ? TRUE : FALSE;
+ return TRUE;
+ case XLOG_VERBOSITY:
+ logVerbosity = value;
+ return TRUE;
+ case XLOG_FILE_VERBOSITY:
+ logFileVerbosity = value;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/* This function does the actual log message writes. */
+
+void
+LogVWrite(int verb, const char *f, va_list args)
+{
+ char tmpBuffer[1024];
+ int len = 0;
+ static Bool newline = TRUE;
+
+ if (newline) {
+ sprintf(tmpBuffer, "[%10.3f] ", GetTimeInMillis() / 1000.0);
+ len = strlen(tmpBuffer);
+ if (logFile)
+ fwrite(tmpBuffer, len, 1, logFile);
+ }
+
+ /*
+ * Since a va_list can only be processed once, write the string to a
+ * buffer, and then write the buffer out to the appropriate output
+ * stream(s).
+ */
+ if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
+ vsnprintf(tmpBuffer, sizeof(tmpBuffer)-1, f, args);
+ tmpBuffer[sizeof(tmpBuffer)-1]=0;
+ len = strlen(tmpBuffer);
+ }
+ newline = (tmpBuffer[len-1] == '\n');
+ if ((verb < 0 || logVerbosity >= verb) && len > 0)
+ fwrite(tmpBuffer, len, 1, stderr);
+ if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
+ if (logFile) {
+ fwrite(tmpBuffer, len, 1, logFile);
+ if (logFlush) {
+ fflush(logFile);
+#ifndef WIN32
+ if (logSync)
+ fsync(fileno(logFile));
+#endif
+ }
+ } else if (needBuffer) {
+ /*
+ * Note, this code is used before OsInit() has been called, so
+ * malloc() and friends can't be used.
+ */
+ if (len > bufferUnused) {
+ bufferSize += 1024;
+ bufferUnused += 1024;
+ if (saveBuffer)
+ saveBuffer = realloc(saveBuffer, bufferSize);
+ else
+ saveBuffer = malloc(bufferSize);
+ if (!saveBuffer)
+ FatalError("realloc() failed while saving log messages\n");
+ }
+ bufferUnused -= len;
+ memcpy(saveBuffer + bufferPos, tmpBuffer, len);
+ bufferPos += len;
+ }
+ }
+}
+
+void
+LogWrite(int verb, const char *f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ LogVWrite(verb, f, args);
+ va_end(args);
+}
+
+void
+LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
+{
+ const char *s = X_UNKNOWN_STRING;
+ char tmpBuf[1024];
+
+ /* Ignore verbosity for X_ERROR */
+ if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
+ switch (type) {
+ case X_PROBED:
+ s = X_PROBE_STRING;
+ break;
+ case X_CONFIG:
+ s = X_CONFIG_STRING;
+ break;
+ case X_DEFAULT:
+ s = X_DEFAULT_STRING;
+ break;
+ case X_CMDLINE:
+ s = X_CMDLINE_STRING;
+ break;
+ case X_NOTICE:
+ s = X_NOTICE_STRING;
+ break;
+ case X_ERROR:
+ s = X_ERROR_STRING;
+ if (verb > 0)
+ verb = 0;
+ break;
+ case X_WARNING:
+ s = X_WARNING_STRING;
+ break;
+ case X_INFO:
+ s = X_INFO_STRING;
+ break;
+ case X_NOT_IMPLEMENTED:
+ s = X_NOT_IMPLEMENTED_STRING;
+ break;
+ case X_UNKNOWN:
+ s = X_UNKNOWN_STRING;
+ break;
+ case X_NONE:
+ s = NULL;
+ break;
+ }
+
+ /* if s is not NULL we need a space before format */
+ snprintf(tmpBuf, sizeof(tmpBuf), "%s%s%s", s ? s : "",
+ s ? " " : "",
+ format);
+ LogVWrite(verb, tmpBuf, args);
+ }
+}
+
+/* Log message with verbosity level specified. */
+void
+LogMessageVerb(MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ LogVMessageVerb(type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Log a message with the standard verbosity level of 1. */
+void
+LogMessage(MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ LogVMessageVerb(type, 1, format, ap);
+ va_end(ap);
+}
+
+void
+AbortServer(void) _X_NORETURN;
+
+void
+AbortServer(void)
+{
+#ifdef XF86BIGFONT
+ XF86BigfontCleanup();
+#endif
+ CloseWellKnownConnections();
+ OsCleanup(TRUE);
+ CloseDownDevices();
+ AbortDDX();
+ fflush(stderr);
+ if (CoreDump)
+ OsAbort();
+ exit (1);
+}
+
+#define AUDIT_PREFIX "AUDIT: %s: %ld: "
+#ifndef AUDIT_TIMEOUT
+#define AUDIT_TIMEOUT ((CARD32)(120 * 1000)) /* 2 mn */
+#endif
+
+static int nrepeat = 0;
+static int oldlen = -1;
+static OsTimerPtr auditTimer = NULL;
+
+void
+FreeAuditTimer(void)
+{
+ if (auditTimer != NULL) {
+ /* Force output of pending messages */
+ TimerForce(auditTimer);
+ TimerFree(auditTimer);
+ auditTimer = NULL;
+ }
+}
+
+static char *
+AuditPrefix(void)
+{
+ time_t tm;
+ char *autime, *s;
+ char *tmpBuf;
+ int len;
+
+ time(&tm);
+ autime = ctime(&tm);
+ if ((s = strchr(autime, '\n')))
+ *s = '\0';
+ len = strlen(AUDIT_PREFIX) + strlen(autime) + 10 + 1;
+ tmpBuf = malloc(len);
+ if (!tmpBuf)
+ return NULL;
+ snprintf(tmpBuf, len, AUDIT_PREFIX, autime, (unsigned long)getpid());
+ return tmpBuf;
+}
+
+void
+AuditF(const char * f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+
+ VAuditF(f, args);
+ va_end(args);
+}
+
+static CARD32
+AuditFlush(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ char *prefix;
+
+ if (nrepeat > 0) {
+ prefix = AuditPrefix();
+ ErrorF("%slast message repeated %d times\n",
+ prefix != NULL ? prefix : "", nrepeat);
+ nrepeat = 0;
+ if (prefix != NULL)
+ free(prefix);
+ return AUDIT_TIMEOUT;
+ } else {
+ /* if the timer expires without anything to print, flush the message */
+ oldlen = -1;
+ return 0;
+ }
+}
+
+void
+VAuditF(const char *f, va_list args)
+{
+ char *prefix;
+ char buf[1024];
+ int len;
+ static char oldbuf[1024];
+
+ prefix = AuditPrefix();
+ len = vsnprintf(buf, sizeof(buf), f, args);
+
+ if (len == oldlen && strcmp(buf, oldbuf) == 0) {
+ /* Message already seen */
+ nrepeat++;
+ } else {
+ /* new message */
+ if (auditTimer != NULL)
+ TimerForce(auditTimer);
+ ErrorF("%s%s", prefix != NULL ? prefix : "", buf);
+ strlcpy(oldbuf, buf, sizeof(oldbuf));
+ oldlen = len;
+ nrepeat = 0;
+ auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT, AuditFlush, NULL);
+ }
+ if (prefix != NULL)
+ free(prefix);
+}
+
+void
+FatalError(const char *f, ...)
+{
+ va_list args;
+ static Bool beenhere = FALSE;
+
+ if (beenhere)
+ ErrorF("\nFatalError re-entered, aborting\n");
+ else
+ ErrorF("\nFatal server error:\n");
+
+ va_start(args, f);
+#ifdef __APPLE__
+ (void)vsnprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__), f, args);
+#endif
+ VErrorF(f, args);
+ va_end(args);
+ ErrorF("\n");
+ if (!beenhere)
+ OsVendorFatalError();
+ if (!beenhere) {
+ beenhere = TRUE;
+ AbortServer();
+ } else
+ OsAbort();
+ /*NOTREACHED*/
+}
+
+void
+VErrorF(const char *f, va_list args)
+{
+#ifdef DDXOSVERRORF
+ if (OsVendorVErrorFProc)
+ OsVendorVErrorFProc(f, args);
+ else
+ LogVWrite(-1, f, args);
+#else
+ LogVWrite(-1, f, args);
+#endif
+}
+
+void
+ErrorF(const char * f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ VErrorF(f, args);
+ va_end(args);
+}
+
+/* A perror() workalike. */
+
+void
+Error(char *str)
+{
+ char *err = NULL;
+ int saveErrno = errno;
+
+ if (str) {
+ err = malloc(strlen(strerror(saveErrno)) + strlen(str) + 2 + 1);
+ if (!err)
+ return;
+ sprintf(err, "%s: ", str);
+ strcat(err, strerror(saveErrno));
+ LogWrite(-1, "%s", err);
+ free(err);
+ } else
+ LogWrite(-1, "%s", strerror(saveErrno));
+}
+
+void
+LogPrintMarkers(void)
+{
+ /* Show what the message marker symbols mean. */
+ LogWrite(0, "Markers: ");
+ LogMessageVerb(X_PROBED, 0, "probed, ");
+ LogMessageVerb(X_CONFIG, 0, "from config file, ");
+ LogMessageVerb(X_DEFAULT, 0, "default setting,\n\t");
+ LogMessageVerb(X_CMDLINE, 0, "from command line, ");
+ LogMessageVerb(X_NOTICE, 0, "notice, ");
+ LogMessageVerb(X_INFO, 0, "informational,\n\t");
+ LogMessageVerb(X_WARNING, 0, "warning, ");
+ LogMessageVerb(X_ERROR, 0, "error, ");
+ LogMessageVerb(X_NOT_IMPLEMENTED, 0, "not implemented, ");
+ LogMessageVerb(X_UNKNOWN, 0, "unknown.\n");
+}
+