Blame SOURCES/0011-Add-xwayland-module.patch

70130e
From 0831ea9c83af12f497093e2566d94f75c3ba202f Mon Sep 17 00:00:00 2001
70130e
From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= <krh@redhat.com>
70130e
Date: Fri, 18 Sep 2009 22:08:16 -0400
70130e
Subject: [PATCH 11/39] Add xwayland module
70130e
MIME-Version: 1.0
70130e
Content-Type: text/plain; charset=UTF-8
70130e
Content-Transfer-Encoding: 8bit
70130e
70130e
Squashed and rebased from the xwayland-1.12 branch.  Contributions from
70130e
70130e
  Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
70130e
  Corentin Chary <corentin.chary@gmail.com>
70130e
  Daniel Stone <daniel@fooishbar.org>
70130e
  Kristian Høgsberg <krh@bitplanet.net>
70130e
  Robert Bragg <robert@linux.intel.com>
70130e
  Scott Moreau <oreaus@gmail.com>
70130e
  Tiago Vignatti <tiago.vignatti@intel.com>
70130e
---
70130e
 configure.ac                           |  15 +
70130e
 hw/xfree86/Makefile.am                 |   8 +-
70130e
 hw/xfree86/common/xf86Config.c         |  28 +-
70130e
 hw/xfree86/common/xf86Globals.c        |   2 +
70130e
 hw/xfree86/common/xf86Init.c           |  20 ++
70130e
 hw/xfree86/common/xf86Priv.h           |   2 +
70130e
 hw/xfree86/dri2/dri2.c                 |   7 +-
70130e
 hw/xfree86/dri2/dri2.h                 |   2 +-
70130e
 hw/xfree86/xwayland/Makefile.am        |  44 +++
70130e
 hw/xfree86/xwayland/drm.xml            | 139 ++++++++
70130e
 hw/xfree86/xwayland/xserver.xml        |  18 +
70130e
 hw/xfree86/xwayland/xwayland-cursor.c  | 241 +++++++++++++
70130e
 hw/xfree86/xwayland/xwayland-drm.c     | 235 +++++++++++++
70130e
 hw/xfree86/xwayland/xwayland-input.c   | 610 +++++++++++++++++++++++++++++++++
70130e
 hw/xfree86/xwayland/xwayland-output.c  | 309 +++++++++++++++++
70130e
 hw/xfree86/xwayland/xwayland-private.h | 132 +++++++
70130e
 hw/xfree86/xwayland/xwayland-window.c  | 316 +++++++++++++++++
70130e
 hw/xfree86/xwayland/xwayland.c         | 392 +++++++++++++++++++++
70130e
 hw/xfree86/xwayland/xwayland.h         |  83 +++++
70130e
 include/xorg-server.h.in               |   3 +
70130e
 20 files changed, 2597 insertions(+), 9 deletions(-)
70130e
 create mode 100644 hw/xfree86/xwayland/Makefile.am
70130e
 create mode 100644 hw/xfree86/xwayland/drm.xml
70130e
 create mode 100644 hw/xfree86/xwayland/xserver.xml
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland-cursor.c
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland-drm.c
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland-input.c
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland-output.c
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland-private.h
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland-window.c
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland.c
70130e
 create mode 100644 hw/xfree86/xwayland/xwayland.h
70130e
70130e
diff --git a/configure.ac b/configure.ac
70130e
index 9fb014f..c146b7b 100644
70130e
--- a/configure.ac
70130e
+++ b/configure.ac
70130e
@@ -635,6 +635,7 @@ AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg
70130e
 AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])
70130e
 AC_ARG_ENABLE(linux_acpi, AC_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])
70130e
 AC_ARG_ENABLE(linux_apm, AC_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])
70130e
+AC_ARG_ENABLE(wayland,      AS_HELP_STRING([--disable-wayland], [Build Wayland extension (default: enabled)]), [WAYLAND=$enableval], [WAYLAND=yes])
70130e
 
70130e
 dnl DDXes.
70130e
 AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
70130e
@@ -1023,6 +1024,14 @@ fi
70130e
 if test "x$MITSHM" = xauto; then
70130e
 	MITSHM="$ac_cv_sysv_ipc"
70130e
 fi
70130e
+
70130e
+AM_CONDITIONAL(WAYLAND, [test "x$WAYLAND" = xyes])
70130e
+if test "x$WAYLAND" = xyes; then
70130e
+	AC_DEFINE(XORG_WAYLAND, 1, [Support wayland mode])
70130e
+	REQUIRED_MODULES="$REQUIRED_MODULES wayland-client"
70130e
+	WAYLAND_SCANNER_RULES(['$(top_srcdir)/hw/xfree86/xwayland'])
70130e
+fi
70130e
+
70130e
 AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes])
70130e
 if test "x$MITSHM" = xyes; then
70130e
 	AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension])
70130e
@@ -1118,6 +1127,7 @@ case "$DRI2,$HAVE_DRI2PROTO" in
70130e
 esac
70130e
 AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
70130e
 
70130e
+<<<<<<< HEAD
70130e
 PKG_CHECK_MODULES([DRI3PROTO], $DRI3PROTO,
70130e
                   [HAVE_DRI3PROTO=yes], [HAVE_DRI3PROTO=no])
70130e
 
70130e
@@ -1177,11 +1187,15 @@ esac
70130e
 AM_CONDITIONAL(DRI3, test "x$DRI3" = xyes)
70130e
 
70130e
 if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$DRI3" = xyes || test "x$CONFIG_UDEV_KMS" = xyes; then
70130e
+=======
70130e
+if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$CONFIG_UDEV_KMS" = xyes || test "x$WAYLAND" = xyes ; then
70130e
+>>>>>>> Add xwayland module
70130e
 	if test "x$DRM" = xyes; then
70130e
 		AC_DEFINE(WITH_LIBDRM, 1, [Building with libdrm support])
70130e
 		PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
70130e
 	fi
70130e
 fi
70130e
+AM_CONDITIONAL(DRM, test "x$DRM" = xyes)
70130e
 
70130e
 if test "x$DRI2" = xyes; then
70130e
 	save_CFLAGS=$CFLAGS
70130e
@@ -2352,6 +2366,7 @@ hw/xfree86/dixmods/Makefile
70130e
 hw/xfree86/doc/Makefile
70130e
 hw/xfree86/dri/Makefile
70130e
 hw/xfree86/dri2/Makefile
70130e
+hw/xfree86/xwayland/Makefile
70130e
 hw/xfree86/exa/Makefile
70130e
 hw/xfree86/exa/man/Makefile
70130e
 hw/xfree86/fbdevhw/Makefile
70130e
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
70130e
index 485386f..ff04b25 100644
70130e
--- a/hw/xfree86/Makefile.am
70130e
+++ b/hw/xfree86/Makefile.am
70130e
@@ -14,6 +14,10 @@ DRI3_BUILDDIR = $(top_builddir)/dri3
70130e
 DRI3_LIB = $(DRI3_BUILDDIR)/libdri3.la
70130e
 endif
70130e
 
70130e
+if WAYLAND
70130e
+WAYLAND_SUBDIR = xwayland
70130e
+endif
70130e
+
70130e
 if XF86UTILS
70130e
 XF86UTILS_SUBDIR = utils
70130e
 endif
70130e
@@ -32,12 +36,12 @@ endif
70130e
 
70130e
 SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \
70130e
 	  ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \
70130e
-	  $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
70130e
+	  $(DRI2_SUBDIR)  $(WAYLAND_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
70130e
 	  fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man
70130e
 
70130e
 DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
70130e
                parser ramdac shadowfb vbe vgahw \
70130e
-               loader dixmods dri dri2 exa modes \
70130e
+               loader dixmods dri dri2 exa modes xwayland \
70130e
 	       utils doc man
70130e
 
70130e
 bin_PROGRAMS = Xorg
70130e
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
70130e
index 74d5ed3..39cd58c 100644
70130e
--- a/hw/xfree86/common/xf86Config.c
70130e
+++ b/hw/xfree86/common/xf86Config.c
70130e
@@ -118,7 +118,8 @@ static ModuleDefault ModuleDefaults[] = {
70130e
     {.name = "fb",.toLoad = TRUE,.load_opt = NULL},
70130e
     {.name = "shadow",.toLoad = TRUE,.load_opt = NULL},
70130e
 #endif
70130e
-    {.name = NULL,.toLoad = FALSE,.load_opt = NULL}
70130e
+    {.name = "xwayland",.toLoad = FALSE,.load_opt=NULL},
70130e
+    {.name = NULL,.toLoad = FALSE,.load_opt=NULL}
70130e
 };
70130e
 
70130e
 /* Forward declarations */
70130e
@@ -260,6 +261,17 @@ xf86ModulelistFromConfig(pointer **optlist)
70130e
         return NULL;
70130e
     }
70130e
 
70130e
+    /*
70130e
+     * Set the xwayland module to autoload if requested.
70130e
+     */
70130e
+    if (xorgWayland) {
70130e
+        for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
70130e
+            if (strcmp(ModuleDefaults[i].name, "xwayland") == 0) {
70130e
+                ModuleDefaults[i].toLoad = TRUE;
70130e
+            }
70130e
+        }
70130e
+    }
70130e
+
70130e
     if (xf86configptr->conf_modules) {
70130e
         /* Walk the disable list and let people know what we've parsed to
70130e
          * not be loaded 
70130e
@@ -863,6 +875,13 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
70130e
     }
70130e
     xf86Msg(from, "%sutomatically adding GPU devices\n",
70130e
             xf86Info.autoAddGPU ? "A" : "Not a");
70130e
+
70130e
+    /* FIXME: Do that at the right place (before xf86Msg). */
70130e
+    if (xorgWayland) {
70130e
+            xf86Info.autoAddDevices = FALSE;
70130e
+            xf86Info.autoEnableDevices = FALSE;
70130e
+    }
70130e
+
70130e
     /*
70130e
      * Set things up based on the config file information.  Some of these
70130e
      * settings may be overridden later when the command line options are
70130e
@@ -953,9 +972,10 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
70130e
     }
70130e
 #endif
70130e
 
70130e
-    /* if we're not hotplugging, force some input devices to exist */
70130e
-    xf86Info.forceInputDevices = !(xf86Info.autoAddDevices &&
70130e
-                                   xf86Info.autoEnableDevices);
70130e
+    if (xorgWayland) /* Don't force input devices */
70130e
+	xf86Info.forceInputDevices = FALSE;
70130e
+    else /* if we're not hotplugging, force some input devices to exist */
70130e
+	xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
70130e
 
70130e
     /* when forcing input devices, we use kbd. otherwise evdev, so use the
70130e
      * evdev rules set. */
70130e
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
70130e
index 7df7a80..b41d2cc 100644
70130e
--- a/hw/xfree86/common/xf86Globals.c
70130e
+++ b/hw/xfree86/common/xf86Globals.c
70130e
@@ -204,3 +204,5 @@ Bool xf86VidModeAllowNonLocal = FALSE;
70130e
 #endif
70130e
 RootWinPropPtr *xf86RegisteredPropertiesTable = NULL;
70130e
 Bool xorgHWAccess = FALSE;
70130e
+Bool xorgWayland = FALSE;
70130e
+Bool xorgRootless = FALSE;
70130e
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
70130e
index 91ec4c8..98adaab 100644
70130e
--- a/hw/xfree86/common/xf86Init.c
70130e
+++ b/hw/xfree86/common/xf86Init.c
70130e
@@ -546,6 +546,13 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
70130e
 
70130e
             if (!(flags & HW_SKIP_CONSOLE))
70130e
                 xorgHWOpenConsole = TRUE;
70130e
+
70130e
+	    if (xorgWayland &&
70130e
+		(NEED_IO_ENABLED(flags) || !(flags & HW_SKIP_CONSOLE))) {
70130e
+
70130e
+		xf86DeleteDriver(i);
70130e
+		continue;
70130e
+	    }
70130e
         }
70130e
 
70130e
         if (xorgHWOpenConsole)
70130e
@@ -957,6 +964,9 @@ InitInput(int argc, char **argv)
70130e
 
70130e
     mieqInit();
70130e
 
70130e
+    if (xorgWayland)
70130e
+	return;
70130e
+
70130e
     /* Initialize all configured input devices */
70130e
     for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
70130e
         (*pInfo)->options =
70130e
@@ -1455,6 +1465,16 @@ ddxProcessArgument(int argc, char **argv, int i)
70130e
         return 1;
70130e
     }
70130e
 
70130e
+    if (!strcmp(argv[i], "-wayland")) {
70130e
+        xorgWayland = TRUE;
70130e
+        return 1;
70130e
+    }
70130e
+
70130e
+    if (!strcmp(argv[i], "-rootless")) {
70130e
+        xorgRootless = TRUE;
70130e
+        return 1;
70130e
+    }
70130e
+
70130e
     /* OS-specific processing */
70130e
     return xf86ProcessArgument(argc, argv, i);
70130e
 }
70130e
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
70130e
index 58cfe0a..3dd2697 100644
70130e
--- a/hw/xfree86/common/xf86Priv.h
70130e
+++ b/hw/xfree86/common/xf86Priv.h
70130e
@@ -91,6 +91,8 @@ extern _X_EXPORT int xf86NumScreens;
70130e
 extern _X_EXPORT const char *xf86VisualNames[];
70130e
 extern _X_EXPORT int xf86Verbose;       /* verbosity level */
70130e
 extern _X_EXPORT int xf86LogVerbose;    /* log file verbosity level */
