xserver: Branch 'input-hotplug' - 20 commits

Daniel Stone daniels at kemper.freedesktop.org
Thu Nov 2 03:18:15 EET 2006


 GL/mesa/main/Makefile.am                  |    1 
 configure.ac                              |   38 -
 dix/devices.c                             |    6 
 fb/fbpict.c                               |   15 
 fb/fbpict.h                               |   47 +
 hw/kdrive/src/kdrive.h                    |    6 
 hw/kdrive/src/kinput.c                    |   15 
 hw/vfb/InitInput.c                        |    4 
 hw/xfree86/Makefile.am                    |   11 
 hw/xfree86/common/xf86Config.c            |   21 
 hw/xfree86/common/xf86Events.c            |    5 
 hw/xfree86/common/xf86Privstr.h           |    3 
 hw/xfree86/os-support/bsd/Makefile.am     |    1 
 hw/xfree86/os-support/bsd/bsd_bell.c      |   81 ++
 hw/xfree86/os-support/drm/xf86drm.c       |  955 ++++++++++++++++++++++++++++++
 hw/xfree86/os-support/linux/Makefile.am   |    2 
 hw/xfree86/os-support/linux/lnx_bell.c    |   43 +
 hw/xfree86/os-support/solaris/Makefile.am |    2 
 hw/xfree86/os-support/solaris/sun_bell.c  |  184 +++++
 hw/xfree86/os-support/xf86_OSproc.h       |    1 
 hw/xfree86/os-support/xf86drm.h           |    1 
 hw/xfree86/os-support/xf86mm.h            |  210 ++++++
 hw/xnest/Keyboard.c                       |    6 
 include/input.h                           |    6 
 include/libdrm-config.h.in                |   10 
 os/connection.c                           |   42 +
 os/utils.c                                |    2 
 xkb/xkbUtils.c                            |  111 ++-
 28 files changed, 1710 insertions(+), 119 deletions(-)

New commits:
diff-tree 4843d823f4d38d8bd468ce3a8feddbff229ed416 (from parents)
Merge: ba9f5138fc32a7a7b97bcf941bc92751b7c6c2c0 a7b944f0d96c3e0e15e75378a04def1ac96089fb
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Thu Nov 2 03:18:13 2006 +0200

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver into input-hotplug

diff-tree ba9f5138fc32a7a7b97bcf941bc92751b7c6c2c0 (from be291a6d9764cf29a7d9a8114d47d9f41ce856e9)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Thu Nov 2 03:16:10 2006 +0200

    xfree86: allow starting with no input devices
    Add a server flag (AllowEmptyInput), which will inhibit adding the
    standard keyboard and mouse drivers, if there are no input devices in the
    config file.

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 6777f43..4138eb1 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -747,7 +747,8 @@ typedef enum {
     FLAG_HANDLE_SPECIAL_KEYS,
     FLAG_RANDR,
     FLAG_AIGLX,
-    FLAG_IGNORE_ABI
+    FLAG_IGNORE_ABI,
+    FLAG_ALLOW_EMPTY_INPUT,
 } FlagValues;
    
 static OptionInfoRec FlagOptions[] = {
@@ -819,6 +820,8 @@ static OptionInfoRec FlagOptions[] = {
 	{0}, FALSE },
   { FLAG_AIGLX,			"AIGLX",			OPTV_BOOLEAN,
 	{0}, FALSE },
+  { FLAG_ALLOW_EMPTY_INPUT,     "AllowEmptyInput",              OPTV_BOOLEAN,
+        {0}, FALSE },
   { FLAG_IGNORE_ABI,			"IgnoreABI",			OPTV_BOOLEAN,
 	{0}, FALSE },
   { -1,				NULL,				OPTV_NONE,
@@ -1016,6 +1019,10 @@ configServerFlags(XF86ConfFlagsPtr flags
 	xf86Info.aiglxFrom = X_CONFIG;
     }
 
+    xf86Info.allowEmptyInput = FALSE;
+    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &value))
+        xf86Info.allowEmptyInput = TRUE;
+
 /* Make sure that timers don't overflow CARD32's after multiplying */
 #define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
 
@@ -1657,8 +1664,6 @@ configLayout(serverLayoutPtr servlayoutp
     servlayoutp->options = conf_layout->lay_option_lst;
     from = X_DEFAULT;
 
-    if (!checkCoreInputDevices(servlayoutp, FALSE))
-	return FALSE;
     return TRUE;
 }
 
@@ -1717,7 +1722,7 @@ configImpliedLayout(serverLayoutPtr serv
     indp = xnfalloc(sizeof(IDevRec));
     indp->identifier = NULL;
     servlayoutp->inputs = indp;
-    if (!checkCoreInputDevices(servlayoutp, TRUE))
+    if (!xf86Info.allowEmptyInput && checkCoreInputDevices(servlayoutp, TRUE))
 	return FALSE;
     
     return TRUE;
@@ -2303,6 +2308,12 @@ addDefaultModes(MonPtr monitorp)
     return TRUE;
 }
 
+static void
+checkInput(serverLayoutPtr layout) {
+    if (!xf86Info.allowEmptyInput)
+        checkCoreInputDevices(layout, FALSE);
+}
+
 /*
  * load the config file and fill the global data structure
  */
@@ -2424,6 +2435,8 @@ xf86HandleConfigFile(Bool autoconfig)
              return CONFIG_PARSE_ERROR;
     }
 
+    checkInput(&xf86ConfigLayout);
+
     /*
      * Handle some command line options that can override some of the
      * ServerFlags settings.
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 7dfcfea..659e566 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -133,6 +133,9 @@ typedef struct {
 	Bool		allowClosedown;
 	ServerGrabInfoRec server;
     } grabInfo;
+
+    Bool        allowEmptyInput;  /* Allow the server to start with no input
+                                   * devices. */
 } xf86InfoRec, *xf86InfoPtr;
 
 #ifdef DPMSExtension
diff-tree be291a6d9764cf29a7d9a8114d47d9f41ce856e9 (from parents)
Merge: a2d6242106bb3a440faa9cad157e0120dbfa7b6e 6fdfd9dad91d7b7aa292f8c4d268dd27c34de8d3
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Thu Nov 2 03:15:25 2006 +0200

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver into input-hotplug

diff --cc configure.ac
index 8935aa0,058759d..9322a2d
@@@ -889,32 -874,9 +891,32 @@@
  PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
  
  XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
- XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm"
+ XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
  AC_SUBST([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.   gcc should set these flags
 +# when -rdynamic is passed to it, other compilers/linkers may need to be added
 +# here.
 +if test "x$GCC" = "xyes"; then
 +       GCC_WARNINGS1="-Wall -Wpointer-arith -Wstrict-prototypes"
 +       GCC_WARNINGS2="-Wmissing-prototypes -Wmissing-declarations"
 +       GCC_WARNINGS3="-Wnested-externs -fno-strict-aliasing"
 +       GCC_WARNINGS="$GCC_WARNINGS1 $GCC_WARNINGS2 $GCC_WARNINGS3"
 +       if test "x$WERROR" = "xyes"; then
 +               GCC_WARNINGS="${GCC_WARNINGS} -Werror"
 +       fi
 +       XSERVER_CFLAGS="$GCC_WARNINGS $XSERVER_CFLAGS"
 +
 +       LD_EXPORT_SYMBOLS_FLAG="-rdynamic"
 +fi
 +case $host_os in
 +       openbsd*)
 +       LD_EXPORT_SYMBOLS_FLAG="-Wl,--export-dynamic"
 +       ;;
 +esac
 +AC_SUBST([LD_EXPORT_SYMBOLS_FLAG])
 +
  AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes],
                 [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt],
                               [have_clock_gettime=no])])
@@@ -1044,7 -1007,7 +1047,7 @@@
  AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
  
  if test "x$XNEST" = xyes; then
- 	XNEST_LIBS="$XSERVER_LIBS $FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB"
 -	XNEST_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
++	XNEST_LIBS="$XSERVER_LIBS $FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
  	AC_SUBST([XNEST_LIBS])
  fi
  
@@@ -1394,7 -1370,7 +1397,7 @@@
  if test "x$XPRINT" = xyes; then
  	PKG_CHECK_MODULES([XPRINT], [printproto x11 xfont $XDMCP_MODULES xau])
  	XPRINT_EXTENSIONS="$XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $RENDER_LIB $COMPOSITE_LIB $RANDR_LIB $XI_LIB $FIXES_LIB $DAMAGE_LIB $XI_LIB $GLX_LIBS"
- 	XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $CONFIG_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB"
 -	XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB $LIBS"
++	XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $CONFIG_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB $LIBS"
  	AC_SUBST([XPRINT_CFLAGS])
  	AC_SUBST([XPRINT_LIBS])
  
diff-tree a7b944f0d96c3e0e15e75378a04def1ac96089fb (from fbfb35189ef6666707097704b43e052cb2f919ae)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Wed Nov 1 16:17:49 2006 -0800

    If getpeerucred() is available, include pid & zoneid in audit messages too

diff --git a/os/connection.c b/os/connection.c
index 60f3b9f..6ca4010 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -165,6 +165,11 @@ extern __const__ int _nfiles;
 #include <netdnet/dn.h>
 #endif /* DNETCONN */
 
+#ifdef HAS_GETPEERUCRED
+# include <ucred.h>
+# include <zone.h>
+#endif
+
 int lastfdesc;			/* maximum file descriptor */
 
 fd_set WellKnownConnections;	/* Listener mask */