70130e
+extern _X_EXPORT Bool xorgWayland;
70130e
+extern _X_EXPORT Bool xorgRootless;
70130e
 
70130e
 extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
70130e
 
70130e
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
70130e
index efdcd66..483d630 100644
70130e
--- a/hw/xfree86/dri2/dri2.c
70130e
+++ b/hw/xfree86/dri2/dri2.c
70130e
@@ -1332,13 +1332,16 @@ DRI2Connect(ClientPtr client, ScreenPtr pScreen,
70130e
 }
70130e
 
70130e
 static int
70130e
-DRI2AuthMagic (ScreenPtr pScreen, uint32_t magic)
70130e
+DRI2AuthMagic (ClientPtr client, ScreenPtr pScreen, uint32_t magic)
70130e
 {
70130e
     DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
70130e
     if (ds == NULL)
70130e
         return -EINVAL;
70130e
 
70130e
-    return (*ds->LegacyAuthMagic) (ds->fd, magic);
70130e
+    if (ds->LegacyAuthMagic2)
70130e
+        return (*ds->LegacyAuthMagic2) (pScreen, magic);
70130e
+    else
70130e
+        return (*ds->LegacyAuthMagic) (ds->fd, magic);
70130e
 }
70130e
 
70130e
 Bool
70130e
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
70130e
index 38b4f58..ed67d01 100644
70130e
--- a/hw/xfree86/dri2/dri2.h
70130e
+++ b/hw/xfree86/dri2/dri2.h
70130e
@@ -207,7 +207,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client,
70130e
 /**
70130e
  * Version of the DRI2InfoRec structure defined in this header
70130e
  */
70130e
-#define DRI2INFOREC_VERSION 9
70130e
+#define DRI2INFOREC_VERSION 10
70130e
 
70130e
 typedef struct {
70130e
     unsigned int version;       /**< Version of this struct */
70130e
diff --git a/hw/xfree86/xwayland/Makefile.am b/hw/xfree86/xwayland/Makefile.am
70130e
new file mode 100644
70130e
index 0000000..b739145
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/Makefile.am
70130e
@@ -0,0 +1,44 @@
70130e
+AM_CPPFLAGS =					\
70130e
+	$(XORG_INCS)				\
70130e
+	-I$(srcdir)/../ddc			\
70130e
+	-I$(srcdir)/../ramdac			\
70130e
+	-I$(srcdir)/../i2c			\
70130e
+	-I$(srcdir)/../parser			\
70130e
+	-I$(srcdir)/../modes
70130e
+
70130e
+libxwayland_la_LTLIBRARIES = libxwayland.la
70130e
+libxwayland_la_CFLAGS = \
70130e
+	-DHAVE_XORG_CONFIG_H \
70130e
+	@DIX_CFLAGS@ @XORG_CFLAGS@ @LIBDRM_CFLAGS@ \
70130e
+	-I$(top_srcdir)/hw/xfree86/common \
70130e
+	-I$(top_srcdir)/hw/xfree86/os-support/bus
70130e
+
70130e
+libxwayland_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ -lwayland-client
70130e
+libxwayland_ladir = $(moduledir)/extensions
70130e
+libxwayland_la_SOURCES =			\
70130e
+	xwayland.c				\
70130e
+	xwayland-input.c			\
70130e
+	xwayland-output.c			\
70130e
+	xwayland-cursor.c			\
70130e
+	xwayland-window.c			\
70130e
+	xwayland-private.h			\
70130e
+	drm-client-protocol.h			\
70130e
+	drm-protocol.c				\
70130e
+	xserver-client-protocol.h		\
70130e
+	xserver-protocol.c
70130e
+
70130e
+if DRM
70130e
+libxwayland_la_SOURCES += xwayland-drm.c
70130e
+endif
70130e
+
70130e
+sdk_HEADERS = xwayland.h
70130e
+
70130e
+BUILT_SOURCES =					\
70130e
+	drm-client-protocol.h			\
70130e
+	drm-protocol.c				\
70130e
+	xserver-client-protocol.h		\
70130e
+	xserver-protocol.c
70130e
+
70130e
+CLEANFILES = $(BUILT_SOURCES)
70130e
+
70130e
+@wayland_scanner_rules@
70130e
diff --git a/hw/xfree86/xwayland/drm.xml b/hw/xfree86/xwayland/drm.xml
70130e
new file mode 100644
70130e
index 0000000..89fd8f0
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/drm.xml
70130e
@@ -0,0 +1,139 @@
70130e
+
70130e
+<protocol name="drm">
70130e
+
70130e
+  <copyright>
70130e
+    Copyright © 2008-2011 Kristian Høgsberg
70130e
+    Copyright © 2010-2011 Intel Corporation
70130e
+
70130e
+    Permission to use, copy, modify, distribute, and sell this
70130e
+    software and its documentation for any purpose is hereby granted
70130e
+    without fee, provided that\n the above copyright notice appear in
70130e
+    all copies and that both that copyright notice and this permission
70130e
+    notice appear in supporting documentation, and that the name of
70130e
+    the copyright holders not be used in advertising or publicity
70130e
+    pertaining to distribution of the software without specific,
70130e
+    written prior permission.  The copyright holders make no
70130e
+    representations about the suitability of this software for any
70130e
+    purpose.  It is provided "as is" without express or implied
70130e
+    warranty.
70130e
+
70130e
+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
70130e
+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
70130e
+    THIS SOFTWARE.
70130e
+  </copyright>
70130e
+
70130e
+  
70130e
+       using the display's global event. -->
70130e
+  <interface name="wl_drm" version="1">
70130e
+    <enum name="error">
70130e
+      <entry name="authenticate_fail" value="0"/>
70130e
+      <entry name="invalid_format" value="1"/>
70130e
+      <entry name="invalid_name" value="2"/>
70130e
+    </enum>
70130e
+
70130e
+    <enum name="format">
70130e
+      
70130e
+           The formats actually supported by the compositor will be
70130e
+           reported by the format event. -->
70130e
+      <entry name="c8" value="0x20203843"/>
70130e
+      <entry name="rgb332" value="0x38424752"/>
70130e
+      <entry name="bgr233" value="0x38524742"/>
70130e
+      <entry name="xrgb4444" value="0x32315258"/>
70130e
+      <entry name="xbgr4444" value="0x32314258"/>
70130e
+      <entry name="rgbx4444" value="0x32315852"/>
70130e
+      <entry name="bgrx4444" value="0x32315842"/>
70130e
+      <entry name="argb4444" value="0x32315241"/>
70130e
+      <entry name="abgr4444" value="0x32314241"/>
70130e
+      <entry name="rgba4444" value="0x32314152"/>
70130e
+      <entry name="bgra4444" value="0x32314142"/>
70130e
+      <entry name="xrgb1555" value="0x35315258"/>
70130e
+      <entry name="xbgr1555" value="0x35314258"/>
70130e
+      <entry name="rgbx5551" value="0x35315852"/>
70130e
+      <entry name="bgrx5551" value="0x35315842"/>
70130e
+      <entry name="argb1555" value="0x35315241"/>
70130e
+      <entry name="abgr1555" value="0x35314241"/>
70130e
+      <entry name="rgba5551" value="0x35314152"/>
70130e
+      <entry name="bgra5551" value="0x35314142"/>
70130e
+      <entry name="rgb565" value="0x36314752"/>
70130e
+      <entry name="bgr565" value="0x36314742"/>
70130e
+      <entry name="rgb888" value="0x34324752"/>
70130e
+      <entry name="bgr888" value="0x34324742"/>
70130e
+      <entry name="xrgb8888" value="0x34325258"/>
70130e
+      <entry name="xbgr8888" value="0x34324258"/>
70130e
+      <entry name="rgbx8888" value="0x34325852"/>
70130e
+      <entry name="bgrx8888" value="0x34325842"/>
70130e
+      <entry name="argb8888" value="0x34325241"/>
70130e
+      <entry name="abgr8888" value="0x34324241"/>
70130e
+      <entry name="rgba8888" value="0x34324152"/>
70130e
+      <entry name="bgra8888" value="0x34324142"/>
70130e
+      <entry name="xrgb2101010" value="0x30335258"/>
70130e
+      <entry name="xbgr2101010" value="0x30334258"/>
70130e
+      <entry name="rgbx1010102" value="0x30335852"/>
70130e
+      <entry name="bgrx1010102" value="0x30335842"/>
70130e
+      <entry name="argb2101010" value="0x30335241"/>
70130e
+      <entry name="abgr2101010" value="0x30334241"/>
70130e
+      <entry name="rgba1010102" value="0x30334152"/>
70130e
+      <entry name="bgra1010102" value="0x30334142"/>
70130e
+      <entry name="yuyv" value="0x56595559"/>
70130e
+      <entry name="yvyu" value="0x55595659"/>
70130e
+      <entry name="uyvy" value="0x59565955"/>
70130e
+      <entry name="vyuy" value="0x59555956"/>
70130e
+      <entry name="ayuv" value="0x56555941"/>
70130e
+      <entry name="nv12" value="0x3231564e"/>
70130e
+      <entry name="nv21" value="0x3132564e"/>
70130e
+      <entry name="nv16" value="0x3631564e"/>
70130e
+      <entry name="nv61" value="0x3136564e"/>
70130e
+      <entry name="yuv410" value="0x39565559"/>
70130e
+      <entry name="yvu410" value="0x39555659"/>
70130e
+      <entry name="yuv411" value="0x31315559"/>
70130e
+      <entry name="yvu411" value="0x31315659"/>
70130e
+      <entry name="yuv420" value="0x32315559"/>
70130e
+      <entry name="yvu420" value="0x32315659"/>
70130e
+      <entry name="yuv422" value="0x36315559"/>
70130e
+      <entry name="yvu422" value="0x36315659"/>
70130e
+      <entry name="yuv444" value="0x34325559"/>
70130e
+      <entry name="yvu444" value="0x34325659"/>
70130e
+    </enum>
70130e
+
70130e
+    
70130e
+         It will be passed on to the drmAuthMagic() or
70130e
+         DRIAuthConnection() call.  This authentication must be
70130e
+         completed before create_buffer could be used. -->
70130e
+    <request name="authenticate">
70130e
+      <arg name="id" type="uint"/>
70130e
+    </request>
70130e
+
70130e
+    
70130e
+         surface must have a name using the flink ioctl -->
70130e
+    <request name="create_buffer">
70130e
+      <arg name="id" type="new_id" interface="wl_buffer"/>
70130e
+      <arg name="name" type="uint"/>
70130e
+      <arg name="width" type="int"/>
70130e
+      <arg name="height" type="int"/>
70130e
+      <arg name="stride" type="uint"/>
70130e
+      <arg name="format" type="uint"/>
70130e
+    </request>
70130e
+
70130e
+    
70130e
+         the server.  The client should use this device for creating
70130e
+         local buffers.  Only buffers created from this device should
70130e
+         be be passed to the server using this drm object's
70130e
+         create_buffer request. -->
70130e
+    <event name="device">
70130e
+      <arg name="name" type="string"/>
70130e
+    </event>
70130e
+
70130e
+    <event name="format">
70130e
+      <arg name="format" type="uint"/>
70130e
+    </event>
70130e
+
70130e
+    
70130e
+    <event name="authenticated"/>
70130e
+  </interface>
70130e
+
70130e
+</protocol>
70130e
diff --git a/hw/xfree86/xwayland/xserver.xml b/hw/xfree86/xwayland/xserver.xml
70130e
new file mode 100644
70130e
index 0000000..9e25f5c
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xserver.xml
70130e
@@ -0,0 +1,18 @@
70130e
+<protocol name="xserver">
70130e
+
70130e
+  <interface name="xserver" version="1">
70130e
+    <request name="set_window_id">
70130e
+      <arg name="surface" type="object" interface="wl_surface"/>
70130e
+      <arg name="id" type="uint"/>
70130e
+    </request>
70130e
+
70130e
+    <event name="client">
70130e
+      <arg name="fd" type="fd"/>
70130e
+    </event>
70130e
+
70130e
+    <event name="listen_socket">
70130e
+      <arg name="fd" type="fd"/>
70130e
+    </event>
70130e
+  </interface>
70130e
+
70130e
+</protocol>
70130e
diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c
70130e
new file mode 100644
70130e
index 0000000..f8860bd
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland-cursor.c
70130e
@@ -0,0 +1,241 @@
70130e
+/*
70130e
+ * Copyright © 2011 Kristian Høgsberg
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifdef HAVE_XORG_CONFIG_H
70130e
+#include "xorg-config.h"
70130e
+#endif
70130e
+
70130e
+#include <unistd.h>
70130e
+#include <errno.h>
70130e
+#include <sys/mman.h>
70130e
+#include <wayland-client.h>
70130e
+
70130e
+#include <xorg-server.h>
70130e
+#include <cursorstr.h>
70130e
+#include <xf86Crtc.h>
70130e
+#include <mipointrst.h>
70130e
+
70130e
+#include "xwayland.h"
70130e
+#include "xwayland-private.h"
70130e
+#include "xserver-client-protocol.h"
70130e
+
70130e
+static DevPrivateKeyRec xwl_cursor_private_key;
70130e
+
70130e
+static void
70130e
+expand_source_and_mask(CursorPtr cursor, void *data)
70130e
+{
70130e
+    CARD32 *argb, *p, d, fg, bg;
70130e
+    CursorBitsPtr bits = cursor->bits;
70130e
+    int size;
70130e
+    int x, y, stride, i, bit;
70130e
+
70130e
+    size = bits->width * bits->height * 4;
70130e
+    argb = malloc(size);
70130e
+    if (argb == NULL)
70130e
+	return;
70130e
+
70130e
+    p = argb;
70130e
+    fg = ((cursor->foreRed & 0xff00) << 8) |
70130e
+	(cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8);
70130e
+    bg = ((cursor->backRed & 0xff00) << 8) |
70130e
+	(cursor->backGreen & 0xff00) | (cursor->backGreen >> 8);
70130e
+    stride = (bits->width / 8 + 3) & ~3;
70130e
+    for (y = 0; y < bits->height; y++)
70130e
+	for (x = 0; x < bits->width; x++) {
70130e
+	    i = y * stride + x / 8;
70130e
+	    bit = 1 << (x & 7);
70130e
+	    if (bits->source[i] & bit)
70130e
+		d = fg;
70130e
+	    else
70130e
+		d = bg;
70130e
+	    if (bits->mask[i] & bit)
70130e
+		d |= 0xff000000;
70130e
+	    else
70130e
+		d = 0x00000000;
70130e
+
70130e
+	    *p++ = d;
70130e
+	}
70130e
+
70130e
+    memcpy(data, argb, size);
70130e
+    free(argb);
70130e
+}
70130e
+
70130e
+static Bool
70130e
+xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    int size;
70130e
+    char filename[] = "/tmp/wayland-shm-XXXXXX";
70130e
+    int fd;
70130e
+    struct wl_shm_pool *pool;
70130e
+    struct wl_buffer *buffer;
70130e
+    void *data;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+    size = cursor->bits->width * cursor->bits->height * 4;
70130e
+
70130e
+    fd = mkstemp(filename);
70130e
+    if (fd < 0) {
70130e
+	ErrorF("open %s failed: %s", filename, strerror(errno));
70130e
+	return FALSE;
70130e
+    }
70130e
+    if (ftruncate(fd, size) < 0) {
70130e
+	ErrorF("ftruncate failed: %s", strerror(errno));
70130e
+	close(fd);
70130e
+	return FALSE;
70130e
+    }
70130e
+
70130e
+    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
70130e
+    unlink(filename);
70130e
+
70130e
+    if (data == MAP_FAILED) {
70130e
+	ErrorF("mmap failed: %s", strerror(errno));
70130e
+	close(fd);
70130e
+	return FALSE;
70130e
+    }
70130e
+
70130e
+    if (cursor->bits->argb)
70130e
+	memcpy(data, cursor->bits->argb, size);
70130e
+    else
70130e
+	expand_source_and_mask(cursor, data);
70130e
+    munmap(data, size);
70130e
+
70130e
+    pool = wl_shm_create_pool(xwl_screen->shm, fd, size);
70130e
+    close(fd);
70130e
+    buffer = wl_shm_pool_create_buffer(pool, 0,
70130e
+				  cursor->bits->width, cursor->bits->height,
70130e
+				  cursor->bits->width * 4,
70130e
+				  WL_SHM_FORMAT_ARGB8888);
70130e
+    wl_shm_pool_destroy(pool);
70130e
+
70130e
+    dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, buffer);
70130e
+
70130e
+    return TRUE;
70130e
+}
70130e
+
70130e
+static Bool
70130e
+xwl_unrealize_cursor(DeviceIntPtr device,
70130e
+			ScreenPtr screen, CursorPtr cursor)
70130e
+{
70130e
+    struct wl_buffer *buffer;
70130e
+
70130e
+    buffer = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
70130e
+    wl_buffer_destroy(buffer);
70130e
+
70130e
+    return TRUE;
70130e
+}
70130e
+
70130e
+void
70130e
+xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
70130e
+{
70130e
+    struct wl_buffer *buffer;
70130e
+
70130e
+    if (!xwl_seat->x_cursor || !xwl_seat->wl_pointer)
70130e
+        return;
70130e
+
70130e
+    buffer = dixGetPrivate(&xwl_seat->x_cursor->devPrivates,
70130e
+                           &xwl_cursor_private_key);
70130e
+
70130e
+    wl_pointer_set_cursor(xwl_seat->wl_pointer,
70130e
+			  xwl_seat->pointer_enter_serial,
70130e
+			  xwl_seat->cursor,
70130e
+			  xwl_seat->x_cursor->bits->xhot,
70130e
+			  xwl_seat->x_cursor->bits->yhot);
70130e
+    wl_surface_attach(xwl_seat->cursor, buffer, 0, 0);
70130e
+    wl_surface_damage(xwl_seat->cursor, 0, 0,
70130e
+		      xwl_seat->x_cursor->bits->width,
70130e
+		      xwl_seat->x_cursor->bits->height);
70130e
+    wl_surface_commit(xwl_seat->cursor);
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_set_cursor(DeviceIntPtr device,
70130e
+	       ScreenPtr screen, CursorPtr cursor, int x, int y)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    struct xwl_seat *xwl_seat;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    if (!xwl_screen || xorg_list_is_empty(&xwl_screen->seat_list))
70130e
+	return;
70130e
+
70130e
+    xwl_seat = xorg_list_first_entry(&xwl_screen->seat_list,
70130e
+		                     struct xwl_seat, link);
70130e
+
70130e
+    xwl_seat->x_cursor = cursor;
70130e
+    xwl_seat_set_cursor(xwl_seat);
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y)
70130e
+{
70130e
+}
70130e
+
70130e
+static Bool
70130e
+xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    return xwl_screen->sprite_funcs->DeviceCursorInitialize(device,
70130e
+							       screen);
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    xwl_screen->sprite_funcs->DeviceCursorCleanup(device, screen);
70130e
+}
70130e
+
70130e
+static miPointerSpriteFuncRec xwl_pointer_sprite_funcs =
70130e
+{
70130e
+    xwl_realize_cursor,
70130e
+    xwl_unrealize_cursor,
70130e
+    xwl_set_cursor,
70130e
+    xwl_move_cursor,
70130e
+    xwl_device_cursor_initialize,
70130e
+    xwl_device_cursor_cleanup
70130e
+};
70130e
+
70130e
+int
70130e
+xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen)
70130e
+{
70130e
+    miPointerScreenPtr pointer_priv;
70130e
+
70130e
+    if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR, 0))
70130e
+	return BadAlloc;
70130e
+
70130e
+    pointer_priv = dixLookupPrivate(&screen->devPrivates, miPointerScreenKey);
70130e
+    xwl_screen->sprite_funcs = pointer_priv->spriteFuncs;
70130e
+    pointer_priv->spriteFuncs = &xwl_pointer_sprite_funcs;
70130e
+
70130e
+    return Success;
70130e
+}
70130e
diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
70130e
new file mode 100644
70130e
index 0000000..ce56e4c
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland-drm.c
70130e
@@ -0,0 +1,235 @@
70130e
+/*
70130e
+ * Copyright © 2011 Kristian Høgsberg
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifdef HAVE_XORG_CONFIG_H
70130e
+#include "xorg-config.h"
70130e
+#endif
70130e
+
70130e
+#include <unistd.h>
70130e
+#include <fcntl.h>
70130e
+
70130e
+#include <xf86drm.h>
70130e
+#include <wayland-util.h>
70130e
+#include <wayland-client.h>
70130e
+#include <drm-client-protocol.h>
70130e
+
70130e
+#include <xf86Xinput.h>
70130e
+#include <xf86Crtc.h>
70130e
+#include <xf86str.h>
70130e
+#include <windowstr.h>
70130e
+#include <input.h>
70130e
+#include <inputstr.h>
70130e
+#include <exevents.h>
70130e
+
70130e
+#include "xwayland.h"
70130e
+#include "xwayland-private.h"
70130e
+#include "../dri2/dri2.h"
70130e
+
70130e
+struct xwl_auth_req {
70130e
+    struct xorg_list link;
70130e
+
70130e
+    ClientPtr client;
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    uint32_t magic;
70130e
+};
70130e
+
70130e
+static void
70130e
+drm_handle_device (void *data, struct wl_drm *drm, const char *device)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+
70130e
+    xwl_screen->device_name = strdup (device);
70130e
+}
70130e
+
70130e
+static void
70130e
+drm_handle_format(void *data, struct wl_drm *wl_drm, uint32_t format)
70130e
+{
70130e
+}
70130e
+
70130e
+static void
70130e
+drm_handle_authenticated (void *data, struct wl_drm *drm)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+    struct xwl_auth_req *req;
70130e
+
70130e
+    xwl_screen->authenticated = 1;
70130e
+
70130e
+    /* it does one authentication transaction at a time, so if there's an
70130e
+     * element in the list, we call DRI2SendAuthReply for that client, remove
70130e
+     * the head and free the struct. If there are still elements in the list,
70130e
+     * it means that we have one or more clients waiting to be authenticated
70130e
+     * and we send out a wl_drm authenticate request for the first client in
70130e
+     * the list */
70130e
+    if (xorg_list_is_empty(&xwl_screen->authenticate_client_list))
70130e
+	return;
70130e
+
70130e
+    req = xorg_list_first_entry(&xwl_screen->authenticate_client_list,
70130e
+	                        struct xwl_auth_req, link);
70130e
+    DRI2SendAuthReply(req->client, TRUE);
70130e
+    AttendClient(req->client);
70130e
+    xorg_list_del(&req->link);
70130e
+    free(req);
70130e
+
70130e
+    xorg_list_for_each_entry(req, &xwl_screen->authenticate_client_list,
70130e
+	                     link) {
70130e
+	wl_drm_authenticate (xwl_screen->drm, req->magic);
70130e
+	return;
70130e
+    }
70130e
+}
70130e
+
70130e
+static const struct wl_drm_listener xwl_drm_listener =
70130e
+{
70130e
+    drm_handle_device,
70130e
+    drm_handle_format,
70130e
+    drm_handle_authenticated
70130e
+};
70130e
+
70130e
+static void
70130e
+drm_handler(void *data, struct wl_registry *registry, uint32_t id,
70130e
+	    const char *interface, uint32_t version)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+
70130e
+    if (strcmp (interface, "wl_drm") == 0) {
70130e
+	xwl_screen->drm = wl_registry_bind(xwl_screen->registry, id,
70130e
+                                           &wl_drm_interface, 1);
70130e
+	wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
70130e
+    }
70130e
+}
70130e
+
70130e
+static const struct wl_registry_listener drm_listener = {
70130e
+    drm_handler,
70130e
+};
70130e
+
70130e
+int
70130e
+xwl_drm_pre_init(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    uint32_t magic;
70130e
+
70130e
+    xwl_screen->drm_registry = wl_display_get_registry(xwl_screen->display);
70130e
+    wl_registry_add_listener(xwl_screen->drm_registry, &drm_listener,
70130e
+                             xwl_screen);
70130e
+
70130e
+    /* Ensure drm_handler has seen all the interfaces */
70130e
+    wl_display_roundtrip(xwl_screen->display);
70130e
+    /* Ensure the xwl_drm_listener has seen the drm device, if any */
70130e
+    wl_display_roundtrip(xwl_screen->display);
70130e
+
70130e
+    ErrorF("wayland_drm_screen_init, device name %s\n",
70130e
+	   xwl_screen->device_name);
70130e
+
70130e
+    xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR);
70130e
+    if (xwl_screen->drm_fd < 0) {
70130e
+	ErrorF("failed to open the drm fd\n");
70130e
+	return BadAccess;
70130e
+    }
70130e
+
70130e
+    if (drmGetMagic(xwl_screen->drm_fd, &magic)) {
70130e
+	ErrorF("failed to get drm magic");
70130e
+	return BadAccess;
70130e
+    }
70130e
+
70130e
+    wl_drm_authenticate(xwl_screen->drm, magic);
70130e
+
70130e
+    wl_display_roundtrip(xwl_screen->display);
70130e
+
70130e
+    ErrorF("opened drm fd: %d\n", xwl_screen->drm_fd);
70130e
+
70130e
+    if (!xwl_screen->authenticated) {
70130e
+	ErrorF("Failed to auth drm fd\n");
70130e
+	return BadAccess;
70130e
+    }
70130e
+
70130e
+    return Success;
70130e
+}
70130e
+
70130e
+Bool xwl_drm_initialised(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    return xwl_screen->authenticated;
70130e
+}
70130e
+
70130e
+int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    return xwl_screen->drm_fd;
70130e
+}
70130e
+
70130e
+int xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
70130e
+			    uint32_t magic)
70130e
+{
70130e
+    struct xwl_auth_req *req;
70130e
+
70130e
+    if (!xwl_screen->drm)
70130e
+	return BadAccess;
70130e
+
70130e
+    req = malloc (sizeof *req);
70130e
+    if (req == NULL)
70130e
+	return BadAlloc;
70130e
+
70130e
+    req->client = client;
70130e
+    req->xwl_screen = xwl_screen;
70130e
+    req->magic = magic;
70130e
+
70130e
+    if (xorg_list_is_empty(&xwl_screen->authenticate_client_list))
70130e
+	wl_drm_authenticate (xwl_screen->drm, magic);
70130e
+
70130e
+    xorg_list_append(&req->link, &xwl_screen->authenticate_client_list);
70130e
+
70130e
+    IgnoreClient(req->client);
70130e
+    xwl_screen->authenticated = 0;
70130e
+
70130e
+    return Success;
70130e
+}
70130e
+
70130e
+
70130e
+int
70130e
+xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
70130e
+			     PixmapPtr pixmap, uint32_t name)
70130e
+{
70130e
+    VisualID visual;
70130e
+    WindowPtr window = xwl_window->window;
70130e
+    ScreenPtr screen = window->drawable.pScreen;
70130e
+    uint32_t format;
70130e
+    int i;
70130e
+
70130e
+    visual = wVisual(window);
70130e
+    for (i = 0; i < screen->numVisuals; i++)
70130e
+	if (screen->visuals[i].vid == visual)
70130e
+	    break;
70130e
+
70130e
+    if (screen->visuals[i].nplanes == 32)
70130e
+	format = WL_DRM_FORMAT_ARGB8888;
70130e
+    else
70130e
+	format = WL_DRM_FORMAT_XRGB8888;
70130e
+
70130e
+    xwl_window->buffer =
70130e
+      wl_drm_create_buffer(xwl_window->xwl_screen->drm,
70130e
+			   name,
70130e
+			   pixmap->drawable.width,
70130e
+			   pixmap->drawable.height,
70130e
+			   pixmap->devKind,
70130e
+			   format);
70130e
+
70130e
+    return xwl_window->buffer ? Success : BadDrawable;
70130e
+}
70130e
diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
70130e
new file mode 100644
70130e
index 0000000..2f8e0c7
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland-input.c
70130e
@@ -0,0 +1,610 @@
70130e
+/*
70130e
+ * Copyright © 2008 Kristian Høgsberg
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifdef HAVE_XORG_CONFIG_H
70130e
+#include "xorg-config.h"
70130e
+#endif
70130e
+
70130e
+#include <errno.h>
70130e
+#include <stdint.h>
70130e
+#include <unistd.h>
70130e
+#include <linux/input.h>
70130e
+#include <wayland-util.h>
70130e
+#include <wayland-client.h>
70130e
+#include <X11/extensions/compositeproto.h>
70130e
+#include <xserver-properties.h>
70130e
+
70130e
+#include <compositeext.h>
70130e
+#include <selection.h>
70130e
+#include <extinit.h>
70130e
+#include <exevents.h>
70130e
+#include <input.h>
70130e
+#include <inpututils.h>
70130e
+#include <inputstr.h>
70130e
+#include <exevents.h>
70130e
+#include <xkbsrv.h>
70130e
+#include <xf86Xinput.h>
70130e
+#include <xf86Crtc.h>
70130e
+#include <xf86str.h>
70130e
+#include <windowstr.h>
70130e
+#include <xf86Priv.h>
70130e
+#include <mipointrst.h>
70130e
+#include <sys/mman.h>
70130e
+
70130e
+#include "xwayland.h"
70130e
+#include "xwayland-private.h"
70130e
+#include "xserver-client-protocol.h"
70130e
+
70130e
+static void
70130e
+xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
70130e
+{
70130e
+	/* Nothing to do, dix handles all settings */
70130e
+}
70130e
+
70130e
+static int
70130e
+xwl_pointer_proc(DeviceIntPtr device, int what)
70130e
+{
70130e
+#define NBUTTONS 10
70130e
+#define NAXES 2
70130e
+    BYTE map[NBUTTONS + 1];
70130e
+    int i = 0;
70130e
+    Atom btn_labels[NBUTTONS] = {0};
70130e
+    Atom axes_labels[NAXES] = {0};
70130e
+
70130e
+    switch (what) {
70130e
+    case DEVICE_INIT:
70130e
+	device->public.on = FALSE;
70130e
+
70130e
+        for (i = 1; i <= NBUTTONS; i++)
70130e
+            map[i] = i;
70130e
+
70130e
+        btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
70130e
+        btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
70130e
+        btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
70130e
+        btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
70130e
+        btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
70130e
+        btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
70130e
+        btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
70130e
+        /* don't know about the rest */
70130e
+
70130e
+        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
70130e
+        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
70130e
+
70130e
+        if (!InitValuatorClassDeviceStruct(device, 2, btn_labels,
70130e
+                                           GetMotionHistorySize(), Absolute))
70130e
+            return BadValue;
70130e
+
70130e
+        /* Valuators */
70130e
+        InitValuatorAxisStruct(device, 0, axes_labels[0],
70130e
+                               0, 0xFFFF, 10000, 0, 10000, Absolute);
70130e
+        InitValuatorAxisStruct(device, 1, axes_labels[1],
70130e
+                               0, 0xFFFF, 10000, 0, 10000, Absolute);
70130e
+
70130e
+        if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
70130e
+            return BadValue;
70130e
+
70130e
+        if (!InitButtonClassDeviceStruct(device, 3, btn_labels, map))
70130e
+            return BadValue;
70130e
+
70130e
+        return Success;
70130e
+
70130e
+    case DEVICE_ON:
70130e
+	device->public.on = TRUE;
70130e
+        return Success;
70130e
+
70130e
+    case DEVICE_OFF:
70130e
+    case DEVICE_CLOSE:
70130e
+	device->public.on = FALSE;
70130e
+        return Success;
70130e
+    }
70130e
+
70130e
+    return BadMatch;
70130e
+
70130e
+#undef NBUTTONS
70130e
+#undef NAXES
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl)
70130e
+{
70130e
+    /* FIXME: Set keyboard leds based on CAPSFLAG etc being set in
70130e
+     * ctrl->leds - needs private protocol. */
70130e
+}
70130e
+
70130e
+static int
70130e
+xwl_keyboard_proc(DeviceIntPtr device, int what)
70130e
+{
70130e
+    InputInfoPtr pInfo = device->public.devicePrivate;
70130e
+    struct xwl_seat *xwl_seat = pInfo->private;
70130e
+    int len;
70130e
+
70130e
+    switch (what) {
70130e
+    case DEVICE_INIT:
70130e
+	device->public.on = FALSE;
70130e
+	len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size);
70130e
+        if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap,
70130e
+						len,
70130e
+						NULL, xwl_keyboard_control))
70130e
+            return BadValue;
70130e
+
70130e
+        return Success;
70130e
+    case DEVICE_ON:
70130e
+	device->public.on = TRUE;
70130e
+        return Success;
70130e
+
70130e
+    case DEVICE_OFF:
70130e
+    case DEVICE_CLOSE:
70130e
+	device->public.on = FALSE;
70130e
+        return Success;
70130e
+    }
70130e
+
70130e
+    return BadMatch;
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_keyboard_uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
70130e
+{
70130e
+}
70130e
+
70130e
+static int
70130e
+xwl_keyboard_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
70130e
+{
70130e
+    pInfo->type_name = "xwayland-keyboard";
70130e
+    pInfo->device_control = xwl_keyboard_proc;
70130e
+    pInfo->read_input = NULL;
70130e
+    pInfo->control_proc = NULL;
70130e
+    pInfo->switch_mode = NULL;
70130e
+    pInfo->fd = -1;
70130e
+
70130e
+    return Success;
70130e
+}
70130e
+
70130e
+_X_EXPORT InputDriverRec xwl_keyboard_driver = {
70130e
+    1,
70130e
+    "xwayland-keyboard",
70130e
+    NULL,
70130e
+    xwl_keyboard_init,
70130e
+    xwl_keyboard_uninit,
70130e
+    NULL,
70130e
+};
70130e
+
70130e
+static void
70130e
+xwl_pointer_uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
70130e
+{
70130e
+}
70130e
+
70130e
+static int
70130e
+xwl_pointer_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
70130e
+{
70130e
+    pInfo->type_name = "xwayland-pointer";
70130e
+    pInfo->device_control = xwl_pointer_proc;
70130e
+    pInfo->read_input = NULL;
70130e
+    pInfo->control_proc = NULL;
70130e
+    pInfo->switch_mode = NULL;
70130e
+    pInfo->fd = -1;
70130e
+
70130e
+    return Success;
70130e
+}
70130e
+
70130e
+_X_EXPORT InputDriverRec xwl_pointer_driver = {
70130e
+    1,
70130e
+    "xwayland-pointer",
70130e
+    NULL,
70130e
+    xwl_pointer_init,
70130e
+    xwl_pointer_uninit,
70130e
+    NULL,
70130e
+};
70130e
+
70130e
+void
70130e
+xwl_input_teardown(pointer p)
70130e
+{
70130e
+}
70130e
+
70130e
+pointer
70130e
+xwl_input_setup(pointer module, pointer opts, int *errmaj, int *errmin)
70130e
+{
70130e
+    xf86AddInputDriver(&xwl_keyboard_driver, module, 0);
70130e
+    xf86AddInputDriver(&xwl_pointer_driver, module, 0);
70130e
+
70130e
+    return module;
70130e
+}
70130e
+
70130e
+static DeviceIntPtr
70130e
+device_added(struct xwl_seat *xwl_seat, const char *driver)
70130e
+{
70130e
+    DeviceIntPtr dev = NULL;
70130e
+    InputInfoPtr pInfo;
70130e
+    int rc;
70130e
+
70130e
+    pInfo = xf86AllocateInput();
70130e
+    if (!pInfo)
70130e
+        return NULL;
70130e
+
70130e
+    pInfo->driver = xstrdup(driver);
70130e
+
70130e
+    if (asprintf(&pInfo->name, "%s:%d", pInfo->driver, xwl_seat->id) == -1) {
70130e
+	free(pInfo);
70130e
+	return NULL;
70130e
+    }
70130e
+
70130e
+    pInfo->private = xwl_seat;
70130e
+
70130e
+    rc = xf86NewInputDevice(pInfo, &dev, 1);
70130e
+    if (rc != Success) {
70130e
+	free(pInfo);
70130e
+	return NULL;
70130e
+    }
70130e
+
70130e
+    LogMessage(X_INFO, "config/xwayland: Adding input device %s\n",
70130e
+	       pInfo->name);
70130e
+
70130e
+    return dev;
70130e
+}
70130e
+
70130e
+static void
70130e
+pointer_handle_enter(void *data, struct wl_pointer *pointer,
70130e
+		     uint32_t serial, struct wl_surface *surface,
70130e
+		     wl_fixed_t sx_w, wl_fixed_t sy_w)
70130e
+
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    DeviceIntPtr dev = xwl_seat->pointer;
70130e
+    int i;
70130e
+    int sx = wl_fixed_to_int(sx_w);
70130e
+    int sy = wl_fixed_to_int(sy_w);
70130e
+    ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
70130e
+
70130e
+    xwl_seat->xwl_screen->serial = serial;
70130e
+    xwl_seat->pointer_enter_serial = serial;
70130e
+
70130e
+    xwl_seat->focus_window = wl_surface_get_user_data(surface);
70130e
+
70130e
+    (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE);
70130e
+
70130e
+    SetDeviceRedirectWindow(xwl_seat->pointer, xwl_seat->focus_window->window);
70130e
+
70130e
+    /* Ideally, X clients shouldn't see these button releases.  When
70130e
+     * the pointer leaves a window with buttons down, it means that
70130e
+     * the wayland compositor has grabbed the pointer.  The button
70130e
+     * release event is consumed by whatever grab in the compositor
70130e
+     * and won't be sent to clients (the X server is a client).
70130e
+     * However, we need to reset X's idea of which buttons are up and
70130e
+     * down, and they're all up (by definition) when the pointer
70130e
+     * enters a window.  We should figure out a way to swallow these
70130e
+     * events, perhaps using an X grab whenever the pointer is not in
70130e
+     * any X window, but for now just send the events. */
70130e
+    for (i = 0; i < dev->button->numButtons; i++)
70130e
+	if (BitIsOn(dev->button->down, i))
70130e
+		xf86PostButtonEvent(dev, TRUE, i, 0, 0, 0);
70130e
+
70130e
+    (*pScreen->DisplayCursor)(dev, pScreen, dev->spriteInfo->sprite->current);
70130e
+}
70130e
+
70130e
+static void
70130e
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
70130e
+		     uint32_t serial, struct wl_surface *surface)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    DeviceIntPtr dev = xwl_seat->pointer;
70130e
+    ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
70130e
+
70130e
+    xwl_seat->xwl_screen->serial = serial;
70130e
+
70130e
+    xwl_seat->focus_window = NULL;
70130e
+    SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin);
70130e
+    (*pScreen->DisplayCursor)(dev, pScreen, NullCursor);
70130e
+}
70130e
+
70130e
+static void
70130e
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
70130e
+		      uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    int32_t dx, dy;
70130e
+    int sx = wl_fixed_to_int(sx_w);
70130e
+    int sy = wl_fixed_to_int(sy_w);
70130e
+    ValuatorMask mask;
70130e
+
70130e
+    if (!xwl_seat->focus_window)
70130e
+	return ;
70130e
+
70130e
+    dx = xwl_seat->focus_window->window->drawable.x;
70130e
+    dy = xwl_seat->focus_window->window->drawable.y;
70130e
+
70130e
+    valuator_mask_zero(&mask);
70130e
+    valuator_mask_set(&mask, 0, dx + sx);
70130e
+    valuator_mask_set(&mask, 1, dy + sy);
70130e
+
70130e
+    QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
70130e
+		       POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
70130e
+}
70130e
+
70130e
+static void
70130e
+pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
70130e
+		      uint32_t time, uint32_t button, uint32_t state)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    int index;
70130e
+
70130e
+    xwl_seat->xwl_screen->serial = serial;
70130e
+
70130e
+    switch (button) {
70130e
+    case BTN_MIDDLE:
70130e
+	index = 2;
70130e
+	break;
70130e
+    case BTN_RIGHT:
70130e
+	index = 3;
70130e
+	break;
70130e
+    default:
70130e
+	index = button - BTN_LEFT + 1;
70130e
+	break;
70130e
+    }
70130e
+
70130e
+    xf86PostButtonEvent(xwl_seat->pointer, TRUE, index, state, 0, 0);
70130e
+}
70130e
+
70130e
+static void
70130e
+pointer_handle_axis(void *data, struct wl_pointer *pointer,
70130e
+		    uint32_t time, uint32_t axis, wl_fixed_t value)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    int index, count;
70130e
+    int i, val;
70130e
+    const int divisor = 10;
70130e
+
70130e
+    if (time - xwl_seat->scroll_time > 2000) {
70130e
+	xwl_seat->vertical_scroll = 0;
70130e
+	xwl_seat->horizontal_scroll = 0;
70130e
+    }
70130e
+    xwl_seat->scroll_time = time;
70130e
+
70130e
+    /* FIXME: Need to do proper smooth scrolling here! */
70130e
+    switch (axis) {
70130e
+    case WL_POINTER_AXIS_VERTICAL_SCROLL:
70130e
+	xwl_seat->vertical_scroll += value / divisor;
70130e
+	val = wl_fixed_to_int(xwl_seat->vertical_scroll);
70130e
+	xwl_seat->vertical_scroll -= wl_fixed_from_int(val);
70130e
+
70130e
+	if (val <= -1)
70130e
+            index = 4;
70130e
+	else if (val >= 1)
70130e
+            index = 5;
70130e
+	else
70130e
+            return;
70130e
+	break;
70130e
+    case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
70130e
+	xwl_seat->horizontal_scroll += value / divisor;
70130e
+	val = wl_fixed_to_int(xwl_seat->horizontal_scroll);
70130e
+	xwl_seat->horizontal_scroll -= wl_fixed_from_int(val);
70130e
+
70130e
+	if (val <= -1)
70130e
+            index = 6;
70130e
+	else if (val >= 1)
70130e
+            index = 7;
70130e
+	else
70130e
+            return;
70130e
+	break;
70130e
+    default:
70130e
+	return;
70130e
+    }
70130e
+
70130e
+    count = abs(val);
70130e
+    for (i = 0; i < count; i++) {
70130e
+	xf86PostButtonEvent(xwl_seat->pointer, TRUE, index, 1, 0, 0);
70130e
+	xf86PostButtonEvent(xwl_seat->pointer, TRUE, index, 0, 0, 0);
70130e
+    }
70130e
+}
70130e
+
70130e
+static const struct wl_pointer_listener pointer_listener = {
70130e
+	pointer_handle_enter,
70130e
+	pointer_handle_leave,
70130e
+	pointer_handle_motion,
70130e
+	pointer_handle_button,
70130e
+	pointer_handle_axis,
70130e
+};
70130e
+
70130e
+static void
70130e
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
70130e
+		    uint32_t time, uint32_t key, uint32_t state)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    uint32_t *k, *end;
70130e
+
70130e
+    xwl_seat->xwl_screen->serial = serial;
70130e
+
70130e
+    end = xwl_seat->keys.data + xwl_seat->keys.size;
70130e
+    for (k = xwl_seat->keys.data; k < end; k++) {
70130e
+	if (*k == key)
70130e
+	    *k = *--end;
70130e
+    }
70130e
+    xwl_seat->keys.size = (void *) end - xwl_seat->keys.data;
70130e
+    if (state) {
70130e
+	k = wl_array_add(&xwl_seat->keys, sizeof *k);
70130e
+	*k = key;
70130e
+    }
70130e
+
70130e
+    xf86PostKeyboardEvent(xwl_seat->keyboard, key + 8, state);
70130e
+}
70130e
+
70130e
+static void
70130e
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
70130e
+		       uint32_t format, int fd, uint32_t size)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+
70130e
+    xwl_seat->keymap_size = size;
70130e
+    xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
70130e
+    if (xwl_seat->keymap == MAP_FAILED)
70130e
+	;	/* wah wah */
70130e
+
70130e
+    close(fd);
70130e
+}
70130e
+
70130e
+static void
70130e
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
70130e
+		      uint32_t serial,
70130e
+		      struct wl_surface *surface, struct wl_array *keys)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    uint32_t *k;
70130e
+
70130e
+    xwl_seat->xwl_screen->serial = serial;
70130e
+
70130e
+    wl_array_copy(&xwl_seat->keys, keys);
70130e
+    wl_array_for_each(k, &xwl_seat->keys)
70130e
+	xf86PostKeyboardEvent(xwl_seat->keyboard, *k + 8, 1);
70130e
+}
70130e
+
70130e
+static void
70130e
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
70130e
+		      uint32_t serial, struct wl_surface *surface)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+    uint32_t *k;
70130e
+
70130e
+    xwl_seat->xwl_screen->serial = serial;
70130e
+
70130e
+    wl_array_for_each(k, &xwl_seat->keys)
70130e
+	xf86PostKeyboardEvent(xwl_seat->keyboard, *k + 8, 0);
70130e
+}
70130e
+
70130e
+static void
70130e
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
70130e
+			  uint32_t serial, uint32_t mods_depressed,
70130e
+			  uint32_t mods_latched, uint32_t mods_locked,
70130e
+			  uint32_t group)
70130e
+{
70130e
+    /* FIXME: Need more server XKB API here. */
70130e
+}
70130e
+
70130e
+static const struct wl_keyboard_listener keyboard_listener = {
70130e
+	keyboard_handle_keymap,
70130e
+	keyboard_handle_enter,
70130e
+	keyboard_handle_leave,
70130e
+	keyboard_handle_key,
70130e
+	keyboard_handle_modifiers,
70130e
+};
70130e
+
70130e
+static void
70130e
+add_devices(void *data, struct wl_callback *callback, uint32_t time)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat = data;
70130e
+
70130e
+    wl_callback_destroy(callback);
70130e
+
70130e
+    if (xwl_seat->wl_pointer)
70130e
+	xwl_seat->pointer = device_added(xwl_seat, "xwayland-pointer");
70130e
+    if (xwl_seat->wl_keyboard)
70130e
+	xwl_seat->keyboard = device_added(xwl_seat, "xwayland-keyboard");
70130e
+}
70130e
+
70130e
+static const struct wl_callback_listener add_devices_listener = {
70130e
+	add_devices
70130e
+};
70130e
+
70130e
+static void
70130e
+seat_handle_capabilities(void *data, struct wl_seat *seat,
70130e
+			 enum wl_seat_capability caps)
70130e
+{
70130e
+	struct xwl_seat *xwl_seat = data;
70130e
+	struct wl_callback *callback;
70130e
+
70130e
+	if (caps & WL_SEAT_CAPABILITY_POINTER) {
70130e
+	    xwl_seat->wl_pointer = wl_seat_get_pointer(seat);
70130e
+	    wl_pointer_add_listener(xwl_seat->wl_pointer,
70130e
+				    &pointer_listener, xwl_seat);
70130e
+            xwl_seat_set_cursor(xwl_seat);
70130e
+	}
70130e
+
70130e
+	if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
70130e
+	    xwl_seat->wl_keyboard = wl_seat_get_keyboard(seat);
70130e
+	    wl_keyboard_add_listener(xwl_seat->wl_keyboard,
70130e
+				     &keyboard_listener, xwl_seat);
70130e
+
70130e
+	}
70130e
+        /* FIXME: Touch ... */
70130e
+
70130e
+	/* Add devices after we've received keymaps. */
70130e
+	if (caps) {
70130e
+	    callback = wl_display_sync(xwl_seat->xwl_screen->display);
70130e
+	    wl_callback_add_listener(callback,
70130e
+				     &add_devices_listener, xwl_seat);
70130e
+	}
70130e
+}
70130e
+
70130e
+static const struct wl_seat_listener seat_listener = {
70130e
+	seat_handle_capabilities,
70130e
+};
70130e
+
70130e
+static void
70130e
+create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat;
70130e
+
70130e
+    xwl_seat = calloc(sizeof *xwl_seat, 1);
70130e
+    if (xwl_seat == NULL) {
70130e
+	ErrorF("create_input ENOMEM");
70130e
+	return ;
70130e
+    }
70130e
+
70130e
+    xwl_seat->xwl_screen = xwl_screen;
70130e
+    xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
70130e
+
70130e
+    xwl_seat->seat =
70130e
+	wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 1);
70130e
+    xwl_seat->id = id;
70130e
+
70130e
+    xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
70130e
+    wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat);
70130e
+    wl_array_init(&xwl_seat->keys);
70130e
+}
70130e
+
70130e
+static void
70130e
+input_handler(void *data, struct wl_registry *registry, uint32_t id,
70130e
+	      const char *interface, uint32_t version)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+
70130e
+    if (strcmp (interface, "wl_seat") == 0) {
70130e
+        create_input_device(xwl_screen, id);
70130e
+    } else if (strcmp(interface, "xserver") == 0) {
70130e
+        xwl_screen->xorg_server =
70130e
+            wl_registry_bind(registry, id, &xserver_interface, 1);
70130e
+        xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
70130e
+                             xwl_screen);
70130e
+    }
70130e
+}
70130e
+
70130e
+static const struct wl_registry_listener input_listener = {
70130e
+    input_handler,
70130e
+};
70130e
+
70130e
+void
70130e
+xwl_input_init(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
70130e
+    wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
70130e
+                             xwl_screen);
70130e
+}
70130e
diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c
70130e
new file mode 100644
70130e
index 0000000..8f087f6
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland-output.c
70130e
@@ -0,0 +1,309 @@
70130e
+/*
70130e
+ * Copyright © 2011 Intel Corporation
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifdef HAVE_XORG_CONFIG_H
70130e
+#include "xorg-config.h"
70130e
+#endif
70130e
+
70130e
+#include <unistd.h>
70130e
+#include <errno.h>
70130e
+#include <sys/mman.h>
70130e
+#include <wayland-client.h>
70130e
+
70130e
+#include <xorg-server.h>
70130e
+#include <cursorstr.h>
70130e
+#include <xf86Crtc.h>
70130e
+#include <mipointrst.h>
70130e
+
70130e
+#include "xwayland.h"
70130e
+#include "xwayland-private.h"
70130e
+#include "xserver-client-protocol.h"
70130e
+
70130e
+static void
70130e
+crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
70130e
+{
70130e
+}
70130e
+
70130e
+static Bool
70130e
+crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
70130e
+		    Rotation rotation, int x, int y)
70130e
+{
70130e
+	return TRUE;
70130e
+}
70130e
+
70130e
+static void
70130e
+crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
70130e
+{
70130e
+}
70130e
+
70130e
+static void
70130e
+crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
70130e
+{
70130e
+}
70130e
+
70130e
+static void
70130e
+crtc_show_cursor (xf86CrtcPtr crtc)
70130e
+{
70130e
+}
70130e
+
70130e
+static void
70130e
+crtc_hide_cursor (xf86CrtcPtr crtc)
70130e
+{
70130e
+}
70130e
+
70130e
+static void
70130e
+crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
70130e
+{
70130e
+}
70130e
+
70130e
+static PixmapPtr
70130e
+crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
70130e
+{
70130e
+	return NULL;
70130e
+}
70130e
+
70130e
+static void *
70130e
+crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
70130e
+{
70130e
+	return NULL;
70130e
+}
70130e
+
70130e
+static void
70130e
+crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
70130e
+{
70130e
+}
70130e
+
70130e
+static const xf86CrtcFuncsRec crtc_funcs = {
70130e
+    .dpms                = crtc_dpms,
70130e
+    .set_mode_major      = crtc_set_mode_major,
70130e
+    .set_cursor_colors   = crtc_set_cursor_colors,
70130e
+    .set_cursor_position = crtc_set_cursor_position,
70130e
+    .show_cursor         = crtc_show_cursor,
70130e
+    .hide_cursor         = crtc_hide_cursor,
70130e
+    .load_cursor_argb    = crtc_load_cursor_argb,
70130e
+    .shadow_create       = crtc_shadow_create,
70130e
+    .shadow_allocate     = crtc_shadow_allocate,
70130e
+    .shadow_destroy      = crtc_shadow_destroy,
70130e
+    .destroy		 = NULL, /* XXX */
70130e
+};
70130e
+
70130e
+static void
70130e
+output_dpms(xf86OutputPtr output, int mode)
70130e
+{
70130e
+	return;
70130e
+}
70130e
+
70130e
+static xf86OutputStatus
70130e
+output_detect(xf86OutputPtr output)
70130e
+{
70130e
+	return XF86OutputStatusConnected;
70130e
+}
70130e
+
70130e
+static Bool
70130e
+output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
70130e
+{
70130e
+	return MODE_OK;
70130e
+}
70130e
+
70130e
+static DisplayModePtr
70130e
+output_get_modes(xf86OutputPtr xf86output)
70130e
+{
70130e
+    struct xwl_output *output = xf86output->driver_private;
70130e
+    struct monitor_ranges *ranges;
70130e
+    DisplayModePtr modes;
70130e
+
70130e
+    modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE);
70130e
+    output->xf86monitor.det_mon[0].type = DS_RANGES;
70130e
+    ranges = &output->xf86monitor.det_mon[0].section.ranges;
70130e
+    ranges->min_h = modes->HSync - 10;
70130e
+    ranges->max_h = modes->HSync + 10;
70130e
+    ranges->min_v = modes->VRefresh - 10;
70130e
+    ranges->max_v = modes->VRefresh + 10;
70130e
+    ranges->max_clock = modes->Clock + 100;
70130e
+    output->xf86monitor.det_mon[1].type = DT;
70130e
+    output->xf86monitor.det_mon[2].type = DT;
70130e
+    output->xf86monitor.det_mon[3].type = DT;
70130e
+    output->xf86monitor.no_sections = 0;
70130e
+
70130e
+    xf86output->MonInfo = &output->xf86monitor;
70130e
+
70130e
+    return modes;
70130e
+}
70130e
+
70130e
+static void
70130e
+output_destroy(xf86OutputPtr xf86output)
70130e
+{
70130e
+    struct xwl_output *output = xf86output->driver_private;
70130e
+
70130e
+    free(output);
70130e
+}
70130e
+
70130e
+static const xf86OutputFuncsRec output_funcs = {
70130e
+    .dpms	= output_dpms,
70130e
+    .detect	= output_detect,
70130e
+    .mode_valid	= output_mode_valid,
70130e
+    .get_modes	= output_get_modes,
70130e
+    .destroy	= output_destroy
70130e
+};
70130e
+
70130e
+struct xwl_output *
70130e
+xwl_output_create(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    struct xwl_output *xwl_output;
70130e
+    xf86OutputPtr xf86output;
70130e
+    xf86CrtcPtr xf86crtc;
70130e
+
70130e
+    xwl_output = calloc(sizeof *xwl_output, 1);
70130e
+    if (xwl_output == NULL) {
70130e
+	ErrorF("create_output ENOMEM");
70130e
+	return NULL;
70130e
+    }
70130e
+
70130e
+    xwl_output->xwl_screen = xwl_screen;
70130e
+
70130e
+    xf86output = xf86OutputCreate(xwl_screen->scrninfo,
70130e
+				  &output_funcs, "XWAYLAND-1");
70130e
+    xf86output->driver_private = xwl_output;
70130e
+    xf86output->possible_crtcs = 1;
70130e
+    xf86output->possible_clones = 1;
70130e
+
70130e
+    xf86crtc = xf86CrtcCreate(xwl_screen->scrninfo, &crtc_funcs);
70130e
+    xf86crtc->driver_private = xwl_output;
70130e
+
70130e
+    xwl_output->xf86output = xf86output;
70130e
+    xwl_output->xf86crtc = xf86crtc;
70130e
+
70130e
+    return xwl_output;
70130e
+}
70130e
+
70130e
+static Bool
70130e
+resize(ScrnInfoPtr scrn, int width, int height)
70130e
+{
70130e
+    if (scrn->virtualX == width && scrn->virtualY == height)
70130e
+	return TRUE;
70130e
+    /* We don't handle resize at all, we must match the compositor size */
70130e
+    return FALSE;
70130e
+}
70130e
+
70130e
+static const xf86CrtcConfigFuncsRec config_funcs = {
70130e
+    resize
70130e
+};
70130e
+
70130e
+static void
70130e
+display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
70130e
+			int physical_width, int physical_height, int subpixel,
70130e
+			const char *make, const char *model, int transform)
70130e
+{
70130e
+    struct xwl_output *xwl_output = data;
70130e
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
70130e
+
70130e
+    xwl_output->xf86output->mm_width = physical_width;
70130e
+    xwl_output->xf86output->mm_height = physical_height;
70130e
+
70130e
+    switch (subpixel) {
70130e
+    case WL_OUTPUT_SUBPIXEL_UNKNOWN:
70130e
+	xwl_output->xf86output->subpixel_order = SubPixelUnknown;
70130e
+	break;
70130e
+    case WL_OUTPUT_SUBPIXEL_NONE:
70130e
+	xwl_output->xf86output->subpixel_order = SubPixelNone;
70130e
+	break;
70130e
+    case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
70130e
+	xwl_output->xf86output->subpixel_order = SubPixelHorizontalRGB;
70130e
+	break;
70130e
+    case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
70130e
+	xwl_output->xf86output->subpixel_order = SubPixelHorizontalBGR;
70130e
+	break;
70130e
+    case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
70130e
+	xwl_output->xf86output->subpixel_order = SubPixelVerticalRGB;
70130e
+	break;
70130e
+    case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
70130e
+	xwl_output->xf86output->subpixel_order = SubPixelVerticalBGR;
70130e
+	break;
70130e
+    }
70130e
+
70130e
+    xwl_output->x = x;
70130e
+    xwl_output->y = y;
70130e
+
70130e
+    xwl_screen->xwl_output = xwl_output;
70130e
+}
70130e
+
70130e
+static void
70130e
+display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
70130e
+		    int width, int height, int refresh)
70130e
+{
70130e
+    struct xwl_output *xwl_output = data;
70130e
+
70130e
+    if (flags & WL_OUTPUT_MODE_CURRENT) {
70130e
+	xwl_output->width = width;
70130e
+	xwl_output->height = height;
70130e
+    }
70130e
+}
70130e
+
70130e
+static const struct wl_output_listener output_listener = {
70130e
+    display_handle_geometry,
70130e
+    display_handle_mode
70130e
+};
70130e
+
70130e
+static void
70130e
+global_handler(void *data, struct wl_registry *registry, uint32_t id,
70130e
+	       const char *interface, uint32_t version)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+    struct xwl_output *xwl_output;
70130e
+
70130e
+    if (strcmp (interface, "wl_output") == 0) {
70130e
+	xwl_output = xwl_output_create(xwl_screen);
70130e
+	xwl_output->output = wl_registry_bind(registry, id,
70130e
+	                                      &wl_output_interface, 1);
70130e
+	wl_output_add_listener(xwl_output->output,
70130e
+			       &output_listener, xwl_output);
70130e
+    }
70130e
+}
70130e
+
70130e
+static const struct wl_registry_listener global_listener = {
70130e
+    global_handler,
70130e
+};
70130e
+
70130e
+void
70130e
+xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo)
70130e
+{
70130e
+    int ret;
70130e
+
70130e
+    xf86CrtcConfigInit(scrninfo, &config_funcs);
70130e
+
70130e
+    xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192);
70130e
+
70130e
+    xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display);
70130e
+    wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
70130e
+                             xwl_screen);
70130e
+
70130e
+    while (!xwl_screen->xwl_output) {
70130e
+        ret = wl_display_roundtrip(xwl_screen->display);
70130e
+        if (ret == -1)
70130e
+            FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
70130e
+    }
70130e
+
70130e
+    xf86InitialConfiguration(scrninfo, TRUE);
70130e
+}
70130e
diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
70130e
new file mode 100644
70130e
index 0000000..e427316
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland-private.h
70130e
@@ -0,0 +1,132 @@
70130e
+/*
70130e
+ * Copyright © 2010 Kristian Høgsberg
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifndef _XWAYLAND_PRIVATE_H_
70130e
+#define _XWAYLAND_PRIVATE_H_
70130e
+
70130e
+struct xwl_window {
70130e
+    struct xwl_screen		*xwl_screen;
70130e
+    struct wl_surface		*surface;
70130e
+    struct wl_buffer		*buffer;
70130e
+    WindowPtr			 window;
70130e
+    DamagePtr			 damage;
70130e
+    struct xorg_list		 link;
70130e
+    struct xorg_list		 link_damage;
70130e
+};
70130e
+
70130e
+struct xwl_output;
70130e
+
70130e
+struct xwl_screen {
70130e
+    struct xwl_driver		*driver;
70130e
+    ScreenPtr			 screen;
70130e
+    ScrnInfoPtr			 scrninfo;
70130e
+    int				 drm_fd;
70130e
+    int				 wayland_fd;
70130e
+    struct xwl_output		*xwl_output;
70130e
+    struct wl_display		*display;
70130e
+    struct wl_registry          *registry;
70130e
+    struct wl_registry          *drm_registry;
70130e
+    struct wl_registry          *input_registry;
70130e
+    struct wl_registry          *output_registry;
70130e
+    struct wl_compositor	*compositor;
70130e
+    struct wl_drm		*drm;
70130e
+    struct wl_shm		*shm;
70130e
+    struct xserver		*xorg_server;
70130e
+    uint32_t			 mask;
70130e
+    uint32_t			 flags;
70130e
+    char			*device_name;
70130e
+    uint32_t			 authenticated;
70130e
+    struct xorg_list		 seat_list;
70130e
+    struct xorg_list		 damage_window_list;
70130e
+    struct xorg_list		 window_list;
70130e
+    struct xorg_list		 authenticate_client_list;
70130e
+    uint32_t			 serial;
70130e
+
70130e
+    CreateWindowProcPtr		 CreateWindow;
70130e
+    DestroyWindowProcPtr	 DestroyWindow;
70130e
+    RealizeWindowProcPtr	 RealizeWindow;
70130e
+    UnrealizeWindowProcPtr	 UnrealizeWindow;
70130e
+    SetWindowPixmapProcPtr	 SetWindowPixmap;
70130e
+    MoveWindowProcPtr		 MoveWindow;
70130e
+    miPointerSpriteFuncPtr	 sprite_funcs;
70130e
+};
70130e
+
70130e
+struct xwl_output {
70130e
+    struct wl_output		*output;
70130e
+    struct xwl_screen		*xwl_screen;
70130e
+    int32_t			 x, y, width, height;
70130e
+    xf86Monitor			 xf86monitor;
70130e
+    xf86OutputPtr		 xf86output;
70130e
+    xf86CrtcPtr			 xf86crtc;
70130e
+};
70130e
+
70130e
+
70130e
+#define MODIFIER_META 0x01
70130e
+
70130e
+struct xwl_seat {
70130e
+    DeviceIntPtr		 pointer;
70130e
+    DeviceIntPtr		 keyboard;
70130e
+    struct xwl_screen		*xwl_screen;
70130e
+    struct wl_seat		*seat;
70130e
+    struct wl_pointer		*wl_pointer;
70130e
+    struct wl_keyboard		*wl_keyboard;
70130e
+    struct wl_array		 keys;
70130e
+    struct wl_surface		*cursor;
70130e
+    struct xwl_window		*focus_window;
70130e
+    uint32_t			 id;
70130e
+    uint32_t			 pointer_enter_serial;
70130e
+    struct xorg_list		 link;
70130e
+    CursorPtr                    x_cursor;
70130e
+
70130e
+    wl_fixed_t			 horizontal_scroll;
70130e
+    wl_fixed_t			 vertical_scroll;
70130e
+    uint32_t			 scroll_time;
70130e
+
70130e
+    size_t			 keymap_size;
70130e
+    char			*keymap;
70130e
+
70130e
+};
70130e
+
70130e
+
70130e
+struct xwl_screen *xwl_screen_get(ScreenPtr screen);
70130e
+
70130e
+void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo);
70130e
+
70130e
+int xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen);
70130e
+int xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen);
70130e
+
70130e
+struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen);
70130e
+
70130e
+void xwl_input_teardown(pointer p);
70130e
+pointer xwl_input_setup(pointer module, pointer opts, int *errmaj, int *errmin);
70130e
+void xwl_input_init(struct xwl_screen *screen);
70130e
+
70130e
+Bool xwl_drm_initialised(struct xwl_screen *screen);
70130e
+
70130e
+void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
70130e
+
70130e
+extern const struct xserver_listener xwl_server_listener;
70130e
+
70130e
+#endif /* _XWAYLAND_PRIVATE_H_ */
70130e
diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c
70130e
new file mode 100644
70130e
index 0000000..925d63c
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland-window.c
70130e
@@ -0,0 +1,316 @@
70130e
+/*
70130e
+ * Copyright © 2011 Intel Corporation
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifdef HAVE_XORG_CONFIG_H
70130e
+#include "xorg-config.h"
70130e
+#endif
70130e
+
70130e
+#include <unistd.h>
70130e
+#include <errno.h>
70130e
+#include <sys/mman.h>
70130e
+#include <wayland-client.h>
70130e
+#include <X11/extensions/compositeproto.h>
70130e
+
70130e
+#include <xorg-server.h>
70130e
+#include <xf86Crtc.h>
70130e
+#include <selection.h>
70130e
+#include <compositeext.h>
70130e
+#include <exevents.h>
70130e
+
70130e
+#include "xwayland.h"
70130e
+#include "xwayland-private.h"
70130e
+#include "xserver-client-protocol.h"
70130e
+
70130e
+static DevPrivateKeyRec xwl_window_private_key;
70130e
+
70130e
+static void
70130e
+free_pixmap(void *data, struct wl_callback *callback, uint32_t time)
70130e
+{
70130e
+    PixmapPtr pixmap = data;
70130e
+    ScreenPtr screen = pixmap->drawable.pScreen;
70130e
+
70130e
+    (*screen->DestroyPixmap)(pixmap);
70130e
+    wl_callback_destroy(callback);
70130e
+}
70130e
+
70130e
+static const struct wl_callback_listener free_pixmap_listener = {
70130e
+	free_pixmap,
70130e
+};
70130e
+
70130e
+static void
70130e
+xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
70130e
+    struct wl_callback *callback;
70130e
+
70130e
+    /* We can safely destroy the buffer because we only use one buffer
70130e
+     * per surface in xwayland model */
70130e
+    if (xwl_window->buffer)
70130e
+        wl_buffer_destroy(xwl_window->buffer);
70130e
+
70130e
+    xwl_screen->driver->create_window_buffer(xwl_window, pixmap);
70130e
+
70130e
+    if (!xwl_window->buffer) {
70130e
+        ErrorF("failed to create buffer\n");
70130e
+	return;
70130e
+    }
70130e
+
70130e
+    wl_surface_attach(xwl_window->surface, xwl_window->buffer, 0, 0);
70130e
+    wl_surface_damage(xwl_window->surface, 0, 0,
70130e
+		      pixmap->drawable.width,
70130e
+		      pixmap->drawable.height);
70130e
+    wl_surface_commit(xwl_window->surface);
70130e
+
70130e
+    callback = wl_display_sync(xwl_screen->display);
70130e
+    wl_callback_add_listener(callback, &free_pixmap_listener, pixmap);
70130e
+    pixmap->refcnt++;
70130e
+}
70130e
+
70130e
+static Bool
70130e
+xwl_create_window(WindowPtr window)
70130e
+{
70130e
+    ScreenPtr screen = window->drawable.pScreen;
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    char buffer[32];
70130e
+    int len, rc;
70130e
+    Atom name;
70130e
+    Bool ret;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    screen->CreateWindow = xwl_screen->CreateWindow;
70130e
+    ret = (*screen->CreateWindow)(window);
70130e
+    xwl_screen->CreateWindow = screen->CreateWindow;
70130e
+    screen->CreateWindow = xwl_create_window;
70130e
+
70130e
+    if (!(xwl_screen->flags & XWL_FLAGS_ROOTLESS) ||
70130e
+	window->parent != NULL)
70130e
+	return ret;
70130e
+
70130e
+    CompositeRedirectSubwindows(window, CompositeRedirectManual);
70130e
+
70130e
+    return ret;
70130e
+}
70130e
+
70130e
+static int
70130e
+xwl_destroy_window (WindowPtr window)
70130e
+{
70130e
+    ScreenPtr screen = window->drawable.pScreen;
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    Bool ret;
70130e
+
70130e
+    if (window->parent == NULL)
70130e
+	CompositeUnRedirectSubwindows (window, CompositeRedirectManual);
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    screen->DestroyWindow = xwl_screen->DestroyWindow;
70130e
+    ret = (*screen->DestroyWindow)(window);
70130e
+    xwl_screen->DestroyWindow = screen->DestroyWindow;
70130e
+    screen->DestroyWindow = xwl_destroy_window;
70130e
+
70130e
+    return ret;
70130e
+}
70130e
+
70130e
+static void
70130e
+damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
70130e
+{
70130e
+    struct xwl_window *xwl_window = data;
70130e
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
70130e
+
70130e
+    xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
70130e
+}
70130e
+
70130e
+static void
70130e
+damage_destroy(DamagePtr pDamage, void *data)
70130e
+{
70130e
+}
70130e
+
70130e
+static Bool
70130e
+xwl_realize_window(WindowPtr window)
70130e
+{
70130e
+    ScreenPtr screen = window->drawable.pScreen;
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    struct xwl_window *xwl_window;
70130e
+    Bool ret;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    screen->RealizeWindow = xwl_screen->RealizeWindow;
70130e
+    ret = (*screen->RealizeWindow)(window);
70130e
+    xwl_screen->RealizeWindow = xwl_screen->RealizeWindow;
70130e
+    screen->RealizeWindow = xwl_realize_window;
70130e
+
70130e
+    if (xwl_screen->flags & XWL_FLAGS_ROOTLESS) {
70130e
+	if (window->redirectDraw != RedirectDrawManual)
70130e
+	    return ret;
70130e
+    } else {
70130e
+	if (window->parent)
70130e
+	    return ret;
70130e
+    }
70130e
+
70130e
+    xwl_window = calloc(sizeof *xwl_window, 1);
70130e
+    xwl_window->xwl_screen = xwl_screen;
70130e
+    xwl_window->window = window;
70130e
+    xwl_window->surface =
70130e
+	wl_compositor_create_surface(xwl_screen->compositor);
70130e
+    if (xwl_window->surface == NULL) {
70130e
+	ErrorF("wl_display_create_surface failed\n");
70130e
+	return FALSE;
70130e
+    }
70130e
+
70130e
+    if (xwl_screen->xorg_server)
70130e
+	xserver_set_window_id(xwl_screen->xorg_server,
70130e
+			      xwl_window->surface, window->drawable.id);
70130e
+
70130e
+    wl_surface_set_user_data(xwl_window->surface, xwl_window);
70130e
+    xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(window));
70130e
+
70130e
+    dixSetPrivate(&window->devPrivates,
70130e
+		  &xwl_window_private_key, xwl_window);
70130e
+
70130e
+    xwl_window->damage =
70130e
+	DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
70130e
+		     FALSE, screen, xwl_window);
70130e
+    DamageRegister(&window->drawable, xwl_window->damage);
70130e
+    DamageSetReportAfterOp(xwl_window->damage, TRUE);
70130e
+
70130e
+    xorg_list_add(&xwl_window->link, &xwl_screen->window_list);
70130e
+    xorg_list_init(&xwl_window->link_damage);
70130e
+
70130e
+    return ret;
70130e
+}
70130e
+
70130e
+static Bool
70130e
+xwl_unrealize_window(WindowPtr window)
70130e
+{
70130e
+    ScreenPtr screen = window->drawable.pScreen;
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    struct xwl_window *xwl_window;
70130e
+    struct xwl_seat *xwl_seat;
70130e
+    Bool ret;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    xorg_list_for_each_entry(xwl_seat,
70130e
+			     &xwl_screen->seat_list, link) {
70130e
+	if (!xwl_seat->focus_window)
70130e
+	    continue ;
70130e
+	if (xwl_seat->focus_window->window == window) {
70130e
+	    xwl_seat->focus_window = NULL;
70130e
+	    SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin);
70130e
+	}
70130e
+    }
70130e
+
70130e
+    screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
70130e
+    ret = (*screen->UnrealizeWindow)(window);
70130e
+    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
70130e
+    screen->UnrealizeWindow = xwl_unrealize_window;
70130e
+
70130e
+    xwl_window =
70130e
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
70130e
+    if (!xwl_window)
70130e
+	return ret;
70130e
+
70130e
+    if (xwl_window->buffer)
70130e
+	wl_buffer_destroy(xwl_window->buffer);
70130e
+    wl_surface_destroy(xwl_window->surface);
70130e
+    xorg_list_del(&xwl_window->link);
70130e
+    if (RegionNotEmpty(DamageRegion(xwl_window->damage)))
70130e
+	xorg_list_del(&xwl_window->link_damage);
70130e
+    DamageDestroy(xwl_window->damage);
70130e
+    free(xwl_window);
70130e
+    dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
70130e
+
70130e
+    return ret;
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
70130e
+{
70130e
+    ScreenPtr screen = window->drawable.pScreen;
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    struct xwl_window *xwl_window;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    screen->SetWindowPixmap = xwl_screen->SetWindowPixmap;
70130e
+    (*screen->SetWindowPixmap)(window, pixmap);
70130e
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
70130e
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
70130e
+
70130e
+    xwl_window =
70130e
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
70130e
+    if (xwl_window)
70130e
+	xwl_window_attach(xwl_window, pixmap);
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_move_window(WindowPtr window, int x, int y,
70130e
+		   WindowPtr sibling, VTKind kind)
70130e
+{
70130e
+    ScreenPtr screen = window->drawable.pScreen;
70130e
+    struct xwl_screen *xwl_screen;
70130e
+    struct xwl_window *xwl_window;
70130e
+
70130e
+    xwl_screen = xwl_screen_get(screen);
70130e
+
70130e
+    screen->MoveWindow = xwl_screen->MoveWindow;
70130e
+    (*screen->MoveWindow)(window, x, y, sibling, kind);
70130e
+    xwl_screen->MoveWindow = screen->MoveWindow;
70130e
+    screen->MoveWindow = xwl_move_window;
70130e
+
70130e
+    xwl_window =
70130e
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
70130e
+    if (xwl_window == NULL)
70130e
+	return;
70130e
+}
70130e
+
70130e
+int
70130e
+xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen)
70130e
+{
70130e
+    if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0))
70130e
+	return BadAlloc;
70130e
+
70130e
+    xwl_screen->CreateWindow = screen->CreateWindow;
70130e
+    screen->CreateWindow = xwl_create_window;
70130e
+
70130e
+    xwl_screen->DestroyWindow = screen->DestroyWindow;
70130e
+    screen->DestroyWindow = xwl_destroy_window;
70130e
+
70130e
+    xwl_screen->RealizeWindow = screen->RealizeWindow;
70130e
+    screen->RealizeWindow = xwl_realize_window;
70130e
+
70130e
+    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
70130e
+    screen->UnrealizeWindow = xwl_unrealize_window;
70130e
+
70130e
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
70130e
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
70130e
+
70130e
+    xwl_screen->MoveWindow = screen->MoveWindow;
70130e
+    screen->MoveWindow = xwl_move_window;
70130e
+
70130e
+    return Success;
70130e
+}
70130e
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
70130e
new file mode 100644
70130e
index 0000000..f59bfe4
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland.c
70130e
@@ -0,0 +1,392 @@
70130e
+/*
70130e
+ * Copyright © 2008-2011 Kristian Høgsberg
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifdef HAVE_XORG_CONFIG_H
70130e
+#include "xorg-config.h"
70130e
+#endif
70130e
+
70130e
+#include <stdint.h>
70130e
+#include <unistd.h>
70130e
+#include <fcntl.h>
70130e
+#include <errno.h>
70130e
+#include <wayland-util.h>
70130e
+#include <wayland-client.h>
70130e
+
70130e
+#include <xorg-server.h>
70130e
+#include <extinit.h>
70130e
+
70130e
+#include <xf86Xinput.h>
70130e
+#include <xf86Crtc.h>
70130e
+#include <xf86Priv.h>
70130e
+#include <os.h>
70130e
+#include <selection.h>
70130e
+
70130e
+#include "xwayland.h"
70130e
+#include "xwayland-private.h"
70130e
+#include "xserver-client-protocol.h"
70130e
+
70130e
+/*
70130e
+ * TODO:
70130e
+ *  - lose X kb focus when wayland surface loses it
70130e
+ *  - active grabs, grab owner crack
70130e
+ */
70130e
+
70130e
+static DevPrivateKeyRec xwl_screen_private_key;
70130e
+static Atom xdnd_atom;
70130e
+
70130e
+static void
70130e
+xserver_client(void *data, struct xserver *xserver, int fd)
70130e
+{
70130e
+    AddClientOnOpenFD(fd);
70130e
+}
70130e
+
70130e
+static void
70130e
+xserver_listen_socket(void *data, struct xserver *xserver, int fd)
70130e
+{
70130e
+    ListenOnOpenFD(fd, TRUE);
70130e
+}
70130e
+
70130e
+const struct xserver_listener xwl_server_listener = {
70130e
+    xserver_client,
70130e
+    xserver_listen_socket
70130e
+};
70130e
+
70130e
+static void
70130e
+xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+
70130e
+    ErrorF("xwl_input_delayed_init\n");
70130e
+
70130e
+    wl_callback_destroy(callback);
70130e
+    xwl_input_init(xwl_screen);
70130e
+}
70130e
+
70130e
+static const struct wl_callback_listener delayed_init_listner = {
70130e
+	xwl_input_delayed_init
70130e
+};
70130e
+
70130e
+static void
70130e
+registry_global(void *data, struct wl_registry *registry, uint32_t id,
70130e
+	        const char *interface, uint32_t version)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+
70130e
+    if (strcmp (interface, "wl_compositor") == 0) {
70130e
+	xwl_screen->compositor =
70130e
+            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
70130e
+    } else if (strcmp(interface, "wl_shm") == 0) {
70130e
+        xwl_screen->shm =
70130e
+            wl_registry_bind(registry, id, &wl_shm_interface, 1);
70130e
+    }
70130e
+}
70130e
+
70130e
+static const struct wl_registry_listener registry_listener = {
70130e
+    registry_global,
70130e
+};
70130e
+
70130e
+static void
70130e
+wakeup_handler(pointer data, int err, pointer read_mask)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+    int ret;
70130e
+
70130e
+    if (err < 0)
70130e
+        return;
70130e
+
70130e
+    if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
70130e
+        return;
70130e
+
70130e
+    ret = wl_display_dispatch(xwl_screen->display);
70130e
+    if (ret == -1)
70130e
+        FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
70130e
+}
70130e
+
70130e
+static void
70130e
+block_handler(pointer data, struct timeval **tv, pointer read_mask)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen = data;
70130e
+    int ret;
70130e
+
70130e
+    ret = wl_display_dispatch_pending(xwl_screen->display);
70130e
+    if (ret == -1)
70130e
+	FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
70130e
+
70130e
+    ret = wl_display_flush(xwl_screen->display);
70130e
+    if (ret == -1)
70130e
+        FatalError("failed to write to XWayland fd: %s\n", strerror(errno));
70130e
+}
70130e
+
70130e
+int
70130e
+xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen)
70130e
+{
70130e
+    struct wl_callback *callback;
70130e
+
70130e
+    xwl_screen->screen = screen;
70130e
+
70130e
+    if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
70130e
+	return BadAlloc;
70130e
+
70130e
+    dixSetPrivate(&screen->devPrivates,
70130e
+		  &xwl_screen_private_key, xwl_screen);
70130e
+
70130e
+    xwl_screen_init_window(xwl_screen, screen);
70130e
+
70130e
+    xwl_screen_init_cursor(xwl_screen, screen);
70130e
+
70130e
+    AddGeneralSocket(xwl_screen->wayland_fd);
70130e
+    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
70130e
+
70130e
+    callback = wl_display_sync(xwl_screen->display);
70130e
+    wl_callback_add_listener(callback, &delayed_init_listner, xwl_screen);
70130e
+
70130e
+    return Success;
70130e
+}
70130e
+
70130e
+struct xwl_screen *
70130e
+xwl_screen_get(ScreenPtr screen)
70130e
+{
70130e
+    return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
70130e
+}
70130e
+
70130e
+static void
70130e
+xwayland_selection_callback(CallbackListPtr *callbacks,
70130e
+			    pointer data, pointer args)
70130e
+{
70130e
+    SelectionInfoRec *info = (SelectionInfoRec *) args;
70130e
+    Selection *selection = info->selection;
70130e
+
70130e
+    switch (info->kind) {
70130e
+    case SelectionSetOwner:
70130e
+	if (selection->selection == xdnd_atom) {
70130e
+	    if (selection->window != None)
70130e
+		ErrorF("client %p starts dnd\n", info->client);
70130e
+	    else
70130e
+		ErrorF("client %p stops dnd\n", info->client);
70130e
+	}
70130e
+	break;
70130e
+    case SelectionWindowDestroy:
70130e
+	ErrorF("selection window destroy\n");
70130e
+	break;
70130e
+    case SelectionClientClose:
70130e
+	ErrorF("selection client close\n");
70130e
+	break;
70130e
+    }
70130e
+}
70130e
+
70130e
+struct xwl_screen *
70130e
+xwl_screen_create(void)
70130e
+{
70130e
+    struct xwl_screen *xwl_screen;
70130e
+
70130e
+    xwl_screen = calloc(sizeof *xwl_screen, 1);
70130e
+    if (xwl_screen == NULL) {
70130e
+	ErrorF("calloc failed\n");
70130e
+	return NULL;
70130e
+    }
70130e
+
70130e
+    xwl_screen->display = wl_display_connect(NULL);
70130e
+    if (xwl_screen->display == NULL) {
70130e
+	ErrorF("wl_display_create failed\n");
70130e
+	return NULL;
70130e
+    }
70130e
+
70130e
+    return xwl_screen;
70130e
+}
70130e
+
70130e
+Bool
70130e
+xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
70130e
+		    uint32_t flags, struct xwl_driver *driver)
70130e
+{
70130e
+    int ret;
70130e
+
70130e
+    noScreenSaverExtension = TRUE;
70130e
+
70130e
+    xdnd_atom = MakeAtom("XdndSelection", 13, 1);
70130e
+    if (!AddCallback(&SelectionCallback,
70130e
+		     xwayland_selection_callback, xwl_screen)) {
70130e
+	return FALSE;
70130e
+    }
70130e
+
70130e
+    xorg_list_init(&xwl_screen->seat_list);
70130e
+    xorg_list_init(&xwl_screen->damage_window_list);
70130e
+    xorg_list_init(&xwl_screen->window_list);
70130e
+    xorg_list_init(&xwl_screen->authenticate_client_list);
70130e
+    xwl_screen->scrninfo = scrninfo;
70130e
+    xwl_screen->driver = driver;
70130e
+    xwl_screen->flags = flags;
70130e
+    xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
70130e
+
70130e
+    if (xorgRootless)
70130e
+	xwl_screen->flags |= XWL_FLAGS_ROOTLESS;
70130e
+
70130e
+    /* Set up listener so we'll catch all events. */
70130e
+    xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
70130e
+    wl_registry_add_listener(xwl_screen->registry, &registry_listener,
70130e
+                             xwl_screen);
70130e
+    ret = wl_display_roundtrip(xwl_screen->display);
70130e
+    if (ret == -1) {
70130e
+        xf86DrvMsg(scrninfo->scrnIndex, X_ERROR,
70130e
+                   "failed to dispatch Wayland events: %s\n", strerror(errno));
70130e
+        return FALSE;
70130e
+    }
70130e
+
70130e
+#ifdef WITH_LIBDRM
70130e
+    if (xwl_screen->driver->use_drm && !xwl_drm_initialised(xwl_screen))
70130e
+	if (xwl_drm_pre_init(xwl_screen) != Success)
70130e
+            return FALSE;
70130e
+#endif
70130e
+
70130e
+    xwayland_screen_preinit_output(xwl_screen, scrninfo);
70130e
+
70130e
+    return TRUE;
70130e
+}
70130e
+
70130e
+int
70130e
+xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
70130e
+			     PixmapPtr pixmap, int fd)
70130e
+{
70130e
+    struct wl_shm_pool *pool;
70130e
+    int size, stride;
70130e
+
70130e
+    stride = pixmap->drawable.width * 4;
70130e
+
70130e
+    size = pixmap->drawable.width * pixmap->drawable.height * 4;
70130e
+    pool = wl_shm_create_pool(xwl_window->xwl_screen->shm, fd, size);
70130e
+    xwl_window->buffer =  wl_shm_pool_create_buffer(pool, 0,
70130e
+			   pixmap->drawable.width,
70130e
+			   pixmap->drawable.height,
70130e
+			   stride, WL_SHM_FORMAT_ARGB8888);
70130e
+    wl_shm_pool_destroy(pool);
70130e
+
70130e
+    return xwl_window->buffer ? Success : BadDrawable;
70130e
+}
70130e
+
70130e
+void xwl_screen_close(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    struct xwl_seat *xwl_seat, *itmp;
70130e
+    struct xwl_window *xwl_window, *wtmp;
70130e
+
70130e
+    if (xwl_screen->registry)
70130e
+        wl_registry_destroy(xwl_screen->registry);
70130e
+    xwl_screen->registry = NULL;
70130e
+
70130e
+    xorg_list_for_each_entry_safe(xwl_seat, itmp,
70130e
+				  &xwl_screen->seat_list, link) {
70130e
+	wl_seat_destroy(xwl_seat->seat);
70130e
+	free(xwl_seat);
70130e
+    }
70130e
+    xorg_list_for_each_entry_safe(xwl_window, wtmp,
70130e
+				  &xwl_screen->window_list, link) {
70130e
+	wl_buffer_destroy(xwl_window->buffer);
70130e
+	wl_surface_destroy(xwl_window->surface);
70130e
+	free(xwl_window);
70130e
+    }
70130e
+
70130e
+    xorg_list_init(&xwl_screen->seat_list);
70130e
+    xorg_list_init(&xwl_screen->damage_window_list);
70130e
+    xorg_list_init(&xwl_screen->window_list);
70130e
+    xorg_list_init(&xwl_screen->authenticate_client_list);
70130e
+
70130e
+    wl_display_roundtrip(xwl_screen->display);
70130e
+}
70130e
+
70130e
+void xwl_screen_destroy(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    if (xwl_screen->xwl_output) {
70130e
+	xf86OutputDestroy(xwl_screen->xwl_output->xf86output);
70130e
+	xf86CrtcDestroy(xwl_screen->xwl_output->xf86crtc);
70130e
+    }
70130e
+
70130e
+    free(xwl_screen->xwl_output);
70130e
+    free(xwl_screen);
70130e
+}
70130e
+
70130e
+/* DDX driver must call this after submitting the rendering */
70130e
+void xwl_screen_post_damage(struct xwl_screen *xwl_screen)
70130e
+{
70130e
+    struct xwl_window *xwl_window;
70130e
+    RegionPtr region;
70130e
+    BoxPtr box;
70130e
+    int count, i;
70130e
+
70130e
+    xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
70130e
+			     link_damage) {
70130e
+
70130e
+	region = DamageRegion(xwl_window->damage);
70130e
+	count = RegionNumRects(region);
70130e
+	for (i = 0; i < count; i++) {
70130e
+	    box = &RegionRects(region)[i];
70130e
+	    wl_surface_damage(xwl_window->surface,
70130e
+			      box->x1, box->y1,
70130e
+			      box->x2 - box->x1 + 1,
70130e
+			      box->y2 - box->y1 + 1);
70130e
+	}
70130e
+	wl_surface_attach(xwl_window->surface,
70130e
+			  xwl_window->buffer,
70130e
+			  0, 0);
70130e
+	wl_surface_commit(xwl_window->surface);
70130e
+	DamageEmpty(xwl_window->damage);
70130e
+    }
70130e
+
70130e
+    xorg_list_init(&xwl_screen->damage_window_list);
70130e
+}
70130e
+
70130e
+static pointer
70130e
+xwl_setup(pointer module, pointer opts, int *errmaj, int *errmin)
70130e
+{
70130e
+    return xwl_input_setup(module, opts, errmaj, errmin);
70130e
+}
70130e
+
70130e
+static void
70130e
+xwl_teardown(pointer p)
70130e
+{
70130e
+    xwl_input_teardown(p);
70130e
+}
70130e
+
70130e
+static XF86ModuleVersionInfo xwl_version_info = {
70130e
+    "xwayland",
70130e
+    MODULEVENDORSTRING,
70130e
+    MODINFOSTRING1,
70130e
+    MODINFOSTRING2,
70130e
+    XORG_VERSION_CURRENT,
70130e
+    1, 0, 0,
70130e
+    ABI_CLASS_EXTENSION,
70130e
+    ABI_EXTENSION_VERSION,
70130e
+    MOD_CLASS_NONE,
70130e
+    { 0, 0, 0, 0 }
70130e
+};
70130e
+
70130e
+_X_EXPORT const XF86ModuleData xwaylandModuleData = {
70130e
+    &xwl_version_info,
70130e
+    &xwl_setup,
70130e
+    &xwl_teardown
70130e
+};
70130e
+
70130e
+int
70130e
+xwl_version(void)
70130e
+{
70130e
+    return xwl_version_info.minorversion;
70130e
+}
70130e
diff --git a/hw/xfree86/xwayland/xwayland.h b/hw/xfree86/xwayland/xwayland.h
70130e
new file mode 100644
70130e
index 0000000..f268366
70130e
--- /dev/null
70130e
+++ b/hw/xfree86/xwayland/xwayland.h
70130e
@@ -0,0 +1,83 @@
70130e
+/*
70130e
+ * Copyright © 2008 Kristian Høgsberg
70130e
+ *
70130e
+ * Permission to use, copy, modify, distribute, and sell this software
70130e
+ * and its documentation for any purpose is hereby granted without
70130e
+ * fee, provided that the above copyright notice appear in all copies
70130e
+ * and that both that copyright notice and this permission notice
70130e
+ * appear in supporting documentation, and that the name of the
70130e
+ * copyright holders not be used in advertising or publicity
70130e
+ * pertaining to distribution of the software without specific,
70130e
+ * written prior permission.  The copyright holders make no
70130e
+ * representations about the suitability of this software for any
70130e
+ * purpose.  It is provided "as is" without express or implied
70130e
+ * warranty.
70130e
+ *
70130e
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
70130e
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
70130e
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
70130e
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
70130e
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
70130e
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
70130e
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70130e
+ * SOFTWARE.
70130e
+ */
70130e
+
70130e
+#ifndef _XWAYLAND_H_
70130e
+#define _XWAYLAND_H_
70130e
+
70130e
+#define XWL_VERSION 2
70130e
+
70130e
+struct xwl_window;
70130e
+struct xwl_screen;
70130e
+
70130e
+struct xwl_driver {
70130e
+    int version;
70130e
+    int use_drm;
70130e
+    int (*create_window_buffer)(struct xwl_window *xwl_window,
70130e
+                                PixmapPtr pixmap);
70130e
+};
70130e
+
70130e
+#define XWL_FLAGS_ROOTLESS 0x01
70130e
+
70130e
+extern _X_EXPORT int
70130e
+xwl_version(void);
70130e
+
70130e
+extern _X_EXPORT struct xwl_screen *
70130e
+xwl_screen_create(void);
70130e
+
70130e
+extern _X_EXPORT Bool
70130e
+xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
70130e
+		    uint32_t flags, struct xwl_driver *driver);
70130e
+
70130e
+extern _X_EXPORT int
70130e
+xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen);
70130e
+
70130e
+extern _X_EXPORT int
70130e
+xwl_drm_pre_init(struct xwl_screen *xwl_screen);
70130e
+
70130e
+extern _X_EXPORT int
70130e
+xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen);
70130e
+
70130e
+extern _X_EXPORT void
70130e
+xwl_screen_close(struct xwl_screen *xwl_screen);
70130e
+
70130e
+extern _X_EXPORT void
70130e
+xwl_screen_destroy(struct xwl_screen *xwl_screen);
70130e
+
70130e
+extern _X_EXPORT void
70130e
+xwl_screen_post_damage(struct xwl_screen *xwl_screen);
70130e
+
70130e
+extern _X_EXPORT int
70130e
+xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
70130e
+		     uint32_t magic);
70130e
+
70130e
+extern _X_EXPORT int
70130e
+xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
70130e
+			     PixmapPtr pixmap, uint32_t name);
70130e
+
70130e
+extern _X_EXPORT int
70130e
+xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
70130e
+			     PixmapPtr pixmap, int fd);
70130e
+
70130e
+#endif /* _XWAYLAND_H_ */
70130e
diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in
70130e
index 960817e..ec43ff7 100644
70130e
--- a/include/xorg-server.h.in
70130e
+++ b/include/xorg-server.h.in
70130e
@@ -221,4 +221,7 @@
70130e
 /* Have support for X shared memory fence library (xshmfence) */
70130e
 #undef HAVE_XSHMFENCE
70130e
 
70130e
+/* Building Xorg server. */
70130e
+#undef XORG_WAYLAND
70130e
+
70130e
 #endif /* _XORG_SERVER_H_ */
70130e
-- 
70130e
1.8.3.1
70130e