@@ -550,8 +555,13 @@ AuthAudit (ClientPtr client, Bool letin,
     char addr[128];
     char *out = addr;
     int client_uid;
-    char client_uid_string[32];
-    
+    char client_uid_string[64];
+#ifdef HAS_GETPEERUCRED
+    ucred_t *peercred = NULL;
+    pid_t client_pid = -1;
+    zoneid_t client_zid = -1;
+#endif
+
     if (!len)
         strcpy(out, "local host");
     else
@@ -588,10 +598,24 @@ AuthAudit (ClientPtr client, Bool letin,
 	    strcpy(out, "unknown address");
 	}
 
+#ifdef HAS_GETPEERUCRED
+    if (getpeerucred(((OsCommPtr)client->osPrivate)->fd, &peercred) >= 0) {
+	client_uid = ucred_geteuid(peercred);
+	client_pid = ucred_getpid(peercred);
+	client_zid = ucred_getzoneid(peercred);
+
+	ucred_free(peercred);
+	snprintf(client_uid_string, sizeof(client_uid_string),
+		 " (uid %ld, pid %ld, zone %ld)",
+		 (long) client_uid, (long) client_pid, (long) client_zid);
+    }
+#else    
     if (LocalClientCred(client, &client_uid, NULL) != -1) {
 	snprintf(client_uid_string, sizeof(client_uid_string),
 		 " (uid %d)", client_uid);
-    } else {
+    }
+#endif
+    else {
 	client_uid_string[0] = '\0';
     }
     
diff-tree fbfb35189ef6666707097704b43e052cb2f919ae (from 6fdfd9dad91d7b7aa292f8c4d268dd27c34de8d3)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Wed Nov 1 15:11:48 2006 -0800

    Bug #1997: AUDIT messages should contain uid for local accesses
    
    <https://bugs.freedesktop.org/show_bug.cgi?id=1997>

diff --git a/os/connection.c b/os/connection.c
index 571ba58..60f3b9f 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -549,7 +549,9 @@ AuthAudit (ClientPtr client, Bool letin,
 {
     char addr[128];
     char *out = addr;
-
+    int client_uid;
+    char client_uid_string[32];
+    
     if (!len)
         strcpy(out, "local host");
     else
@@ -585,14 +587,22 @@ AuthAudit (ClientPtr client, Bool letin,
 	default:
 	    strcpy(out, "unknown address");
 	}
+
+    if (LocalClientCred(client, &client_uid, NULL) != -1) {
+	snprintf(client_uid_string, sizeof(client_uid_string),
+		 " (uid %d)", client_uid);
+    } else {
+	client_uid_string[0] = '\0';
+    }
     
     if (proto_n)
-	AuditF("client %d %s from %s\n  Auth name: %.*s ID: %d\n", 
+	AuditF("client %d %s from %s%s\n  Auth name: %.*s ID: %d\n", 
 	       client->index, letin ? "connected" : "rejected", addr,
-	       (int)proto_n, auth_proto, auth_id);
+	       client_uid_string, (int)proto_n, auth_proto, auth_id);
     else 
-	AuditF("client %d %s from %s\n", 
-	       client->index, letin ? "connected" : "rejected", addr);
+	AuditF("client %d %s from %s%s\n", 
+	       client->index, letin ? "connected" : "rejected", addr,
+	       client_uid_string);
 }
 
 XID
diff-tree a2d6242106bb3a440faa9cad157e0120dbfa7b6e (from d9a5e3e964b6c91fbca88b50674fce9660b972a4)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Thu Nov 2 00:46:33 2006 +0200

    kdrive:remove Change{Keyboard,Pointer}Device
    This was removed in the DIX, so just axe it.

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index be18586..83da67f 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2269,21 +2269,6 @@ ProcessInputEvents ()
     KdCheckLock ();
 }
 
-/* We don't want to allow people to change the core devices, because the DIX
- * does magical repeating goodness for us. */
-int
-ChangeKeyboardDevice(DeviceIntPtr pOldDev, DeviceIntPtr pDev)
-{
-    return BadDevice;
-}
-
-int
-ChangePointerDevice(DeviceIntPtr pOldDev, DeviceIntPtr pDev, unsigned char x,
-                    unsigned char y)
-{
-    return BadDevice;
-}
-
 /* FIXME use XSECURITY to work out whether the client should be allowed to
  * open and close. */
 void
diff-tree d9a5e3e964b6c91fbca88b50674fce9660b972a4 (from d7d931abe01a8cf555b027f2bcfcccd5e9053e52)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Thu Nov 2 00:45:23 2006 +0200

    XkbCopyKeymap: be more careful with levels, allocate compat/geom
    Take various extra precautions with copying levels across (thanks Chris
    Lee for a gdb session), including allocating when we don't already have a
    coherent map.
    Only free type components if they're present.
    Allocate geometry and compat components if we don't already have them in
    the dest map.

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 0c1ac9c..627ab20 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1082,52 +1082,61 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr
             stype = src->map->types;
             dtype = dst->map->types;
             for (i = 0; i < src->map->num_types; i++, dtype++, stype++) {
-                if (stype->num_levels != dtype->num_levels) {
-                    if (dtype->level_names)
+                if (stype->num_levels) {
+                    if (stype->num_levels != dtype->num_levels &&
+                        dtype->num_levels && dtype->level_names) {
                         tmp = xrealloc(dtype->level_names,
                                        stype->num_levels * sizeof(Atom));
-                    else
+                        if (!tmp)
+                            continue;
+                        dtype->level_names = tmp;
+                    }
+                    else if (!dtype->num_levels || !dtype->level_names) {
                         tmp = xalloc(stype->num_levels * sizeof(Atom));
-                    if (!tmp)
-                        continue; /* don't return FALSE here, try to whack
-                                     all the pointers we can, so we don't
-                                     double-free when going down. */
-                    dtype->level_names = tmp;
+                        if (!tmp)
+                            continue;
+                        dtype->level_names = tmp;
+                    }
                     dtype->num_levels = stype->num_levels;
+                    memcpy(dtype->level_names, stype->level_names,
+                           stype->num_levels * sizeof(Atom));
+                }
+                else {
+                    if (dtype->num_levels && dtype->level_names)
+                        xfree(dtype->level_names);
+                    dtype->num_levels = 0;
+                    dtype->level_names = NULL;
                 }
-                memcpy(dtype->level_names, stype->level_names,
-                       stype->num_levels * sizeof(Atom));
 
                 dtype->name = stype->name;
                 memcpy(&dtype->mods, &stype->mods, sizeof(XkbModsRec));
 
-                if (stype->map) {
-                    if (dtype->map) {
-                        if (stype->map_count != dtype->map_count) {
+                if (stype->map_count) {
+                    if (stype->map) {
+                        if (stype->map_count != dtype->map_count &&
+                            dtype->map_count && dtype->map) {
                             tmp = xrealloc(dtype->map,
                                            stype->map_count *
                                              sizeof(XkbKTMapEntryRec));
                             if (!tmp)
                                 return FALSE;
                             dtype->map = tmp;
+                       }
+                        else if (!dtype->map_count || !dtype->map) {
+                            tmp = xalloc(stype->map_count *
+                                           sizeof(XkbKTMapEntryRec));
+                            if (!tmp)
+                                return FALSE;
+                            dtype->map = tmp;
                         }
-                    }
-                    else {
-                        tmp = xalloc(stype->map_count *
-                                       sizeof(XkbKTMapEntryRec));
-                        if (!tmp)
-                            return FALSE;
-                        dtype->map = tmp;
-                    }
 
-                    dtype->map_count = stype->map_count;
-                    memcpy(dtype->map, stype->map, stype->map_count *
-                                               sizeof(XkbKTMapEntryRec));
-                }
+                        memcpy(dtype->map, stype->map,
+                               stype->map_count * sizeof(XkbKTMapEntryRec));
+                    }
 
-                if (stype->preserve) {
-                    if (dtype->preserve) {
-                        if (stype->map_count != dtype->map_count) {
+                    if (stype->preserve) {
+                        if (stype->map_count != dtype->map_count &&
+                            dtype->map_count && dtype->preserve) {
                             tmp = xrealloc(dtype->preserve,
                                            stype->map_count *
                                              sizeof(XkbModsRec));
@@ -1135,22 +1144,30 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr
                                 return FALSE;
                             dtype->preserve = tmp;
                         }
-                    }
-                    else {
-                        tmp = xalloc(stype->map_count * sizeof(XkbModsRec));
-                        if (!tmp)
-                            return FALSE;
-                        dtype->preserve = tmp;
+                        else if (!dtype->preserve || !dtype->map_count) {
+                            tmp = xalloc(stype->map_count *
+                                         sizeof(XkbModsRec));
+                            if (!tmp)
+                                return FALSE;
+                            dtype->preserve = tmp;
+                        }
+
+                        memcpy(dtype->preserve, stype->preserve,
+                               stype->map_count * sizeof(XkbModsRec));
                     }
 
-                    memcpy(dtype->preserve, stype->preserve,
-                           stype->map_count * sizeof(XkbModsRec));
+                    dtype->map_count = stype->map_count;
                 }
                 else {
-                    if (dtype->preserve) {
-                        xfree(dtype->preserve);
-                        dtype->preserve = NULL;
+                    if (dtype->map_count) {
+                        if (dtype->map)
+                            xfree(dtype->map);
+                        if (dtype->preserve)
+                            xfree(dtype->preserve);
+                        dtype->map_count = 0;
                     }
+                    dtype->map = NULL;
+                    dtype->preserve = NULL;
                 }
             }
         }
@@ -1160,9 +1177,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr
                      i++, dtype++) {
                     if (dtype->level_names)
                         xfree(dtype->level_names);
-                    if (dtype->map)
+                    if (dtype->map && dtype->map_count)
                         xfree(dtype->map);
-                    if (dtype->preserve)
+                    if (dtype->preserve && dtype->preserve)
                         xfree(dtype->preserve);
                 }
                 xfree(dst->map->types);
@@ -1451,6 +1468,12 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr
 
     /* compat */
     if (src->compat) {
+        if (!dst->compat) {
+            dst->compat = xcalloc(1, sizeof(XkbCompatMapRec));
+            if (!dst->compat)
+                return FALSE;
+        }
+
         if (src->compat->sym_interpret) {
             if (src->compat->size_si != dst->compat->size_si) {
                 if (dst->compat->sym_interpret)
@@ -1486,6 +1509,12 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr
 
     /* geometry */
     if (src->geom) {
+        if (!dst->geom) {
+            dst->geom = xcalloc(sizeof(XkbGeometryRec), 1);
+            if (!dst->geom)
+                return FALSE;
+        }
+
         /* properties */
         if (src->geom->num_properties) {
             if (src->geom->num_properties != dst->geom->sz_properties) {
diff-tree 6fdfd9dad91d7b7aa292f8c4d268dd27c34de8d3 (from 40f84793bca40dcc6883d51aefa1bda44bd1ac61)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Nov 1 14:29:59 2006 -0800

    Fix several cases where optimized paths were hit when they shouldn't be.
    
    This fixes a number of rendercheck cases.

diff --git a/fb/fbpict.c b/fb/fbpict.c
index d839994..28503c0 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -930,9 +930,8 @@ fbComposite (CARD8      op,
     case PictOpOver:
 	if (pMask)
 	{
-	    if (srcRepeat &&
-		pSrc->pDrawable->width == 1 &&
-		pSrc->pDrawable->height == 1)
+	    if (fbCanGetSolid(pSrc) &&
+		!maskRepeat)
 	    {
 		srcRepeat = FALSE;
 		if (PICT_FORMAT_COLOR(pSrc->format)) {
@@ -1044,7 +1043,7 @@ fbComposite (CARD8      op,
 	    {
 		if (pSrc->pDrawable == pMask->pDrawable &&
 		    xSrc == xMask && ySrc == yMask &&
-		    !pMask->componentAlpha)
+		    !pMask->componentAlpha && !maskRepeat)
 		{
 		    /* source == mask: non-premultiplied data */
 		    switch (pSrc->format) {
@@ -1108,9 +1107,7 @@ fbComposite (CARD8      op,
 		else
 		{
 		    /* non-repeating source, repeating mask => translucent window */
-		    if (maskRepeat &&
-			pMask->pDrawable->width == 1 &&
-			pMask->pDrawable->height == 1)
+		    if (fbCanGetSolid(pMask))
 		    {
 			if (pSrc->format == PICT_x8r8g8b8 &&
 			    pDst->format == PICT_x8r8g8b8 &&
@@ -1127,9 +1124,7 @@ fbComposite (CARD8      op,
 	}
 	else /* no mask */
 	{
-	    if (srcRepeat &&
-		pSrc->pDrawable->width == 1 &&
-		pSrc->pDrawable->height == 1)
+	    if (fbCanGetSolid(pSrc))
 	    {
 		/* no mask and repeating source */
 		switch (pSrc->format) {
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 19d5557..5cdde9e 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -30,6 +30,13 @@
 
 #include "renderedge.h"
 
+
+#if defined(__GNUC__)
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+
 #define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
 #define FbIntDiv(a,b)	 (((CARD16) (a) * 255) / (b))
 
@@ -67,6 +74,40 @@
 #define Green(x) (((x) >> 8) & 0xff)
 #define Blue(x) ((x) & 0xff)
 
+/**
+ * Returns TRUE if the fbComposeGetSolid can be used to get a single solid
+ * color representing every source sampling location of the picture.
+ */
+static INLINE Bool
+fbCanGetSolid(PicturePtr pict)
+{
+    if (pict->pDrawable == NULL ||
+	pict->pDrawable->width != 1 ||
+	pict->pDrawable->height != 1)
+    {
+	return FALSE;
+    }
+    if (pict->repeat != RepeatNormal)
+	return FALSE;
+
+    switch (pict->format) {
+    case PICT_a8r8g8b8:
+    case PICT_x8r8g8b8:
+    case PICT_a8b8g8r8:
+    case PICT_x8b8g8r8:
+    case PICT_r8g8b8:
+    case PICT_b8g8r8:
+    case PICT_r5g6b5:
+    case PICT_b5g6r5:
+	return TRUE;
+    default:
+	return FALSE;
+    }
+}
+
+#define fbCanGetSolid(pict) \
+(pict->pDrawable != NULL && pict->pDrawable->width == 1 && pict->pDrawable->height == 1)
+
 #define fbComposeGetSolid(pict, bits, fmt) { \
     FbBits	*__bits__; \
     FbStride	__stride__; \
@@ -322,12 +363,6 @@
 #define FASTCALL
 #endif
 
-#if defined(__GNUC__)
-#define INLINE __inline__
-#else
-#define INLINE
-#endif
-
 typedef struct _FbComposeData {
     CARD8	op;
     PicturePtr	src;
diff-tree 40f84793bca40dcc6883d51aefa1bda44bd1ac61 (from c03311a1e78daa291477a67b1bb7206772108c5d)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Wed Nov 1 14:34:46 2006 -0800

    Propogate $LIBS for xtrans, clock_gettime, libm, etc. to libs used for each server

diff --git a/configure.ac b/configure.ac
index 6676ea6..058759d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -874,7 +874,7 @@ PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQ
 PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
 
 XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
-XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm"
+XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
 AC_SUBST([SYS_LIBS])
 
 AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes],
@@ -885,9 +885,9 @@ AC_MSG_CHECKING([for a useful monotonic 
 
 if ! test "x$have_clock_gettime" = xno; then
     if ! test "x$have_clock_gettime" = xyes; then
-        LIBS="$have_clock_gettime"
+        CLOCK_LIBS="$have_clock_gettime"
     else
-        LIBS=""
+        CLOCK_LIBS=""
     fi
 
     AC_RUN_IFELSE([
@@ -912,7 +912,8 @@ AC_MSG_RESULT([$MONOTONIC_CLOCK])
 
 if test "x$MONOTONIC_CLOCK" = xyes; then
     AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
-    XSERVER_LIBS="$XSERVER_LIBS $LIBS"
+    XSERVER_LIBS="$XSERVER_LIBS $CLOCK_LIBS"
+    LIBS="$LIBS $CLOCK_LIBS"
 fi
 
 dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so
@@ -990,7 +991,7 @@ AC_MSG_RESULT([$XVFB])
 AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
 
 if test "x$XVFB" = xyes; then
-	XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB"
+	XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
 	AC_SUBST([XVFB_LIBS])
 fi
 
@@ -1006,7 +1007,7 @@ AC_MSG_RESULT([$XNEST])
 AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
 
 if test "x$XNEST" = xyes; then
-	XNEST_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB"
+	XNEST_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
 	AC_SUBST([XNEST_LIBS])
 fi
 
@@ -1369,7 +1370,7 @@ AC_MSG_RESULT([$XPRINT])
 if test "x$XPRINT" = xyes; then
 	PKG_CHECK_MODULES([XPRINT], [printproto x11 xfont $XDMCP_MODULES xau])
 	XPRINT_EXTENSIONS="$XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $RENDER_LIB $COMPOSITE_LIB $RANDR_LIB $XI_LIB $FIXES_LIB $DAMAGE_LIB $XI_LIB $GLX_LIBS"
-	XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB"
+	XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB $LIBS"
 	AC_SUBST([XPRINT_CFLAGS])
 	AC_SUBST([XPRINT_LIBS])
 
diff-tree d7d931abe01a8cf555b027f2bcfcccd5e9053e52 (from 81728558a044fdde0e1d63da7b6314755f77296e)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Nov 1 23:48:58 2006 +0200

    configure.ac: remove check for rate/period
    Keyboard stuff is now handled in the kbd driver.

diff --git a/configure.ac b/configure.ac
index aa6c607..8935aa0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1194,25 +1194,6 @@ dnl has it in libc), or if libdl is need
 		  *)
 			;;
 		esac
-
-		# check whether struct kbd_repeat has the 'period' field.
-		# on kernels < 2.5.42 it's called 'rate' instead.
-		AC_TRY_COMPILE([
-#include <linux/kd.h>
-#ifdef __sparc__
-#include <asm/param.h>
-#include <asm/kbio.h>
-#endif
-],[
-int main () { 
-	struct kbd_repeat k;
-	k.period = 0;
-	return 0;
-}],
-		[period_field="period"],
-		[period_field="rate"])
-		AC_DEFINE_UNQUOTED(LNX_KBD_PERIOD_NAME, [$period_field],
-		                   [Name of the period field in struct kbd_repeat])
 		;;
 	  freebsd* | kfreebsd*-gnu)
 	  	XORG_OS="freebsd"
diff-tree 81728558a044fdde0e1d63da7b6314755f77296e (from 3df454719f9cbf6a046cb7458019ec621b3b42ee)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Nov 1 23:10:26 2006 +0200

    input: add non-keyboard bell ringing function
    Add a generic 'ring the bell' function (console bell on Linux and BSD,
    /dev/audio on Solaris), and add DDX functions for this.  Make this the
    core keyboard's bell.
    Port Xvfb and Xnest to this.
    Port XFree86 to this, with OS-specific hooks for Linux, BSD, and Solaris
    taken from foo_io.c in the old layer.

diff --git a/dix/devices.c b/dix/devices.c
index a554f2f..aa04862 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -211,9 +211,11 @@ ActivateDevice(DeviceIntPtr dev)
 }
 
 static void
-CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer ctrl, int something)
+CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
 {
-    return;
+    KeybdCtrl *ctrl = arg;
+
+    DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
 }
 
 static void
diff --git a/hw/vfb/InitInput.c b/hw/vfb/InitInput.c
index 9cb1c02..99cf56c 100644
--- a/hw/vfb/InitInput.c
+++ b/hw/vfb/InitInput.c
@@ -55,6 +55,10 @@ ProcessInputEvents()
     miPointerUpdate();
 }
 
+void DDXRingBell(int volume, int pitch, int duration)
+{
+}
+
 #define VFB_MIN_KEY 8
 #define VFB_MAX_KEY 255
 KeySym  map[MAP_LENGTH * LK201_GLYPHS_PER_KEY];
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 3df201a..4a9f369 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -1128,6 +1128,11 @@ xf86ReloadInputDevs(int sig)
   return;
 }
 
+_X_EXPORT void
+DDXRingBell(int volume, int pitch, int duration) {
+    xf86OSRingBell(volume, pitch, duration);
+}
+
 #ifdef WSCONS_SUPPORT
 
 /* XXX Currently XKB is mandatory. */
diff --git a/hw/xfree86/os-support/bsd/Makefile.am b/hw/xfree86/os-support/bsd/Makefile.am
index 0a0bcab..e456328 100644
--- a/hw/xfree86/os-support/bsd/Makefile.am
+++ b/hw/xfree86/os-support/bsd/Makefile.am
@@ -63,6 +63,7 @@ libbsd_la_SOURCES = \
 	bsd_VTsw.c \
 	bsd_init.c \
 	bsd_mouse.c \
+	bsd_bell.c \
 	$(ARCH_SOURCES) \
 	$(AGP_SOURCES) \
 	$(APM_SOURCES) \
diff --git a/hw/xfree86/os-support/bsd/bsd_bell.c b/hw/xfree86/os-support/bsd/bsd_bell.c
new file mode 100644
index 0000000..60c2ffc
--- /dev/null
+++ b/hw/xfree86/os-support/bsd/bsd_bell.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1992 by Rich Murphey <Rich at Rice.edu>
+ * Copyright 1993 by David Dawes <dawes at xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Rich Murphey and David Dawes 
+ * not be used in advertising or publicity pertaining to distribution of 
+ * the software without specific, written prior permission.  Rich Murphey and
+ * David Dawes make no representations about the suitability of this 
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO 
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID DAWES 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_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <termios.h>
+
+#include "xf86.h"
+#include "xf86Priv.h"
+
+#ifdef WSCONS_SUPPORT
+#define KBD_FD(i) ((i).kbdFd != -1 ? (i).kbdFd : (i).consoleFd)
+#endif
+
+_X_EXPORT void
+xf86OSRingBell(int loudness, int pitch, int duration)
+{
+#ifdef WSCONS_SUPPORT
+        struct wskbd_bell_data wsb;
+#endif
+
+        if (loudness && pitch)
+        {
+#ifdef PCCONS_SUPPORT
+                int data[2];
+#endif
+
+                switch (xf86Info.consType) {
+
+#ifdef PCCONS_SUPPORT
+                case PCCONS:
+                        data[0] = pitch;
+                        data[1] = (duration * loudness) / 50;
+                        ioctl(xf86Info.consoleFd, CONSOLE_X_BELL, data);
+                        break;
+#endif
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+                case SYSCONS:
+                case PCVT:
+                        ioctl(xf86Info.consoleFd, KDMKTONE,
+                              ((1193190 / pitch) & 0xffff) |
+                              (((unsigned long)duration*loudness/50)<<16));
+                        break;
+#endif
+#if defined (WSCONS_SUPPORT)
+                case WSCONS:
+                        wsb.which = WSKBD_BELL_DOALL;
+                        wsb.pitch = pitch;
+                        wsb.period = duration;
+                        wsb.volume = loudness;
+                        ioctl(KBD_FD(xf86Info), WSKBDIO_COMPLEXBELL,
+                                      &wsb);
+                        break;
+#endif
+                }
+        }
+}
diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am
index fc4243b..673a4e1 100644
--- a/hw/xfree86/os-support/linux/Makefile.am
+++ b/hw/xfree86/os-support/linux/Makefile.am
@@ -20,7 +20,7 @@ XORG_CFLAGS += -DHAVE_APM
 endif
 
 liblinux_la_SOURCES = lnx_init.c lnx_video.c lnx_mouse.c \
-                     lnx_pci.c lnx_agp.c lnx_kmod.c \
+                     lnx_pci.c lnx_agp.c lnx_kmod.c lnx_bell.c \
                      $(srcdir)/../shared/bios_mmap.c \
 		     $(srcdir)/../shared/VTsw_usl.c \
 		     $(srcdir)/../shared/posix_tty.c \
diff --git a/hw/xfree86/os-support/linux/lnx_bell.c b/hw/xfree86/os-support/linux/lnx_bell.c
new file mode 100644
index 0000000..6ef881b
--- /dev/null
+++ b/hw/xfree86/os-support/linux/lnx_bell.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2006 Daniel Stone
+ *
+ * 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 this copyright notice and this permission notice appear in
+ * supporting electronic 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 COPYRIGHT HOLDERS OR AUTHORS 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.
+ *
+ * Author: Daniel Stone <daniel at fooishbar.org>
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <sys/ioctl.h>
+#include <linux/kd.h>
+
+#include "xf86.h"
+#include "xf86Priv.h"
+
+_X_EXPORT void
+xf86OSRingBell(int loudness, int pitch, int duration)
+{
+    if (xf86Info.consoleFd == -1 || !pitch || !loudness)
+        return;
+
+    ioctl(xf86Info.consoleFd, KDMKTONE,
+          ((1193190 / pitch) & 0xffff) |
+          (((unsigned long)duration * loudness / 50) << 16));
+}
diff --git a/hw/xfree86/os-support/solaris/Makefile.am b/hw/xfree86/os-support/solaris/Makefile.am
index 9c86079..291c329 100644
--- a/hw/xfree86/os-support/solaris/Makefile.am
+++ b/hw/xfree86/os-support/solaris/Makefile.am
@@ -19,7 +19,7 @@ solaris-$(SOLARIS_INOUT_ARCH).il: solari
 
 noinst_LTLIBRARIES = libsolaris.la
 libsolaris_la_SOURCES = sun_bios.c sun_init.c \
-	sun_mouse.c sun_vid.c $(AGP_SRC) \
+	sun_mouse.c sun_vid.c sun_bell.c $(AGP_SRC) \
 	$(srcdir)/../shared/libc_wrapper.c \
 	$(srcdir)/../shared/kmod_noop.c $(srcdir)/../shared/pm_noop.c \
 	$(srcdir)/../shared/posix_tty.c $(srcdir)/../shared/sigiostubs.c \
diff --git a/hw/xfree86/os-support/solaris/sun_bell.c b/hw/xfree86/os-support/solaris/sun_bell.c
new file mode 100644
index 0000000..369103f
--- /dev/null
+++ b/hw/xfree86/os-support/solaris/sun_bell.c
@@ -0,0 +1,184 @@
+/* Copyright 2004-2005 Sun Microsystems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 Software 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
+ * MERCHANTABILITY, 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 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.
+ * 
+ * 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <sys/audio.h>
+#include <sys/uio.h>
+#include <limits.h>
+#include <math.h>
+#include <poll.h>
+
+#include "xf86.h"
+#include "xf86Priv.h"
+
+#define BELL_RATE       48000   /* Samples per second */
+#define BELL_HZ         50      /* Fraction of a second i.e. 1/x */
+#define BELL_MS         (1000/BELL_HZ)  /* MS */
+#define BELL_SAMPLES    (BELL_RATE / BELL_HZ)
+#define BELL_MIN        3       /* Min # of repeats */
+
+#define AUDIO_DEVICE    "/dev/audio"
+
+_X_EXPORT int
+xf86OSRingBell(int loudness, int pitch, int duration)
+{
+    static short    samples[BELL_SAMPLES];
+    static short    silence[BELL_SAMPLES]; /* "The Sound of Silence" */
+    static int      lastFreq;
+    int             cnt; 
+    int             i;
+    int             written;
+    int             repeats;
+    int             freq;
+    audio_info_t    audioInfo;
+    struct iovec    iov[IOV_MAX];
+    int             iovcnt;
+    double          ampl, cyclen, phase;
+    int             audioFD;
+
+    if ((loudness <= 0) || (pitch <= 0) || (duration <= 0)) {
+        return 0;
+    }
+
+    lastFreq = 0;
+    bzero(silence, sizeof(silence));
+
+    audioFD = open(AUDIO_DEVICE, O_WRONLY | O_NONBLOCK);
+    if (audioFD == -1) {
+        xf86Msg(X_ERROR, "Bell: cannot open audio device \"%s\": %s\n",
+                AUDIO_DEVICE, strerror(errno));
+        return -1;
+    }
+
+    freq = pitch;
+    freq = min(freq, (BELL_RATE / 2) - 1);
+    freq = max(freq, 2 * BELL_HZ);
+
+    /*
+     * Ensure full waves per buffer
+     */
+    freq -= freq % BELL_HZ;
+
+    if (freq != lastFreq) {
+        lastFreq = freq;
+        ampl =  16384.0;
+
+        cyclen = (double) freq / (double) BELL_RATE;
+        phase = 0.0;
+
+        for (i = 0; i < BELL_SAMPLES; i++) {
+            samples[i] = (short) (ampl * sin(2.0 * M_PI * phase));
+            phase += cyclen;
+            if (phase >= 1.0)
+                phase -= 1.0;
+        }
+    }
+
+    repeats = (duration + (BELL_MS / 2)) / BELL_MS;
+    repeats = max(repeats, BELL_MIN);
+
+    loudness = max(0, loudness);
+    loudness = min(loudness, 100);
+
+#ifdef DEBUG
+    ErrorF("BELL : freq %d volume %d duration %d repeats %d\n",
+           freq, loudness, duration, repeats);
+#endif
+
+    AUDIO_INITINFO(&audioInfo);
+    audioInfo.play.encoding = AUDIO_ENCODING_LINEAR;
+    audioInfo.play.sample_rate = BELL_RATE;
+    audioInfo.play.channels = 2;
+    audioInfo.play.precision = 16;
+    audioInfo.play.gain = min(AUDIO_MAX_GAIN, AUDIO_MAX_GAIN * loudness / 100);
+
+    if (ioctl(audioFD, AUDIO_SETINFO, &audioInfo) < 0){
+        xf86Msg(X_ERROR,
+                "Bell: AUDIO_SETINFO failed on audio device \"%s\": %s\n",
+                AUDIO_DEVICE, strerror(errno));
+        close(audioFD);
+        return -1;
+    }
+
+    iovcnt = 0;
+
+    for (cnt = 0; cnt <= repeats; cnt++) {
+        iov[iovcnt].iov_base = (char *) samples;
+        iov[iovcnt++].iov_len = sizeof(samples);
+        if (cnt == repeats) {
+            /* Insert a bit of silence so that multiple beeps are distinct and
+             * not compressed into a single tone.
+             */
+            iov[iovcnt].iov_base = (char *) silence;
+            iov[iovcnt++].iov_len = sizeof(silence);
+        }
+        if ((iovcnt >= IOV_MAX) || (cnt == repeats)) {
+            written = writev(audioFD, iov, iovcnt);
+
+            if ((written < ((int)(sizeof(samples) * iovcnt)))) {
+                /* audio buffer was full! */
+
+                int naptime;
+
+                if (written == -1) {
+                    if (errno != EAGAIN) {
+                        xf86Msg(X_ERROR,
+                               "Bell: writev failed on audio device \"%s\": %s\n",
+                                AUDIO_DEVICE, strerror(errno));
+                        close(audioFD);
+                        return -1;
+                    }
+                    i = iovcnt;
+                } else {
+                    i = ((sizeof(samples) * iovcnt) - written)
+                        / sizeof(samples);
+                }
+                cnt -= i;
+
+                /* sleep a little to allow audio buffer to drain */
+                naptime = BELL_MS * i;
+                poll(NULL, 0, naptime);
+
+                i = ((sizeof(samples) * iovcnt) - written) % sizeof(samples);
+                iovcnt = 0;
+                if ((written != -1) && (i > 0)) {
+                    iov[iovcnt].iov_base = ((char *) samples) + i;
+                    iov[iovcnt++].iov_len = sizeof(samples) - i;
+                }
+            } else {
+                iovcnt = 0;
+            }
+        }
+    }
+
+    close(audioFD);
+    return 0;
+}
diff --git a/hw/xfree86/os-support/xf86_OSproc.h b/hw/xfree86/os-support/xf86_OSproc.h
index c987d75..0311b81 100644
--- a/hw/xfree86/os-support/xf86_OSproc.h
+++ b/hw/xfree86/os-support/xf86_OSproc.h
@@ -174,6 +174,7 @@ extern int xf86GetSerialModemState(int f
 extern int xf86SerialModemSetBits(int fd, int bits);
 extern int xf86SerialModemClearBits(int fd, int bits);
 extern int xf86LoadKernelModule(const char *pathname);
+extern void xf86RingBell(int volume, int pitch, int duration);
 
 /* AGP GART interface */
 
diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index 26a5ed3..0dacae7 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -94,6 +94,12 @@ xnestBell(int volume, DeviceIntPtr pDev,
 }
 
 void
+DDXRingBell(int volume, int pitch, int duration)
+{
+  XBell(xnestDisplay, volume);
+}
+
+void
 xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
 {
 #if 0
diff --git a/include/input.h b/include/input.h
index 3fe6944..f2fe6d1 100644
--- a/include/input.h
+++ b/include/input.h
@@ -441,7 +441,9 @@ extern DeviceIntPtr LookupDeviceIntRec(
 extern int NewInputDeviceRequest(
     InputOption *options);
 
-extern DeviceIntPtr LookupDeviceIntRec(
-    CARD8 deviceid);
+extern void DDXRingBell(
+    int volume,
+    int pitch,
+    int duration);
 
 #endif /* INPUT_H */
diff-tree 3df454719f9cbf6a046cb7458019ec621b3b42ee (from 644ee2434a4e09f5baea00a486911f8c24b9a261)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Nov 1 23:02:57 2006 +0200

    kdrive: add KdRingBell prototype

diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
index f0fc909..ced48d7 100644
--- a/hw/kdrive/src/kdrive.h
+++ b/hw/kdrive/src/kdrive.h
@@ -872,6 +872,12 @@ KdEnableInput (void);
 void
 ProcessInputEvents (void);
 
+void
+KdRingBell (KdKeyboardInfo      *ki,
+            int                 volume,
+            int                 pitch,
+            int                 duration);
+
 extern KdPointerDriver	LinuxMouseDriver;
 extern KdPointerDriver	LinuxEvdevDriver;
 extern KdPointerDriver	Ps2MouseDriver;
diff-tree c03311a1e78daa291477a67b1bb7206772108c5d (from a2434ec5f3c9dc79d1f05c2d704a82a766718ed4)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Tue Oct 31 16:05:48 2006 -0800

    Fix automake error: BUILT_SOURCES was defined multiple times on Solaris

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 64c54f8..72befea 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -58,12 +58,15 @@ Xorg_LDADD = $(XORG_LIBS) \
 
 Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
 
+BUILT_SOURCES = xorg.conf.example
+CLEAN = xorg.conf.example xorg.conf.example.pre
+EXTRA_DIST = xorgconf.cpp
 
 if SOLARIS_ASM_INLINE
 # Needs to be built before any files are compiled when using Sun compilers
 # so in*/out* inline definitions are properly processed.
 
-BUILT_SOURCES = os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il
+BUILT_SOURCES += os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il
 
 os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il:
 	cd os-support/solaris ; make solaris-$(SOLARIS_INOUT_ARCH).il
@@ -84,10 +87,6 @@ endif
 optionsdir = $(libdir)/X11
 dist_options_DATA = Options
 
-BUILT_SOURCES = xorg.conf.example
-CLEAN = xorg.conf.example xorg.conf.example.pre
-EXTRA_DIST = xorgconf.cpp
-
 CPP_FILES_FLAGS = \
 	-DRGBPATH=\"$(RGB_DB)\" \
 	-DLOCALFONTPATH="\"$(BASE_FONT_PATH)/local\"" \
diff-tree a2434ec5f3c9dc79d1f05c2d704a82a766718ed4 (from 645d0576205532a3610ae351267d5b84d76236bd)
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date:   Tue Oct 31 15:57:59 2006 -0800

    Make _POSIX_C_SOURCE hack work with Solaris headers
    
    Solaris headers are very literal - if you ask for POSIX_C_SOURCE 199309L,
    they limit to only the functions in that standard and no more, unless you
    also specify __EXTENSIONS__ to allow functions beyond the standard base.

diff --git a/os/utils.c b/os/utils.c
index 7d258a4..f7cdb82 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -58,6 +58,8 @@ OR PERFORMANCE OF THIS SOFTWARE.
 #ifdef _POSIX_C_SOURCE
 #define _SAVED_POSIX_C_SOURCE _POSIX_C_SOURCE
 #undef _POSIX_C_SOURCE
+#else if defined(sun)	/* Needed to tell Solaris headers not to restrict to */
+#define __EXTENSIONS__	/* only the functions defined in POSIX 199309.       */
 #endif
 #define _POSIX_C_SOURCE 199309L
 #include <time.h>
diff-tree 645d0576205532a3610ae351267d5b84d76236bd (from 59584c375f4e4b2670a92002ecb7a78a0bc50cce)
Author: Matthieu Herrb <matthieu.herrb at laas.fr>
Date:   Sun Oct 29 18:19:56 2006 +0100

    Handle building in a separate objdir

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index b62ceaf..64c54f8 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -103,4 +103,4 @@ relink:
 	rm -f Xorg && $(MAKE) Xorg
 
 xorg.conf.example.pre: xorgconf.cpp
-	cp xorgconf.cpp $@
+	cp $(srcdir)/xorgconf.cpp $@
diff-tree 59584c375f4e4b2670a92002ecb7a78a0bc50cce (from 0107320fac0913aae2cb169992e31c670b4bd2f7)
Author: Matthieu Herrb <matthieu.herrb at laas.fr>
Date:   Sun Oct 29 17:49:46 2006 +0100

    kill GNU-make'ism.

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 79d2ec5..b62ceaf 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -103,4 +103,4 @@ relink:
 	rm -f Xorg && $(MAKE) Xorg
 
 xorg.conf.example.pre: xorgconf.cpp
-	cp $< $@
+	cp xorgconf.cpp $@
diff-tree 0107320fac0913aae2cb169992e31c670b4bd2f7 (from parents)
Merge: 06b6b971d065226b983ba25da7ea8236ec37df04 a34446f5b3d90714969a90583c49cb1eae1c9651
Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Date:   Sun Oct 29 15:23:35 2006 +0100

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver

diff-tree 06b6b971d065226b983ba25da7ea8236ec37df04 (from 92d04e746bd9b8ad3ee217c165ace20468e079cf)
Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Date:   Sun Oct 29 15:22:37 2006 +0100

    Make sure we have 64-bit file-offsets in libdrm.

diff --git a/configure.ac b/configure.ac
index 140757f..6676ea6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,7 +49,8 @@ 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 libdrm now needs 64-bit file offsets
+AC_CONFIG_HEADERS(include/libdrm-config.h)
 
 AC_PROG_CC
 AM_PROG_AS
@@ -62,7 +63,6 @@ AC_PROG_MAKE_SET
 PKG_PROG_PKG_CONFIG
 AC_PROG_LEX
 AC_PROG_YACC
-dnl for libdrm
 AC_SYS_LARGEFILE
 XORG_PROG_RAWCPP
 
diff --git a/hw/xfree86/os-support/drm/xf86drm.c b/hw/xfree86/os-support/drm/xf86drm.c
index ade4266..e990e28 100644
--- a/hw/xfree86/os-support/drm/xf86drm.c
+++ b/hw/xfree86/os-support/drm/xf86drm.c
@@ -33,6 +33,7 @@
 
 
 #ifdef HAVE_XORG_CONFIG_H
+#include <libdrm-config.h>
 #include <xorg-config.h>
 #endif
 
diff --git a/include/libdrm-config.h.in b/include/libdrm-config.h.in
new file mode 100644
index 0000000..286004b
--- /dev/null
+++ b/include/libdrm-config.h.in
@@ -0,0 +1,10 @@
+/* 
+ * libdrm-config.h.in: not at all generated.
+ */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
diff-tree a34446f5b3d90714969a90583c49cb1eae1c9651 (from 004d00e6689f452fc9fdf91f5ffc6d6aed697d54)
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Fri Oct 27 13:43:43 2006 -0400

    Add missing file to list in Makefile.am

diff --git a/GL/mesa/main/Makefile.am b/GL/mesa/main/Makefile.am
index 4d5b0cd..64b383d 100644
--- a/GL/mesa/main/Makefile.am
+++ b/GL/mesa/main/Makefile.am
@@ -60,6 +60,7 @@ nodist_libmain_la_SOURCES = accum.c \
                     light.c \
                     lines.c \
                     matrix.c \
+                    mipmap.c \
                     mm.c \
                     occlude.c \
                     pixel.c \
diff-tree 92d04e746bd9b8ad3ee217c165ace20468e079cf (from 004d00e6689f452fc9fdf91f5ffc6d6aed697d54)
Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Date:   Fri Oct 27 18:26:30 2006 +0200

    Import libdrm functions for the drm memory manager.

diff --git a/configure.ac b/configure.ac
index c0cc003..140757f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,6 +62,8 @@ AC_PROG_MAKE_SET
 PKG_PROG_PKG_CONFIG
 AC_PROG_LEX
 AC_PROG_YACC
+dnl for libdrm
+AC_SYS_LARGEFILE
 XORG_PROG_RAWCPP
 
 AC_HEADER_DIRENT
diff --git a/hw/xfree86/os-support/drm/xf86drm.c b/hw/xfree86/os-support/drm/xf86drm.c
index 214e58b..ade4266 100644
--- a/hw/xfree86/os-support/drm/xf86drm.c
+++ b/hw/xfree86/os-support/drm/xf86drm.c
@@ -2305,3 +2305,957 @@ int drmRemoveSIGIOHandler(int fd)
 
     return xf86RemoveSIGIOHandler(fd);
 }
+
+/*
+ * Valid flags are 
+ * DRM_FENCE_FLAG_EMIT
+ * DRM_FENCE_FLAG_SHAREABLE
+ * DRM_FENCE_MASK_DRIVER
+ */
+
+int drmFenceCreate(int fd, unsigned flags, int class,unsigned type, 
+		   drmFence *fence)
+{
+    drm_fence_arg_t arg;
+    
+    memset(&arg, 0, sizeof(arg));
+    arg.type = type;
+    arg.class = class;
+    arg.op = drm_fence_create;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    fence->handle = arg.handle;
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->flags = arg.flags;
+    fence->signaled = 0;
+    return 0;
+}
+
+/*
+ * Valid flags are 
+ * DRM_FENCE_FLAG_SHAREABLE
+ * DRM_FENCE_MASK_DRIVER
+ */
+
+int drmFenceBuffers(int fd, unsigned flags, drmFence *fence)
+{
+    drm_fence_arg_t arg;
+    
+    memset(&arg, 0, sizeof(arg));
+    arg.flags = flags;
+    arg.op = drm_fence_buffers;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    fence->handle = arg.handle;
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->flags = arg.flags;
+    fence->signaled = 0;
+    return 0;
+}
+    
+int drmFenceDestroy(int fd, const drmFence *fence)
+{
+    drm_fence_arg_t arg;
+   
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = fence->handle;
+    arg.op = drm_fence_destroy;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    return 0;
+}
+
+int drmFenceReference(int fd, unsigned handle, drmFence *fence)
+{
+    drm_fence_arg_t arg;
+   
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = handle;
+    arg.op = drm_fence_reference;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    fence->handle = arg.handle;
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->flags = arg.flags;
+    fence->signaled = arg.signaled;
+    return 0;
+}
+
+int drmFenceUnreference(int fd, const drmFence *fence)
+{
+    drm_fence_arg_t arg;
+   
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = fence->handle;
+    arg.op = drm_fence_unreference;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    return 0;
+}
+
+int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type)
+{
+    drm_fence_arg_t arg;
+   
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = fence->handle;
+    arg.type = flush_type;
+    arg.op = drm_fence_flush;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->signaled = arg.signaled;
+    return 0;
+}
+
+int drmFenceUpdate(int fd, drmFence *fence)
+{
+    drm_fence_arg_t arg;
+	
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = fence->handle;
+    arg.op = drm_fence_signaled;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->signaled = arg.signaled;
+    return 0;
+}
+
+int drmFenceSignaled(int fd, drmFence *fence, unsigned fenceType, 
+		     int *signaled)
+{
+    int 
+	ret;
+
+    if ((fence->flags & DRM_FENCE_FLAG_SHAREABLE) ||
+	((fenceType & fence->signaled) != fenceType)) {
+
+	ret = drmFenceFlush(fd, fence, fenceType);
+	if (ret)
+	    return ret;
+    }
+
+    *signaled = ((fenceType & fence->signaled) == fenceType);
+
+    return 0;
+}
+
+/*
+ * Valid flags are 
+ * DRM_FENCE_FLAG_SHAREABLE
+ * DRM_FENCE_MASK_DRIVER
+ */
+
+
+int drmFenceEmit(int fd, unsigned flags, drmFence *fence, unsigned emit_type)
+{
+    drm_fence_arg_t arg;
+   
+    memset(&arg, 0, sizeof(arg));
+    arg.flags = flags;
+    arg.handle = fence->handle;
+    arg.type = emit_type;
+    arg.op = drm_fence_emit;
+    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+	return -errno;
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->signaled = arg.signaled;
+    return 0;
+}
+
+/*
+ * Valid flags are 
+ * DRM_FENCE_FLAG_WAIT_LAZY
+ * DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS
+ */
+    
+int drmFenceWait(int fd, unsigned flags, drmFence *fence, unsigned flush_type)
+{
+    drm_fence_arg_t arg;
+    int ret;
+
+    if (flush_type == 0) {
+	flush_type = fence->type;
+    }
+
+    if (!(fence->flags & DRM_FENCE_FLAG_SHAREABLE)) {
+	if ((flush_type & fence->signaled) == flush_type) {
+	    return 0;
+	}
+    }
+
+    memset(&arg, 0, sizeof(arg));
+    arg.handle = fence->handle;
+    arg.type = flush_type;
+    arg.flags = flags;
+    arg.op = drm_fence_wait;
+    do {
+	ret = ioctl(fd, DRM_IOCTL_FENCE, &arg);
+    } while (ret != 0 && errno == EAGAIN);
+
+    if (ret)
+	return -errno;
+
+    fence->class = arg.class;
+    fence->type = arg.type;
+    fence->signaled = arg.signaled;
+    return 0;
+}    
+
+static int drmAdjustListNodes(drmBOList *list)
+{
+    drmBONode *node;
+    drmMMListHead *l;
+    int ret = 0;
+
+    while(list->numCurrent < list->numTarget) {
+	node = (drmBONode *) malloc(sizeof(*node));
+	if (!node) {
+	    ret = -ENOMEM;
+	    break;
+	}
+	list->numCurrent++;
+	DRMLISTADD(&node->head, &list->free);
+    }
+
+    while(list->numCurrent > list->numTarget) {
+	l = list->free.next;
+	if (l == &list->free)
+	    break;
+	DRMLISTDEL(l);
+	node = DRMLISTENTRY(drmBONode, l, head);
+	free(node);
+	list->numCurrent--;
+    }
+    return ret;
+}
+
+void drmBOFreeList(drmBOList *list)
+{
+    drmBONode *node;
+    drmMMListHead *l;
+
+    l = list->list.next;
+    while(l != &list->list) {
+	DRMLISTDEL(l);
+	node = DRMLISTENTRY(drmBONode, l, head);
+	free(node);
+	l = list->free.next;
+	list->numCurrent--;
+	list->numOnList--;
+    }
+
+    l = list->free.next;
+    while(l != &list->free) {
+	DRMLISTDEL(l);
+	node = DRMLISTENTRY(drmBONode, l, head);
+	free(node);
+	l = list->free.next;
+	list->numCurrent--;
+    }
+}
+	
+int drmBOResetList(drmBOList *list) {
+
+    drmMMListHead *l;
+    int ret;
+
+    ret = drmAdjustListNodes(list);
+    if (ret)
+	return ret;
+
+    l = list->list.next;
+    while(l != &list->list) {
+	DRMLISTDEL(l);
+	DRMLISTADD(l, &list->free);
+	list->numOnList--;
+	l = list->list.next;
+    }
+    return drmAdjustListNodes(list);
+}
+	
+static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, 
+				 unsigned long arg0,
+				 unsigned long arg1)
+{
+    drmBONode *node;
+    drmMMListHead *l;
+
+    l = list->free.next;
+    if (l == &list->free) {
+	node = (drmBONode *) malloc(sizeof(*node));
+	if (!node) {
+	    return NULL;
+	}
+	list->numCurrent++;
+    } else {
+	DRMLISTDEL(l);
+	node = DRMLISTENTRY(drmBONode, l, head);
+    }
+    node->buf = item;
+    node->arg0 = arg0;
+    node->arg1 = arg1;
+    DRMLISTADD(&node->head, &list->list);
+    list->numOnList++;
+    return node;
+}
+     	
+void *drmBOListIterator(drmBOList *list)
+{
+    void *ret = list->list.next;
+
+    if (ret == &list->list)
+	return NULL;
+    return ret;
+}
+
+void *drmBOListNext(drmBOList *list, void *iterator)
+{
+    void *ret;
+
+    drmMMListHead *l = (drmMMListHead *) iterator;
+    ret = l->next;
+    if (ret == &list->list)
+	return NULL;
+    return ret;
+}
+
+drmBO *drmBOListBuf(void *iterator)
+{
+    drmBONode *node;
+    drmMMListHead *l = (drmMMListHead *) iterator;
+    node = DRMLISTENTRY(drmBONode, l, head);
+    
+    return node->buf;
+}
+
+
+int drmBOCreateList(int numTarget, drmBOList *list)
+{
+    DRMINITLISTHEAD(&list->list);
+    DRMINITLISTHEAD(&list->free);
+    list->numTarget = numTarget;
+    list->numCurrent = 0;
+    list->numOnList = 0;
+    return drmAdjustListNodes(list);
+}
+
+static void drmBOCopyReply(const drm_bo_arg_reply_t *rep, 
+			   drmBO *buf)
+{
+    buf->handle = rep->handle;
+    buf->flags = rep->flags;
+    buf->size = rep->size;
+    buf->offset = rep->offset;
+    buf->mapHandle = rep->arg_handle;
+    buf->mask = rep->mask;
+    buf->start = rep->buffer_start;
+    buf->fenceFlags = rep->fence_flags;
+    buf->replyFlags = rep->rep_flags;
+    buf->pageAlignment = rep->page_alignment;
+}
+    
+    
+
+int drmBOCreate(int fd, unsigned long start, unsigned long size, 
+		unsigned pageAlignment, void *user_buffer, drm_bo_type_t type, 
+		unsigned mask,
+		unsigned hint, drmBO *buf)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    int ret;
+
+    memset(buf, 0, sizeof(*buf));
+    memset(&arg, 0, sizeof(arg));
+    req->mask = mask;
+    req->hint = hint;
+    req->size = size;
+    req->type = type;
+    req->page_alignment = pageAlignment;
+
+    buf->virtual = NULL;
+
+    switch(type) {
+    case drm_bo_type_dc:
+        req->buffer_start = start;
+	break;
+    case drm_bo_type_user:
+	req->buffer_start = (unsigned long) user_buffer;
+	buf->virtual = user_buffer;
+	break;
+    case drm_bo_type_fake:
+        req->buffer_start = start;
+	break;
+    default:
+	return -EINVAL;
+    }
+    req->op = drm_bo_create;
+
+    do {
+	ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+    } while (ret != 0 && errno == EAGAIN);
+
+    if (ret)
+	return -errno;
+    if (!arg.handled) {
+	return -EFAULT;
+    }
+    if (rep->ret) {
+        fprintf(stderr, "Error %d\n", rep->ret);
+	return rep->ret;
+    }
+    
+    drmBOCopyReply(rep, buf);
+    buf->mapVirtual = NULL;
+    buf->mapCount = 0;
+
+    return 0;
+}
+
+int drmBODestroy(int fd, drmBO *buf)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    
+    if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
+	(void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
+	buf->mapVirtual = NULL;
+	buf->virtual = NULL;
+    }
+
+    memset(&arg, 0, sizeof(arg));
+    req->handle = buf->handle;
+    req->op = drm_bo_destroy;
+
+    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+	return -errno;
+    if (!arg.handled) {
+	return -EFAULT;
+    }
+    if (rep->ret) {
+	return rep->ret;
+    }
+
+    buf->handle = 0;
+    return 0;
+}
+ 
+int drmBOReference(int fd, unsigned handle, drmBO *buf)
+{
+
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    
+    memset(&arg, 0, sizeof(arg));
+    req->handle = handle;
+    req->op = drm_bo_reference;
+    
+    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+	return -errno;
+    if (!arg.handled) {
+	return -EFAULT;
+    }
+    if (rep->ret) {
+	return rep->ret;
+    }
+
+    drmBOCopyReply(rep, buf);
+    buf->type = drm_bo_type_dc;
+    buf->mapVirtual = NULL;
+    buf->mapCount = 0;
+    buf->virtual = NULL;
+
+    return 0;
+}
+
+int drmBOUnReference(int fd, drmBO *buf)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    
+
+    if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
+	(void) munmap(buf->mapVirtual, buf->start + buf->size);
+	buf->mapVirtual = NULL;
+	buf->virtual = NULL;
+    }
+
+    memset(&arg, 0, sizeof(arg));
+    req->handle = buf->handle;
+    req->op = drm_bo_unreference;
+
+    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+	return -errno;
+    if (!arg.handled) {
+	return -EFAULT;
+    }
+    if (rep->ret) {
+	return rep->ret;
+    }
+
+    buf->handle = 0;
+    return 0;
+}   
+
+/*
+ * Flags can be  DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE or'ed together
+ * Hint currently be DRM_BO_HINT_DONT_BLOCK, which makes the
+ * call return an -EBUSY if it can' immediately honor the mapping request.
+ */
+
+int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
+	     void **address)
+{
+
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    int ret = 0;
+
+    /*
+     * Make sure we have a virtual address of the buffer.
+     */
+
+    if (!buf->virtual && buf->type != drm_bo_type_fake) {
+	drmAddress virtual;
+	virtual = mmap(0, buf->size + buf->start, 
+		       PROT_READ | PROT_WRITE, MAP_SHARED,
+		       fd, buf->mapHandle);
+	if (virtual == MAP_FAILED) {
+	    ret = -errno;
+	}
+	if (ret) 
+	    return ret;
+	buf->mapVirtual = virtual;
+	buf->virtual = ((char *) virtual) + buf->start;
+    }
+
+    memset(&arg, 0, sizeof(arg));
+    req->handle = buf->handle;
+    req->mask = mapFlags;
+    req->hint = mapHint;
+    req->op = drm_bo_map;
+
+    /*
+     * May hang if the buffer object is busy.
+     * This IOCTL synchronizes the buffer.
+     */
+    
+    do {
+	ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+    } while (ret != 0 && errno == EAGAIN);
+
+    if (ret) 
+	return ret;
+    if (!arg.handled) 
+	return -EFAULT;
+    if (rep->ret)
+	return rep->ret;
+
+    drmBOCopyReply(rep, buf);	
+    buf->mapFlags = mapFlags;
+    ++buf->mapCount;
+    *address = buf->virtual;
+
+    return 0;
+}
+
+int drmBOUnmap(int fd, drmBO *buf)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+
+	
+    memset(&arg, 0, sizeof(arg));
+    req->handle = buf->handle;
+    req->op = drm_bo_unmap;
+
+    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
+	return -errno;
+    }
+    if (!arg.handled) 
+        return -EFAULT;
+    if (rep->ret)
+	return rep->ret;
+
+    return 0;
+}
+    
+int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, 
+		  unsigned hint)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    int ret = 0;
+
+    memset(&arg, 0, sizeof(arg));
+    req->handle = buf->handle;
+    req->mask = flags;
+    req->hint = hint;
+    req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
+    req->op = drm_bo_validate;
+
+    do{
+	ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+    } while (ret && errno == EAGAIN);
+    
+    if (ret) 
+	return ret;
+    if (!arg.handled)
+	return -EFAULT;
+    if (rep->ret)
+	return rep->ret;
+
+    drmBOCopyReply(rep, buf);
+    return 0;
+}
+	    
+
+int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    int ret = 0;
+
+    memset(&arg, 0, sizeof(arg));
+    req->handle = buf->handle;
+    req->mask = flags;
+    req->arg_handle = fenceHandle;
+    req->op = drm_bo_validate;
+
+    ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+    
+    if (ret) 
+	return ret;
+    if (!arg.handled)
+	return -EFAULT;
+    if (rep->ret)
+	return rep->ret;
+    return 0;
+}
+
+int drmBOInfo(int fd, drmBO *buf)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    int ret = 0;
+
+    memset(&arg, 0, sizeof(arg));
+    req->handle = buf->handle;
+    req->op = drm_bo_info;
+
+    ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+    
+    if (ret) 
+	return ret;
+    if (!arg.handled)
+	return -EFAULT;
+    if (rep->ret)
+	return rep->ret;
+    drmBOCopyReply(rep, buf);
+    return 0;
+}
+
+int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint)
+{
+    drm_bo_arg_t arg;
+    drm_bo_arg_request_t *req = &arg.d.req;
+    drm_bo_arg_reply_t *rep = &arg.d.rep;
+    int ret = 0;
+
+    if ((buf->flags & DRM_BO_FLAG_SHAREABLE) ||
+	(buf->replyFlags & DRM_BO_REP_BUSY)) {
+        memset(&arg, 0, sizeof(arg));
+	req->handle = buf->handle;
+	req->op = drm_bo_wait_idle;
+	req->hint = hint;
+
+	do {
+	    ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+	} while (ret && errno == EAGAIN);
+
+	if (ret) 
+	    return ret;
+	if (!arg.handled)
+	    return -EFAULT;
+	if (rep->ret)
+	    return rep->ret;
+	drmBOCopyReply(rep, buf);
+    }
+    return 0;
+}
+	
+int drmBOBusy(int fd, drmBO *buf, int *busy)
+{
+    if (!(buf->flags & DRM_BO_FLAG_SHAREABLE) &&
+	!(buf->replyFlags & DRM_BO_REP_BUSY)) {
+	*busy = 0;
+	return 0;
+    } else {
+	int ret = drmBOInfo(fd, buf);
+	if (ret)
+	    return ret;
+	*busy = (buf->replyFlags & DRM_BO_REP_BUSY);
+	return 0;
+    }
+}
+    
+    
+int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, 
+		       unsigned mask,
+		       int *newItem)
+{
+    drmBONode *node, *cur;
+    drmMMListHead *l;
+
+    *newItem = 0;
+    cur = NULL;
+
+    for (l = list->list.next; l != &list->list; l = l->next) {
+	node = DRMLISTENTRY(drmBONode, l, head);
+	if (node->buf == buf) {
+	    cur = node;
+	    break;
+	}
+    }
+    if (!cur) {
+	cur = drmAddListItem(list, buf, flags, mask);
+	if (!cur) {
+	    drmMsg("Out of memory creating validate list node.\n");
+	    return -ENOMEM;
+	}
+	*newItem = 1;
+	cur->arg0 = flags;
+	cur->arg1 = mask;
+    } else {
+	unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
+	unsigned memFlags = cur->arg0 & flags & memMask;
+	
+	if (!memFlags) {
+	    drmMsg("Incompatible memory location requests "
+		   "on validate list.\n");
+	    drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
+		   cur->arg0, cur->arg1);
+	    drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
+		   flags, mask);
+	    return -EINVAL;
+	}
+	if (mask & cur->arg1 & ~DRM_BO_MASK_MEM  & (cur->arg0 ^ flags)) {
+	    drmMsg("Incompatible buffer flag requests "
+		   "on validate list.\n");
+	    drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
+		   cur->arg0, cur->arg1);
+	    drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
+		   flags, mask);
+	    return -EINVAL;
+	}
+	cur->arg1 |= mask;
+	cur->arg0 = memFlags | ((cur->arg0 | flags) & 
+				cur->arg1 & ~DRM_BO_MASK_MEM);	
+    }
+    return 0;
+}
+
+
+int drmBOValidateList(int fd, drmBOList *list)
+{
+   
+  drmBONode *node;
+  drmMMListHead *l;
+  drm_bo_arg_t *arg, *first;
+  drm_bo_arg_request_t *req;
+  drm_bo_arg_reply_t *rep;
+  drm_u64_t *prevNext = NULL;
+  drmBO *buf;
+  int ret;
+
+  first = NULL;
+
+  for (l = list->list.next; l != &list->list; l = l->next) {
+      node = DRMLISTENTRY(drmBONode, l, head);
+
+      arg = &node->bo_arg;
+      req = &arg->d.req;
+
+      if (!first)
+	  first = arg;
+
+      if (prevNext)
+	  *prevNext = (unsigned long) arg;
+
+      memset(arg, 0, sizeof(*arg));
+      prevNext = &arg->next;
+      req->handle = node->buf->handle;
+      req->op = drm_bo_validate;
+      req->mask = node->arg0;
+      req->hint = 0;
+      req->arg_handle = node->arg1;
+  }
+  
+  if (!first) 
+      return 0;
+
+  do{
+      ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
+  } while (ret && errno == EAGAIN);
+
+
+  if (ret)
+      return -errno;
+  
+  for (l = list->list.next; l != &list->list; l = l->next) {
+      node = DRMLISTENTRY(drmBONode, l, head);
+      arg = &node->bo_arg;
+      rep = &arg->d.rep;
+      
+      if (!arg->handled) {
+	  drmMsg("Unhandled request\n");
+	  return -EFAULT;
+      }
+      if (rep->ret)
+	  return rep->ret;
+
+      buf = node->buf;
+      drmBOCopyReply(rep, buf);
+  }
+
+  return 0;
+}
+	  
+
+int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
+{
+   
+  drmBONode *node;
+  drmMMListHead *l;
+  drm_bo_arg_t *arg, *first;
+  drm_bo_arg_request_t *req;
+  drm_bo_arg_reply_t *rep;
+  drm_u64_t *prevNext = NULL;
+  int ret;
+
+  first = NULL;
+
+  for (l = list->list.next; l != &list->list; l = l->next) {
+      node = DRMLISTENTRY(drmBONode, l, head);
+
+      arg = &node->bo_arg;
+      req = &arg->d.req;
+
+      if (!first)
+	  first = arg;
+
+      if (prevNext)
+	  *prevNext = (unsigned long) arg;
+
+      memset(arg, 0, sizeof(*arg));
+      prevNext = &arg->next;
+      req->handle = node->buf->handle;
+      req->op = drm_bo_fence;
+      req->mask = node->arg0;
+      req->arg_handle = fenceHandle;
+  }
+  
+  if (!first) 
+      return 0;
+
+  ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
+
+  if (ret)
+      return -errno;
+  
+  for (l = list->list.next; l != &list->list; l = l->next) {
+      node = DRMLISTENTRY(drmBONode, l, head);
+
+      arg = &node->bo_arg;
+      rep = &arg->d.rep;
+      
+      if (!arg->handled)
+	  return -EFAULT;
+      if (rep->ret)
+	  return rep->ret;
+      drmBOCopyReply(rep, node->buf);
+  }
+
+  return 0;
+}
+
+int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
+	      unsigned memType)
+{
+    drm_mm_init_arg_t arg;
+    
+    memset(&arg, 0, sizeof(arg));
+    arg.req.op = mm_init;
+    arg.req.p_offset = pOffset;
+    arg.req.p_size = pSize;
+    arg.req.mem_type = memType;
+
+    if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
+	return -errno;
+    
+    return 0;	
+}
+
+int drmMMTakedown(int fd, unsigned memType)
+{
+    drm_mm_init_arg_t arg;
+
+
+    memset(&arg, 0, sizeof(arg));
+    arg.req.op = mm_takedown;
+    arg.req.mem_type = memType;
+
+    if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
+	return -errno;
+    
+    return 0;	
+}
+
+int drmMMLock(int fd, unsigned memType)
+{
+    drm_mm_init_arg_t arg;
+    int ret;
+
+    memset(&arg, 0, sizeof(arg));
+    arg.req.op = mm_lock;
+    arg.req.mem_type = memType;
+
+    do{
+	ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
+    } while (ret && errno == EAGAIN);
+    
+    return ret;	
+}
+
+int drmMMUnlock(int fd, unsigned memType)
+{
+    drm_mm_init_arg_t arg;
+    int ret;
+
+    memset(&arg, 0, sizeof(arg));
+    arg.req.op = mm_unlock;
+    arg.req.mem_type = memType;
+
+    do{
+	ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
+    } while (ret && errno == EAGAIN);
+    
+    return ret;	
+}
diff --git a/hw/xfree86/os-support/xf86drm.h b/hw/xfree86/os-support/xf86drm.h
index 1076706..18e4564 100644
--- a/hw/xfree86/os-support/xf86drm.h
+++ b/hw/xfree86/os-support/xf86drm.h
@@ -36,6 +36,7 @@
 #define _XF86DRM_H_
 
 #include <drm.h>
+#include <xf86mm.h>
 
 				/* Defaults, if nothing set in xf86config */
 #define DRM_DEV_UID	 0
diff --git a/hw/xfree86/os-support/xf86mm.h b/hw/xfree86/os-support/xf86mm.h
new file mode 100644
index 0000000..e1a4e3e
--- /dev/null
+++ b/hw/xfree86/os-support/xf86mm.h
@@ -0,0 +1,210 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * 
+ **************************************************************************/
+
+#ifndef _XF86MM_H_
+#define _XF86MM_H_
+#include <stddef.h>
+#include "drm.h"
+
+/*
+ * Note on multithreaded applications using this interface.
+ * Libdrm is not threadsafe, so common buffer, TTM, and fence objects need to
+ * be protected using an external mutex.
+ *
+ * Note: Don't protect the following functions, as it may lead to deadlocks:
+ * drmBOUnmap(), drmFenceBuffers().
+ * The kernel is synchronizing and refcounting buffer maps. 
+ * User space only needs to refcount object usage within the same application.
+ */
+
+
+/*
+ * List macros heavily inspired by the Linux kernel
+ * list handling. No list looping yet.
+ */
+
+typedef struct _drmMMListHead
+{
+    struct _drmMMListHead *prev;
+    struct _drmMMListHead *next;
+} drmMMListHead;
+
+#define DRMINITLISTHEAD(__item)		       \
+  do{					       \
+    (__item)->prev = (__item);		       \
+    (__item)->next = (__item);		       \
+  } while (0)
+
+#define DRMLISTADD(__item, __list)			\
+  do {						\
+    (__item)->prev = (__list);			\
+    (__item)->next = (__list)->next;		\
+    (__list)->next->prev = (__item);		\
+    (__list)->next = (__item);			\
+  } while (0)
+
+#define DRMLISTADDTAIL(__item, __list)		\
+  do {						\
+    (__item)->next = (__list);			\
+    (__item)->prev = (__list)->prev;		\
+    (__list)->prev->next = (__item);		\
+    (__list)->prev = (__item);			\
+  } while(0)
+
+#define DRMLISTDEL(__item)			\
+  do {						\
+    (__item)->prev->next = (__item)->next;	\
+    (__item)->next->prev = (__item)->prev;	\
+  } while(0)
+
+#define DRMLISTDELINIT(__item)			\
+  do {						\
+    (__item)->prev->next = (__item)->next;	\
+    (__item)->next->prev = (__item)->prev;	\
+    (__item)->next = (__item);			\
+    (__item)->prev = (__item);			\
+  } while(0)
+
+#define DRMLISTENTRY(__type, __item, __field)   \
+    ((__type *)(((char *) (__item)) - offsetof(__type, __field)))
+
+typedef struct _drmFence{
+        unsigned handle;
+        int class;
+        unsigned type; 
+        unsigned flags;
+        unsigned signaled;
+        unsigned pad[4]; /* for future expansion */
+} drmFence;
+
+typedef struct _drmBO{
+    drm_bo_type_t type;
+    unsigned handle;
+    drm_u64_t mapHandle;
+    unsigned flags;
+    unsigned mask;
+    unsigned mapFlags;
+    unsigned long size;
+    unsigned long offset;
+    unsigned long start;
+    unsigned replyFlags;
+    unsigned fenceFlags;
+    unsigned pageAlignment;
+    void *virtual;
+    void *mapVirtual;
+    int mapCount;
+    unsigned pad[8];     /* for future expansion */
+} drmBO;
+
+
+typedef struct _drmBONode {
+    drmMMListHead head;
+    drmBO *buf;
+    drm_bo_arg_t bo_arg;
+    unsigned long arg0;
+    unsigned long arg1;
+} drmBONode;
+
+typedef struct _drmBOList {
+    unsigned numTarget;
+    unsigned numCurrent;
+    unsigned numOnList;
+    drmMMListHead list;
+    drmMMListHead free;
+} drmBOList;
+
+/* Fencing */
+
+extern int drmFenceCreate(int fd, unsigned flags, int class,
+			  unsigned type, 
+			  drmFence *fence);
+extern int drmFenceDestroy(int fd, const drmFence *fence);
+extern int drmFenceReference(int fd, unsigned handle, drmFence *fence);
+extern int drmFenceUnreference(int fd, const drmFence *fence);
+extern int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
+extern int drmFenceSignaled(int fd, drmFence *fence, 
+			    unsigned fenceType, int *signaled);
+extern int drmFenceWait(int fd, unsigned flags, drmFence *fence, 
+			unsigned flush_type);
+extern int drmFenceEmit(int fd, unsigned flags, drmFence *fence, 
+			unsigned emit_type);
+extern int drmFenceBuffers(int fd, unsigned flags, drmFence *fence);
+extern int drmFenceUpdate(int fd, drmFence *fence);
+
+
+/*
+ * Buffer object list functions.
+ */
+
+extern void drmBOFreeList(drmBOList *list);
+extern int drmBOResetList(drmBOList *list);
+extern void *drmBOListIterator(drmBOList *list);
+extern void *drmBOListNext(drmBOList *list, void *iterator);
+extern drmBO *drmBOListBuf(void *iterator);
+extern int drmBOCreateList(int numTarget, drmBOList *list);
+
+/*
+ * Buffer object functions.
+ */
+
+extern int drmBOCreate(int fd, unsigned long start, unsigned long size,
+		       unsigned pageAlignment,void *user_buffer, 
+		       drm_bo_type_t type, unsigned mask,
+		       unsigned hint, drmBO *buf);
+extern int drmBODestroy(int fd, drmBO *buf);
+extern int drmBOReference(int fd, unsigned handle, drmBO *buf);
+extern int drmBOUnReference(int fd, drmBO *buf);
+extern int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
+		    void **address);
+extern int drmBOUnmap(int fd, drmBO *buf);
+extern int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, 
+			 unsigned hint);
+extern int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle);
+extern int drmBOInfo(int fd, drmBO *buf);
+extern int drmBOBusy(int fd, drmBO *buf, int *busy);
+
+
+extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, 
+		       unsigned mask,
+		       int *newItem);
+extern int drmBOValidateList(int fd, drmBOList *list);
+extern int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle);
+extern int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint);
+
+/*
+ * Initialization functions.
+ */
+
+extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
+		     unsigned memType);
+extern int drmMMTakedown(int fd, unsigned memType);
+extern int drmMMLock(int fd, unsigned memType);
+extern int drmMMUnlock(int fd, unsigned memType);
+
+
+#endif



More information about the xorg-commit mailing list