xserver: Branch 'xwayland' - 9 commits

Kristian Høgsberg krh at kemper.freedesktop.org
Fri Mar 7 17:02:37 PST 2014


Rebased ref, commits from common ancestor:
commit 0c14bdb995f5aa9559ca7bf6a03e6ba52854cff1
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Sep 18 22:08:16 2009 -0400

    Add xwayland module
    
    Squashed and rebased from the xwayland-1.12 branch.  Contributions from
    
      Christopher James Halse Rogers <christopher.halse.rogers at canonical.com>
      Corentin Chary <corentin.chary at gmail.com>
      Daniel Stone <daniel at fooishbar.org>
      Kristian Høgsberg <krh at bitplanet.net>
      Robert Bragg <robert at linux.intel.com>
      Scott Moreau <oreaus at gmail.com>
      Tiago Vignatti <tiago.vignatti at intel.com>
      Giovanni Campagna <gcampagn at redhat.com>
      Jonas Ã…dahl <jadahl at gmail.com>
      Ray Strode <rstrode at redhat.com>
      Trevor McCort <tjmccort at gmail.com>
      Rui Matos <tiagomatos at gmail.com>

diff --git a/configure.ac b/configure.ac
index 74819bf..6d412f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -626,6 +626,7 @@ AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg
 AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])
 AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])
 AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])
+AC_ARG_ENABLE(wayland,      AS_HELP_STRING([--disable-wayland], [Build Wayland extension (default: auto)]), [WAYLAND=$enableval], [WAYLAND=auto])
 
 dnl DDXes.
 AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
@@ -1019,6 +1020,18 @@ fi
 if test "x$MITSHM" = xauto; then
 	MITSHM="$ac_cv_sysv_ipc"
 fi
+
+WAYLAND_MODULES="wayland-client libdrm"
+if test "x$WAYLAND" = xauto; then
+        PKG_CHECK_MODULES(XWAYLAND, $WAYLAND_MODULES, [WAYLAND=yes], [WAYLAND=no])
+fi
+if test "x$WAYLAND" = xyes; then
+        PKG_CHECK_MODULES(XWAYLAND, $WAYLAND_MODULES)
+	AC_DEFINE(XORG_WAYLAND, 1, [Support wayland mode])
+	WAYLAND_SCANNER_RULES(['$(top_srcdir)/hw/xfree86/xwayland'])
+fi
+AM_CONDITIONAL(WAYLAND, [test "x$WAYLAND" = xyes])
+
 AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes])
 if test "x$MITSHM" = xyes; then
 	AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension])
@@ -1248,6 +1261,7 @@ if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$DRI3" = xyes || test "
 		PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
 	fi
 fi
+AM_CONDITIONAL(DRM, test "x$DRM" = xyes)
 
 if test "x$DRI2" = xyes; then
 	save_CFLAGS=$CFLAGS
@@ -2485,6 +2499,7 @@ hw/xfree86/dixmods/Makefile
 hw/xfree86/doc/Makefile
 hw/xfree86/dri/Makefile
 hw/xfree86/dri2/Makefile
+hw/xfree86/xwayland/Makefile
 hw/xfree86/exa/Makefile
 hw/xfree86/exa/man/Makefile
 hw/xfree86/fbdevhw/Makefile
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 73e1b4c..9c82ffd 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -14,10 +14,15 @@ DRI3_BUILDDIR = $(top_builddir)/dri3
 DRI3_LIB = $(DRI3_BUILDDIR)/libdri3.la
 endif
 
+
 if GLAMOR_EGL
 GLAMOR_EGL_SUBDIR = glamor_egl
 endif
 
+if WAYLAND
+WAYLAND_SUBDIR = xwayland
+endif
+
 if XF86UTILS
 XF86UTILS_SUBDIR = utils
 endif
@@ -36,13 +41,13 @@ endif
 
 SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \
 	  ramdac $(VGAHW_SUBDIR) loader modes $(DRI_SUBDIR) \
-	  $(DRI2_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
+	  $(DRI2_SUBDIR) $(WAYLAND_SUBDIR) . $(VBE_SUBDIR) i2c dixmods \
 	  fbdevhw shadowfb exa $(XF86UTILS_SUBDIR) doc man \
 	  $(GLAMOR_EGL_SUBDIR)
 
 DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
                parser ramdac shadowfb vbe vgahw \
-               loader dixmods dri dri2 exa modes \
+               loader dixmods dri dri2 exa modes xwayland \
 	       utils doc man
 
 bin_PROGRAMS = Xorg
diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c
index 4eb86de..47ef684 100644
--- a/hw/xfree86/common/xf86AutoConfig.c
+++ b/hw/xfree86/common/xf86AutoConfig.c
@@ -274,11 +274,17 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
 
 #if !defined(sun)
     /* Fallback to platform default frame buffer driver */
-    if (i < (nmatches - 1)) {
+    if (i < (nmatches - 2)) {
+#ifdef XORG_WAYLAND
+        if (xorgWayland) {
+            matches[i++] = xnfstrdup("wlglamor");
+            matches[i++] = xnfstrdup("wayland");
+        } else
+#endif
 #if !defined(__linux__) && defined(__sparc__)
-        matches[i++] = xnfstrdup("wsfb");
+            matches[i++] = xnfstrdup("wsfb");
 #else
-        matches[i++] = xnfstrdup("fbdev");
+            matches[i++] = xnfstrdup("fbdev");
 #endif
     }
 #endif                          /* !sun */
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 542d5ab..7eb8b1b 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -118,7 +118,8 @@ static ModuleDefault ModuleDefaults[] = {
     {.name = "fb",.toLoad = TRUE,.load_opt = NULL},
     {.name = "shadow",.toLoad = TRUE,.load_opt = NULL},
 #endif
-    {.name = NULL,.toLoad = FALSE,.load_opt = NULL}
+    {.name = "xwayland",.toLoad = FALSE,.load_opt=NULL},
+    {.name = NULL,.toLoad = FALSE,.load_opt=NULL}
 };
 
 /* Forward declarations */
@@ -260,6 +261,17 @@ xf86ModulelistFromConfig(void ***optlist)
         return NULL;
     }
 
+    /*
+     * Set the xwayland module to autoload if requested.
+     */
+    if (xorgWayland) {
+        for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+            if (strcmp(ModuleDefaults[i].name, "xwayland") == 0) {
+                ModuleDefaults[i].toLoad = TRUE;
+            }
+        }
+    }
+
     if (xf86configptr->conf_modules) {
         /* Walk the disable list and let people know what we've parsed to
          * not be loaded 
@@ -507,9 +519,13 @@ xf86InputDriverlistFromConfig(void)
 static void
 fixup_video_driver_list(const char **drivers)
 {
-    static const char *fallback[4] = { "fbdev", "vesa", "wsfb", NULL };
+    static const char *fallback_hw[4] = { "fbdev", "vesa", "wsfb", NULL };
     const char **end, **drv;
     const char *x;
+#ifdef XORG_WAYLAND
+    static const char *fallback_wl[2] = { "wayland", NULL };
+#endif
+    static const char **fallbacks;
     int i;
 
     /* walk to the end of the list */
@@ -520,9 +536,15 @@ fixup_video_driver_list(const char **drivers)
      * for each of the fallback drivers, if we find it in the list,
      * swap it with the last available non-fallback driver.
      */
-    for (i = 0; fallback[i]; i++) {
+#ifdef XORG_WAYLAND
+    if (xorgWayland)
+        fallbacks = fallback_wl;
+    else
+#endif
+        fallbacks = fallback_hw;
+    for (i = 0; fallbacks[i]; i++) {
         for (drv = drivers; drv != end; drv++) {
-            if (strstr(*drv, fallback[i])) {
+            if (strstr(*drv, fallbacks[i])) {
                 x = *drv;
                 *drv = *end;
                 *end = x;
@@ -859,6 +881,13 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     }
     xf86Msg(from, "%sutomatically adding GPU devices\n",
             xf86Info.autoAddGPU ? "A" : "Not a");
+
+    /* FIXME: Do that at the right place (before xf86Msg). */
+    if (xorgWayland) {
+            xf86Info.autoAddDevices = FALSE;
+            xf86Info.autoEnableDevices = FALSE;
+    }
+
     /*
      * Set things up based on the config file information.  Some of these
      * settings may be overridden later when the command line options are
@@ -949,9 +978,10 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     }
 #endif
 
-    /* if we're not hotplugging, force some input devices to exist */
-    xf86Info.forceInputDevices = !(xf86Info.autoAddDevices &&
-                                   xf86Info.autoEnableDevices);
+    if (xorgWayland) /* Don't force input devices */
+	xf86Info.forceInputDevices = FALSE;
+    else /* if we're not hotplugging, force some input devices to exist */
+	xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
 
     /* when forcing input devices, we use kbd. otherwise evdev, so use the
      * evdev rules set. */
diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 7df7a80..b41d2cc 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -204,3 +204,5 @@ Bool xf86VidModeAllowNonLocal = FALSE;
 #endif
 RootWinPropPtr *xf86RegisteredPropertiesTable = NULL;
 Bool xorgHWAccess = FALSE;
+Bool xorgWayland = FALSE;
+Bool xorgRootless = FALSE;
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index ff4d38f..919d35f 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -550,6 +550,25 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             /* Non-seat0 X servers should not open console */
             if (!(flags & HW_SKIP_CONSOLE) && !ServerIsNotSeat0())
                 xorgHWOpenConsole = TRUE;
+
+	    if (xorgWayland) {
+                if (flags != HW_WAYLAND) {
+                    xf86DeleteDriver(i);
+                    continue;
+                }
+
+                want_hw_access = FALSE;
+                xorgHWOpenConsole = FALSE;
+	    }
+        }
+
+        for (i = 0; i < xf86NumDrivers; i++) {
+                if (xf86DriverList[i] == NULL) {
+                        for (j = i; j < xf86NumDrivers; j++) {
+                            xf86DriverList[j] = xf86DriverList[j + 1];
+                        }
+                        xf86NumDrivers--;
+                }
         }
 
         if (xorgHWOpenConsole)
@@ -963,6 +982,9 @@ InitInput(int argc, char **argv)
 
     mieqInit();
 
+    if (xorgWayland)
+	return;
+
     /* Initialize all configured input devices */
     for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
         (*pInfo)->options =
@@ -1463,6 +1485,16 @@ ddxProcessArgument(int argc, char **argv, int i)
         return 1;
     }
 
+    if (!strcmp(argv[i], "-wayland")) {
+        xorgWayland = TRUE;
+        return 1;
+    }
+
+    if (!strcmp(argv[i], "-rootless")) {
+        xorgRootless = TRUE;
+        return 1;
+    }
+
     /* OS-specific processing */
     return xf86ProcessArgument(argc, argv, i);
 }
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 6e374eb..f843765 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -91,6 +91,8 @@ extern _X_EXPORT int xf86NumScreens;
 extern _X_EXPORT const char *xf86VisualNames[];
 extern _X_EXPORT int xf86Verbose;       /* verbosity level */
 extern _X_EXPORT int xf86LogVerbose;    /* log file verbosity level */
+extern _X_EXPORT Bool xorgWayland;
+extern _X_EXPORT Bool xorgRootless;
 
 extern _X_EXPORT RootWinPropPtr *xf86RegisteredPropertiesTable;
 
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index b164b7f..676f9d8 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -288,6 +288,7 @@ typedef struct {
 #define HW_MMIO 2
 #define HW_SKIP_CONSOLE 4
 #define NEED_IO_ENABLED(x) (x & HW_IO)
+#define HW_WAYLAND 8
 
 typedef CARD32 xorgHWFlags;
 
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index c70f72e..3d40138 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -1332,13 +1332,16 @@ DRI2Connect(ClientPtr client, ScreenPtr pScreen,
 }
 
 static int
-DRI2AuthMagic (ScreenPtr pScreen, uint32_t magic)
+DRI2AuthMagic (ClientPtr client, ScreenPtr pScreen, uint32_t magic)
 {
     DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
     if (ds == NULL)
         return -EINVAL;
 
-    return (*ds->LegacyAuthMagic) (ds->fd, magic);
+    if (ds->LegacyAuthMagic2)
+        return (*ds->LegacyAuthMagic2) (pScreen, magic);
+    else
+        return (*ds->LegacyAuthMagic) (ds->fd, magic);
 }
 
 Bool
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 38b4f58..ed67d01 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -207,7 +207,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client,
 /**
  * Version of the DRI2InfoRec structure defined in this header
  */
-#define DRI2INFOREC_VERSION 9
+#define DRI2INFOREC_VERSION 10
 
 typedef struct {
     unsigned int version;       /**< Version of this struct */
diff --git a/hw/xfree86/xwayland/.gitignore b/hw/xfree86/xwayland/.gitignore
new file mode 100644
index 0000000..abedfee
--- /dev/null
+++ b/hw/xfree86/xwayland/.gitignore
@@ -0,0 +1,4 @@
+drm-client-protocol.h
+drm-protocol.c
+xserver-client-protocol.h
+xserver-protocol.c
diff --git a/hw/xfree86/xwayland/Makefile.am b/hw/xfree86/xwayland/Makefile.am
new file mode 100644
index 0000000..22ab154
--- /dev/null
+++ b/hw/xfree86/xwayland/Makefile.am
@@ -0,0 +1,46 @@
+AM_CPPFLAGS =					\
+	$(XORG_INCS)				\
+	-I$(srcdir)/../ddc			\
+	-I$(srcdir)/../ramdac			\
+	-I$(srcdir)/../i2c			\
+	-I$(srcdir)/../parser			\
+	-I$(srcdir)/../modes
+
+libxwayland_la_LTLIBRARIES = libxwayland.la
+AM_CFLAGS = \
+	-DHAVE_XORG_CONFIG_H \
+	@DIX_CFLAGS@ @XORG_CFLAGS@ @XWAYLAND_CFLAGS@ \
+	-I$(top_srcdir)/hw/xfree86/common \
+	-I$(top_srcdir)/hw/xfree86/os-support/bus
+
+libxwayland_la_LDFLAGS = -module -avoid-version @XWAYLAND_LIBS@
+libxwayland_ladir = $(moduledir)/extensions
+libxwayland_la_SOURCES =			\
+	xwayland.c				\
+	xwayland-input.c			\
+	xwayland-output.c			\
+	xwayland-cursor.c			\
+	xwayland-window.c			\
+	xwayland-private.h			\
+	drm-client-protocol.h			\
+	drm-protocol.c				\
+	xserver-client-protocol.h		\
+	xserver-protocol.c
+
+if DRM
+AM_CFLAGS += @LIBDRM_CFLAGS@
+libxwayland_la_LDFLAGS += @LIBDRM_LIBS@
+libxwayland_la_SOURCES += xwayland-drm.c
+endif
+
+sdk_HEADERS = xwayland.h
+
+BUILT_SOURCES =					\
+	drm-client-protocol.h			\
+	drm-protocol.c				\
+	xserver-client-protocol.h		\
+	xserver-protocol.c
+
+CLEANFILES = $(BUILT_SOURCES)
+
+ at wayland_scanner_rules@
diff --git a/hw/xfree86/xwayland/drm.xml b/hw/xfree86/xwayland/drm.xml
new file mode 100644
index 0000000..89fd8f0
--- /dev/null
+++ b/hw/xfree86/xwayland/drm.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="drm">
+
+  <copyright>
+    Copyright © 2008-2011 Kristian Høgsberg
+    Copyright © 2010-2011 Intel Corporation
+
+    Permission to use, copy, modify, distribute, and sell this
+    software and its documentation for any purpose is hereby granted
+    without fee, provided that\n the above copyright notice appear in
+    all copies and that both that copyright notice and this permission
+    notice appear in supporting documentation, and that the name of
+    the copyright holders not be used in advertising or publicity
+    pertaining to distribution of the software without specific,
+    written prior permission.  The copyright holders make no
+    representations about the suitability of this software for any
+    purpose.  It is provided "as is" without express or implied
+    warranty.
+
+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+    THIS SOFTWARE.
+  </copyright>
+
+  <!-- drm support. This object is created by the server and published
+       using the display's global event. -->
+  <interface name="wl_drm" version="1">
+    <enum name="error">
+      <entry name="authenticate_fail" value="0"/>
+      <entry name="invalid_format" value="1"/>
+      <entry name="invalid_name" value="2"/>
+    </enum>
+
+    <enum name="format">
+      <!-- The drm format codes match the #defines in drm_fourcc.h.
+           The formats actually supported by the compositor will be
+           reported by the format event. -->
+      <entry name="c8" value="0x20203843"/>
+      <entry name="rgb332" value="0x38424752"/>
+      <entry name="bgr233" value="0x38524742"/>
+      <entry name="xrgb4444" value="0x32315258"/>
+      <entry name="xbgr4444" value="0x32314258"/>
+      <entry name="rgbx4444" value="0x32315852"/>
+      <entry name="bgrx4444" value="0x32315842"/>
+      <entry name="argb4444" value="0x32315241"/>
+      <entry name="abgr4444" value="0x32314241"/>
+      <entry name="rgba4444" value="0x32314152"/>
+      <entry name="bgra4444" value="0x32314142"/>
+      <entry name="xrgb1555" value="0x35315258"/>
+      <entry name="xbgr1555" value="0x35314258"/>
+      <entry name="rgbx5551" value="0x35315852"/>
+      <entry name="bgrx5551" value="0x35315842"/>
+      <entry name="argb1555" value="0x35315241"/>
+      <entry name="abgr1555" value="0x35314241"/>
+      <entry name="rgba5551" value="0x35314152"/>
+      <entry name="bgra5551" value="0x35314142"/>
+      <entry name="rgb565" value="0x36314752"/>
+      <entry name="bgr565" value="0x36314742"/>
+      <entry name="rgb888" value="0x34324752"/>
+      <entry name="bgr888" value="0x34324742"/>
+      <entry name="xrgb8888" value="0x34325258"/>
+      <entry name="xbgr8888" value="0x34324258"/>
+      <entry name="rgbx8888" value="0x34325852"/>
+      <entry name="bgrx8888" value="0x34325842"/>
+      <entry name="argb8888" value="0x34325241"/>
+      <entry name="abgr8888" value="0x34324241"/>
+      <entry name="rgba8888" value="0x34324152"/>
+      <entry name="bgra8888" value="0x34324142"/>
+      <entry name="xrgb2101010" value="0x30335258"/>
+      <entry name="xbgr2101010" value="0x30334258"/>
+      <entry name="rgbx1010102" value="0x30335852"/>
+      <entry name="bgrx1010102" value="0x30335842"/>
+      <entry name="argb2101010" value="0x30335241"/>
+      <entry name="abgr2101010" value="0x30334241"/>
+      <entry name="rgba1010102" value="0x30334152"/>
+      <entry name="bgra1010102" value="0x30334142"/>
+      <entry name="yuyv" value="0x56595559"/>
+      <entry name="yvyu" value="0x55595659"/>
+      <entry name="uyvy" value="0x59565955"/>
+      <entry name="vyuy" value="0x59555956"/>
+      <entry name="ayuv" value="0x56555941"/>
+      <entry name="nv12" value="0x3231564e"/>
+      <entry name="nv21" value="0x3132564e"/>
+      <entry name="nv16" value="0x3631564e"/>
+      <entry name="nv61" value="0x3136564e"/>
+      <entry name="yuv410" value="0x39565559"/>
+      <entry name="yvu410" value="0x39555659"/>
+      <entry name="yuv411" value="0x31315559"/>
+      <entry name="yvu411" value="0x31315659"/>
+      <entry name="yuv420" value="0x32315559"/>
+      <entry name="yvu420" value="0x32315659"/>
+      <entry name="yuv422" value="0x36315559"/>
+      <entry name="yvu422" value="0x36315659"/>
+      <entry name="yuv444" value="0x34325559"/>
+      <entry name="yvu444" value="0x34325659"/>
+    </enum>
+
+    <!-- Call this request with the magic received from drmGetMagic().
+         It will be passed on to the drmAuthMagic() or
+         DRIAuthConnection() call.  This authentication must be
+         completed before create_buffer could be used. -->
+    <request name="authenticate">
+      <arg name="id" type="uint"/>
+    </request>
+
+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
+         surface must have a name using the flink ioctl -->
+    <request name="create_buffer">
+      <arg name="id" type="new_id" interface="wl_buffer"/>
+      <arg name="name" type="uint"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="stride" type="uint"/>
+      <arg name="format" type="uint"/>
+    </request>
+
+    <!-- Notification of the path of the drm device which is used by
+         the server.  The client should use this device for creating
+         local buffers.  Only buffers created from this device should
+         be be passed to the server using this drm object's
+         create_buffer request. -->
+    <event name="device">
+      <arg name="name" type="string"/>
+    </event>
+
+    <event name="format">
+      <arg name="format" type="uint"/>
+    </event>
+
+    <!-- Raised if the authenticate request succeeded -->
+    <event name="authenticated"/>
+  </interface>
+
+</protocol>
diff --git a/hw/xfree86/xwayland/xserver.xml b/hw/xfree86/xwayland/xserver.xml
new file mode 100644
index 0000000..9e25f5c
--- /dev/null
+++ b/hw/xfree86/xwayland/xserver.xml
@@ -0,0 +1,18 @@
+<protocol name="xserver">
+
+  <interface name="xserver" version="1">
+    <request name="set_window_id">
+      <arg name="surface" type="object" interface="wl_surface"/>
+      <arg name="id" type="uint"/>
+    </request>
+
+    <event name="client">
+      <arg name="fd" type="fd"/>
+    </event>
+
+    <event name="listen_socket">
+      <arg name="fd" type="fd"/>
+    </event>
+  </interface>
+
+</protocol>
diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c
new file mode 100644
index 0000000..2b3cb5e
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-cursor.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2011 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <wayland-client.h>
+
+#include <cursorstr.h>
+#include <xf86Crtc.h>
+#include <mipointrst.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static void
+expand_source_and_mask(CursorPtr cursor, void *data)
+{
+    CARD32 *argb, *p, d, fg, bg;
+    CursorBitsPtr bits = cursor->bits;
+    int size;
+    int x, y, stride, i, bit;
+
+    size = bits->width * bits->height * 4;
+    argb = malloc(size);
+    if (argb == NULL)
+	return;
+
+    p = argb;
+    fg = ((cursor->foreRed & 0xff00) << 8) |
+	(cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8);
+    bg = ((cursor->backRed & 0xff00) << 8) |
+	(cursor->backGreen & 0xff00) | (cursor->backGreen >> 8);
+    stride = (bits->width / 8 + 3) & ~3;
+    for (y = 0; y < bits->height; y++)
+	for (x = 0; x < bits->width; x++) {
+	    i = y * stride + x / 8;
+	    bit = 1 << (x & 7);
+	    if (bits->source[i] & bit)
+		d = fg;
+	    else
+		d = bg;
+	    if (bits->mask[i] & bit)
+		d |= 0xff000000;
+	    else
+		d = 0x00000000;
+
+	    *p++ = d;
+	}
+
+    memcpy(data, argb, size);
+    free(argb);
+}
+
+static Bool
+xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor)
+{
+    struct xwl_screen *xwl_screen;
+    int size;
+    char filename[] = "/tmp/wayland-shm-XXXXXX";
+    int fd;
+    struct wl_shm_pool *pool;
+    struct wl_buffer *buffer;
+    void *data;
+
+    xwl_screen = xwl_screen_get(screen);
+    size = cursor->bits->width * cursor->bits->height * 4;
+
+    fd = mkstemp(filename);
+    if (fd < 0) {
+	ErrorF("open %s failed: %s", filename, strerror(errno));
+	return FALSE;
+    }
+    if (ftruncate(fd, size) < 0) {
+	ErrorF("ftruncate failed: %s", strerror(errno));
+	close(fd);
+	return FALSE;
+    }
+
+    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    unlink(filename);
+
+    if (data == MAP_FAILED) {
+	ErrorF("mmap failed: %s", strerror(errno));
+	close(fd);
+	return FALSE;
+    }
+
+    if (cursor->bits->argb)
+	memcpy(data, cursor->bits->argb, size);
+    else
+	expand_source_and_mask(cursor, data);
+    munmap(data, size);
+
+    pool = wl_shm_create_pool(xwl_screen->shm, fd, size);
+    close(fd);
+    buffer = wl_shm_pool_create_buffer(pool, 0,
+				  cursor->bits->width, cursor->bits->height,
+				  cursor->bits->width * 4,
+				  WL_SHM_FORMAT_ARGB8888);
+    wl_shm_pool_destroy(pool);
+
+    dixSetPrivate(&cursor->devPrivates,
+                  &xwl_screen->cursor_private_key, buffer);
+
+    return TRUE;
+}
+
+static Bool
+xwl_unrealize_cursor(DeviceIntPtr device,
+			ScreenPtr screen, CursorPtr cursor)
+{
+    struct wl_buffer *buffer;
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = xwl_screen_get(screen);
+    buffer = dixGetPrivate(&cursor->devPrivates,
+                           &xwl_screen->cursor_private_key);
+    wl_buffer_destroy(buffer);
+
+    return TRUE;
+}
+
+void
+xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
+{
+    struct wl_buffer *buffer;
+
+    if (!xwl_seat->wl_pointer)
+        return;
+
+    if (!xwl_seat->x_cursor) {
+        wl_pointer_set_cursor(xwl_seat->wl_pointer,
+                              xwl_seat->pointer_enter_serial,
+                              NULL, 0, 0);
+        return;
+    }
+
+    buffer = dixGetPrivate(&xwl_seat->x_cursor->devPrivates,
+                           &xwl_seat->xwl_screen->cursor_private_key);
+
+    wl_pointer_set_cursor(xwl_seat->wl_pointer,
+			  xwl_seat->pointer_enter_serial,
+			  xwl_seat->cursor,
+			  xwl_seat->x_cursor->bits->xhot,
+			  xwl_seat->x_cursor->bits->yhot);
+    wl_surface_attach(xwl_seat->cursor, buffer, 0, 0);
+    wl_surface_damage(xwl_seat->cursor, 0, 0,
+		      xwl_seat->x_cursor->bits->width,
+		      xwl_seat->x_cursor->bits->height);
+    wl_surface_commit(xwl_seat->cursor);
+}
+
+static void
+xwl_set_cursor(DeviceIntPtr device,
+	       ScreenPtr screen, CursorPtr cursor, int x, int y)
+{
+    struct xwl_screen *xwl_screen;
+    struct xwl_seat *xwl_seat;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    if (!xwl_screen || xorg_list_is_empty(&xwl_screen->seat_list))
+	return;
+
+    xwl_seat = xorg_list_first_entry(&xwl_screen->seat_list,
+		                     struct xwl_seat, link);
+
+    xwl_seat->x_cursor = cursor;
+    xwl_seat_set_cursor(xwl_seat);
+}
+
+static void
+xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y)
+{
+}
+
+static Bool
+xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen)
+{
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    return xwl_screen->sprite_funcs->DeviceCursorInitialize(device,
+							       screen);
+}
+
+static void
+xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen)
+{
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    xwl_screen->sprite_funcs->DeviceCursorCleanup(device, screen);
+}
+
+static miPointerSpriteFuncRec xwl_pointer_sprite_funcs =
+{
+    xwl_realize_cursor,
+    xwl_unrealize_cursor,
+    xwl_set_cursor,
+    xwl_move_cursor,
+    xwl_device_cursor_initialize,
+    xwl_device_cursor_cleanup
+};
+
+int
+xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen)
+{
+    miPointerScreenPtr pointer_priv;
+
+    if (!dixRegisterPrivateKey(&xwl_screen->cursor_private_key,
+                               PRIVATE_CURSOR, 0))
+	return BadAlloc;
+
+    pointer_priv = dixLookupPrivate(&screen->devPrivates, miPointerScreenKey);
+    xwl_screen->sprite_funcs = pointer_priv->spriteFuncs;
+    pointer_priv->spriteFuncs = &xwl_pointer_sprite_funcs;
+
+    return Success;
+}
diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
new file mode 100644
index 0000000..5250857
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2011 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <xf86drm.h>
+#include <wayland-util.h>
+#include <wayland-client.h>
+#include <drm-client-protocol.h>
+
+#include <xf86Xinput.h>
+#include <xf86Crtc.h>
+#include <xf86str.h>
+#include <windowstr.h>
+#include <input.h>
+#include <inputstr.h>
+#include <exevents.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "../dri2/dri2.h"
+
+struct xwl_auth_req {
+    struct xorg_list link;
+
+    ClientPtr client;
+    struct xwl_screen *xwl_screen;
+    uint32_t magic;
+};
+
+static void
+drm_handle_device (void *data, struct wl_drm *drm, const char *device)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    xwl_screen->device_name = strdup (device);
+}
+
+static void
+drm_handle_format(void *data, struct wl_drm *wl_drm, uint32_t format)
+{
+}
+
+static void
+drm_handle_authenticated (void *data, struct wl_drm *drm)
+{
+    struct xwl_screen *xwl_screen = data;
+    struct xwl_auth_req *req;
+
+    xwl_screen->authenticated = 1;
+
+    /* it does one authentication transaction at a time, so if there's an
+     * element in the list, we call DRI2SendAuthReply for that client, remove
+     * the head and free the struct. If there are still elements in the list,
+     * it means that we have one or more clients waiting to be authenticated
+     * and we send out a wl_drm authenticate request for the first client in
+     * the list */
+    if (xorg_list_is_empty(&xwl_screen->authenticate_client_list))
+	return;
+
+    req = xorg_list_first_entry(&xwl_screen->authenticate_client_list,
+	                        struct xwl_auth_req, link);
+    DRI2SendAuthReply(req->client, TRUE);
+    AttendClient(req->client);
+    xorg_list_del(&req->link);
+    free(req);
+
+    xorg_list_for_each_entry(req, &xwl_screen->authenticate_client_list,
+	                     link) {
+	wl_drm_authenticate (xwl_screen->drm, req->magic);
+	return;
+    }
+}
+
+static const struct wl_drm_listener xwl_drm_listener =
+{
+    drm_handle_device,
+    drm_handle_format,
+    drm_handle_authenticated
+};
+
+static void
+drm_handler(void *data, struct wl_registry *registry, uint32_t id,
+	    const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    if (strcmp (interface, "wl_drm") == 0) {
+	xwl_screen->drm = wl_registry_bind(xwl_screen->registry, id,
+                                           &wl_drm_interface, 1);
+	wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
+    }
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    /* Nothing to do here, wl_drm should not be removed */
+}
+
+static const struct wl_registry_listener drm_listener = {
+    drm_handler,
+    global_remove
+};
+
+int
+xwl_drm_pre_init(struct xwl_screen *xwl_screen)
+{
+    uint32_t magic;
+
+    xwl_screen->drm_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->drm_registry, &drm_listener,
+                             xwl_screen);
+
+    /* Ensure drm_handler has seen all the interfaces */
+    wl_display_roundtrip(xwl_screen->display);
+    /* Ensure the xwl_drm_listener has seen the drm device, if any */
+    wl_display_roundtrip(xwl_screen->display);
+
+    ErrorF("wayland_drm_screen_init, device name %s\n",
+	   xwl_screen->device_name);
+
+    xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR);
+    if (xwl_screen->drm_fd < 0) {
+	ErrorF("failed to open the drm fd\n");
+	return BadAccess;
+    }
+
+    if (drmGetMagic(xwl_screen->drm_fd, &magic)) {
+	ErrorF("failed to get drm magic");
+	return BadAccess;
+    }
+
+    wl_drm_authenticate(xwl_screen->drm, magic);
+
+    wl_display_roundtrip(xwl_screen->display);
+
+    ErrorF("opened drm fd: %d\n", xwl_screen->drm_fd);
+
+    if (!xwl_screen->authenticated) {
+	ErrorF("Failed to auth drm fd\n");
+	return BadAccess;
+    }
+
+    return Success;
+}
+
+Bool xwl_drm_initialised(struct xwl_screen *xwl_screen)
+{
+    return xwl_screen->authenticated;
+}
+
+int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
+{
+    return xwl_screen->drm_fd;
+}
+
+int xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
+			    uint32_t magic)
+{
+    struct xwl_auth_req *req;
+
+    if (!xwl_screen->drm)
+	return BadAccess;
+
+    req = malloc (sizeof *req);
+    if (req == NULL)
+	return BadAlloc;
+
+    req->client = client;
+    req->xwl_screen = xwl_screen;
+    req->magic = magic;
+
+    if (xorg_list_is_empty(&xwl_screen->authenticate_client_list))
+	wl_drm_authenticate (xwl_screen->drm, magic);
+
+    xorg_list_append(&req->link, &xwl_screen->authenticate_client_list);
+
+    IgnoreClient(req->client);
+    xwl_screen->authenticated = 0;
+
+    return Success;
+}
+
+
+int
+xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, uint32_t name)
+{
+    VisualID visual;
+    WindowPtr window = xwl_window->window;
+    ScreenPtr screen = window->drawable.pScreen;
+    uint32_t format;
+    int i;
+
+    visual = wVisual(window);
+    for (i = 0; i < screen->numVisuals; i++)
+	if (screen->visuals[i].vid == visual)
+	    break;
+
+    switch (screen->visuals[i].nplanes) {
+    case 32:
+	format = WL_DRM_FORMAT_ARGB8888;
+        break;
+    case 24:
+    default:
+	format = WL_DRM_FORMAT_XRGB8888;
+        break;
+    case 16:
+        format = WL_DRM_FORMAT_RGB565;
+        break;
+    }
+
+    xwl_window->buffer =
+      wl_drm_create_buffer(xwl_window->xwl_screen->drm,
+			   name,
+			   pixmap->drawable.width,
+			   pixmap->drawable.height,
+			   pixmap->devKind,
+			   format);
+
+    return xwl_window->buffer ? Success : BadDrawable;
+}
diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
new file mode 100644
index 0000000..9adc615
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <wayland-util.h>
+#include <wayland-client.h>
+#include <X11/extensions/compositeproto.h>
+#include <xserver-properties.h>
+
+#include <compositeext.h>
+#include <selection.h>
+#include <extinit.h>
+#include <exevents.h>
+#include <input.h>
+#include <inpututils.h>
+#include <inputstr.h>
+#include <exevents.h>
+#include <xkbsrv.h>
+#include <windowstr.h>
+#include <mipointrst.h>
+#include <sys/mman.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static void
+xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+	/* Nothing to do, dix handles all settings */
+}
+
+static int
+xwl_pointer_proc(DeviceIntPtr device, int what)
+{
+#define NBUTTONS 10
+#define NAXES 2
+    BYTE map[NBUTTONS + 1];
+    int i = 0;
+    Atom btn_labels[NBUTTONS] = {0};
+    Atom axes_labels[NAXES] = {0};
+
+    switch (what) {
+    case DEVICE_INIT:
+	device->public.on = FALSE;
+
+        for (i = 1; i <= NBUTTONS; i++)
+            map[i] = i;
+
+        btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+        btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+        btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+        btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+        btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+        btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+        btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+        /* don't know about the rest */
+
+        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
+        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+
+        if (!InitValuatorClassDeviceStruct(device, 2, btn_labels,
+                                           GetMotionHistorySize(), Absolute))
+            return BadValue;
+
+        /* Valuators */
+        InitValuatorAxisStruct(device, 0, axes_labels[0],
+                               0, 0xFFFF, 10000, 0, 10000, Absolute);
+        InitValuatorAxisStruct(device, 1, axes_labels[1],
+                               0, 0xFFFF, 10000, 0, 10000, Absolute);
+
+        if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
+            return BadValue;
+
+        if (!InitButtonClassDeviceStruct(device, 3, btn_labels, map))
+            return BadValue;
+
+        return Success;
+
+    case DEVICE_ON:
+	device->public.on = TRUE;
+        return Success;
+
+    case DEVICE_OFF:
+    case DEVICE_CLOSE:
+	device->public.on = FALSE;
+        return Success;
+    }
+
+    return BadMatch;
+
+#undef NBUTTONS
+#undef NAXES
+}
+
+static void
+xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl)
+{
+    /* FIXME: Set keyboard leds based on CAPSFLAG etc being set in
+     * ctrl->leds - needs private protocol. */
+}
+
+static int
+xwl_keyboard_proc(DeviceIntPtr device, int what)
+{
+    struct xwl_seat *xwl_seat = device->public.devicePrivate;
+    int len;
+
+    switch (what) {
+    case DEVICE_INIT:
+	device->public.on = FALSE;
+        if (xwl_seat->keymap)
+            len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size);
+        else
+            len = 0;
+        if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap,
+						len,
+						NULL, xwl_keyboard_control))
+            return BadValue;
+
+        return Success;
+    case DEVICE_ON:
+	device->public.on = TRUE;
+        return Success;
+
+    case DEVICE_OFF:
+    case DEVICE_CLOSE:
+	device->public.on = FALSE;
+        return Success;
+    }
+
+    return BadMatch;
+}
+
+static DeviceIntPtr
+device_added(struct xwl_seat *xwl_seat, const char *driver)
+{
+    DeviceIntPtr dev = NULL;
+    Atom type_atom;
+    char *name;
+    int rc;
+    Bool (*device_control) (DeviceIntPtr device, int what);
+
+    if (strcmp(driver, "xwayland-keyboard") == 0) {
+        name = xwl_seat->keyboard_name;
+        device_control = xwl_keyboard_proc;
+    } else {
+        name = xwl_seat->pointer_name;
+        device_control = xwl_pointer_proc;
+    }
+
+    snprintf(name, sizeof xwl_seat->keyboard_name,
+             "%s:%d", driver, xwl_seat->id);
+
+    dev = AddInputDevice(serverClient, device_control, TRUE);
+    if (dev == NULL)
+        return NULL;
+
+    type_atom = MakeAtom(driver, strlen(driver), TRUE);
+    AssignTypeAndName(dev, type_atom, name);
+    dev->public.devicePrivate = xwl_seat;
+    dev->type = SLAVE;
+    dev->spriteInfo->spriteOwner = FALSE;
+
+    rc = ActivateDevice(dev, TRUE);
+    if (rc != Success) {
+        RemoveDevice(dev, TRUE);
+        xf86Msg(X_ERROR, "xwayland: Couldn't init device \"%s\"\n", name);
+        return NULL;
+    }
+
+    EnableDevice(dev, TRUE);
+    if (!dev->enabled) {
+        RemoveDevice(dev, TRUE);
+        xf86Msg(X_ERROR, "xwayland: Couldn't enable device \"%s\"\n", name);
+        return NULL;
+    }
+
+    LogMessage(X_INFO, "xwayland: Adding input device %s\n", name);
+
+    return dev;
+}
+
+static void
+pointer_handle_enter(void *data, struct wl_pointer *pointer,
+		     uint32_t serial, struct wl_surface *surface,
+		     wl_fixed_t sx_w, wl_fixed_t sy_w)
+
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr dev = xwl_seat->pointer;
+    int i;
+    int sx = wl_fixed_to_int(sx_w);
+    int sy = wl_fixed_to_int(sy_w);
+    ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
+    ValuatorMask mask;
+
+    xwl_seat->xwl_screen->serial = serial;
+    xwl_seat->pointer_enter_serial = serial;
+
+    xwl_seat->focus_window = wl_surface_get_user_data(surface);
+
+    (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE);
+
+    SetDeviceRedirectWindow(xwl_seat->pointer, xwl_seat->focus_window->window);
+
+    /* Ideally, X clients shouldn't see these button releases.  When
+     * the pointer leaves a window with buttons down, it means that
+     * the wayland compositor has grabbed the pointer.  The button
+     * release event is consumed by whatever grab in the compositor
+     * and won't be sent to clients (the X server is a client).
+     * However, we need to reset X's idea of which buttons are up and
+     * down, and they're all up (by definition) when the pointer
+     * enters a window.  We should figure out a way to swallow these
+     * events, perhaps using an X grab whenever the pointer is not in
+     * any X window, but for now just send the events. */
+    valuator_mask_zero(&mask);
+    for (i = 0; i < dev->button->numButtons; i++)
+	if (BitIsOn(dev->button->down, i))
+            QueuePointerEvents(xwl_seat->pointer, ButtonRelease, i, 0, &mask);
+
+    (*pScreen->DisplayCursor)(dev, pScreen, dev->spriteInfo->sprite->current);
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+		     uint32_t serial, struct wl_surface *surface)
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr dev = xwl_seat->pointer;
+    ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    xwl_seat->focus_window = NULL;
+    SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin);
+    (*pScreen->DisplayCursor)(dev, pScreen, NullCursor);
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+		      uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+    struct xwl_seat *xwl_seat = data;
+    int32_t dx, dy;
+    int sx = wl_fixed_to_int(sx_w);
+    int sy = wl_fixed_to_int(sy_w);
+    ValuatorMask mask;
+
+    if (!xwl_seat->focus_window)
+	return ;
+
+    dx = xwl_seat->focus_window->window->drawable.x;
+    dy = xwl_seat->focus_window->window->drawable.y;
+
+    valuator_mask_zero(&mask);
+    valuator_mask_set(&mask, 0, dx + sx);
+    valuator_mask_set(&mask, 1, dy + sy);
+
+    QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
+		       POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
+		      uint32_t time, uint32_t button, uint32_t state)
+{
+    struct xwl_seat *xwl_seat = data;
+    int index;
+    ValuatorMask mask;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    switch (button) {
+    case BTN_MIDDLE:
+	index = 2;
+	break;
+    case BTN_RIGHT:
+	index = 3;
+	break;
+    default:
+	index = button - BTN_LEFT + 1;
+	break;
+    }
+
+    valuator_mask_zero(&mask);
+    QueuePointerEvents(xwl_seat->pointer,
+                       state ? ButtonPress : ButtonRelease, index, 0, &mask);
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *pointer,
+		    uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+    struct xwl_seat *xwl_seat = data;
+    int index, count;
+    int i, val;
+    const int divisor = 10;
+    ValuatorMask mask;
+
+    if (time - xwl_seat->scroll_time > 2000) {
+	xwl_seat->vertical_scroll = 0;
+	xwl_seat->horizontal_scroll = 0;
+    }
+    xwl_seat->scroll_time = time;
+
+    /* FIXME: Need to do proper smooth scrolling here! */
+    switch (axis) {
+    case WL_POINTER_AXIS_VERTICAL_SCROLL:
+	xwl_seat->vertical_scroll += value / divisor;
+	val = wl_fixed_to_int(xwl_seat->vertical_scroll);
+	xwl_seat->vertical_scroll -= wl_fixed_from_int(val);
+
+	if (val <= -1)
+            index = 4;
+	else if (val >= 1)
+            index = 5;
+	else
+            return;
+	break;
+    case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
+	xwl_seat->horizontal_scroll += value / divisor;
+	val = wl_fixed_to_int(xwl_seat->horizontal_scroll);
+	xwl_seat->horizontal_scroll -= wl_fixed_from_int(val);
+
+	if (val <= -1)
+            index = 6;
+	else if (val >= 1)
+            index = 7;
+	else
+            return;
+	break;
+    default:
+	return;
+    }
+
+    valuator_mask_zero(&mask);
+
+    count = abs(val);
+    for (i = 0; i < count; i++) {
+        QueuePointerEvents(xwl_seat->pointer, ButtonPress, index, 0, &mask);
+        QueuePointerEvents(xwl_seat->pointer, ButtonRelease, index, 0, &mask);
+    }
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+	pointer_handle_enter,
+	pointer_handle_leave,
+	pointer_handle_motion,
+	pointer_handle_button,
+	pointer_handle_axis,
+};
+
+static void
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
+		    uint32_t time, uint32_t key, uint32_t state)
+{
+    struct xwl_seat *xwl_seat = data;
+    uint32_t *k, *end;
+    ValuatorMask mask;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    end = (uint32_t *) ((char *) xwl_seat->keys.data + xwl_seat->keys.size);
+    for (k = xwl_seat->keys.data; k < end; k++) {
+	if (*k == key)
+	    *k = *--end;
+    }
+    xwl_seat->keys.size = (char *) end - (char *) xwl_seat->keys.data;
+    if (state) {
+	k = wl_array_add(&xwl_seat->keys, sizeof *k);
+	*k = key;
+    }
+
+    valuator_mask_zero(&mask);
+    QueueKeyboardEvents(xwl_seat->keyboard,
+                        state ? KeyPress : KeyRelease, key + 8, &mask);
+}
+
+static void
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
+		       uint32_t format, int fd, uint32_t size)
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr master;
+    XkbDescPtr xkb;
+    XkbChangesRec changes = { 0 };
+
+    if (xwl_seat->keymap)
+        munmap(xwl_seat->keymap, xwl_seat->keymap_size);
+
+    xwl_seat->keymap_size = size;
+    xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+    if (xwl_seat->keymap == MAP_FAILED) {
+        xwl_seat->keymap_size = 0;
+        xwl_seat->keymap = NULL;
+        goto out;
+    }
+
+    if (!xwl_seat->keyboard)
+        goto out;
+
+    xkb = XkbCompileKeymapFromString(xwl_seat->keyboard, xwl_seat->keymap,
+                                     strnlen(xwl_seat->keymap, xwl_seat->keymap_size));
+    if (!xkb)
+        goto out;
+
+    XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes);
+    /* Keep the current controls */
+    XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc);
+
+    XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb);
+
+    master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
+    if (master && master->lastSlave == xwl_seat->keyboard)
+        XkbDeviceApplyKeymap(master, xkb);
+
+    XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE);
+
+ out:
+    close(fd);
+}
+
+static void
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
+		      uint32_t serial,
+		      struct wl_surface *surface, struct wl_array *keys)
+{
+    struct xwl_seat *xwl_seat = data;
+    ValuatorMask mask;
+    uint32_t *k;
+
+    xwl_seat->xwl_screen->serial = serial;
+    xwl_seat->keyboard_focus = surface;
+
+    wl_array_copy(&xwl_seat->keys, keys);
+    valuator_mask_zero(&mask);
+    wl_array_for_each(k, &xwl_seat->keys)
+        QueueKeyboardEvents(xwl_seat->keyboard, KeyPress, *k + 8, &mask);
+}
+
+static void
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
+		      uint32_t serial, struct wl_surface *surface)
+{
+    struct xwl_seat *xwl_seat = data;
+    ValuatorMask mask;
+    uint32_t *k;
+
+    xwl_seat->xwl_screen->serial = serial;
+
+    valuator_mask_zero(&mask);
+    wl_array_for_each(k, &xwl_seat->keys)
+        QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8, &mask);
+
+    xwl_seat->keyboard_focus = NULL;
+}
+
+static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+			  uint32_t serial, uint32_t mods_depressed,
+			  uint32_t mods_latched, uint32_t mods_locked,
+			  uint32_t group)
+{
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr dev;
+    XkbStateRec old_state, *new_state;
+    xkbStateNotify sn;
+    CARD16 changed;
+
+    /* We don't need any of this while we have keyboard focus since
+       the regular key event processing already takes care of setting
+       our internal state correctly. */
+    if (xwl_seat->keyboard_focus)
+        return;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next) {
+        if (dev != xwl_seat->keyboard && dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD))
+            continue;
+
+        old_state = dev->key->xkbInfo->state;
+        new_state = &dev->key->xkbInfo->state;
+
+        new_state->locked_group = group & XkbAllGroupsMask;
+        new_state->locked_mods = mods_locked & XkbAllModifiersMask;
+        XkbLatchModifiers(dev, XkbAllModifiersMask, mods_latched & XkbAllModifiersMask);
+
+        XkbComputeDerivedState(dev->key->xkbInfo);
+
+        changed = XkbStateChangedFlags(&old_state, new_state);
+        if (!changed)
+            continue;
+
+        sn.keycode = 0;
+        sn.eventType = 0;
+        sn.requestMajor = XkbReqCode;
+        sn.requestMinor = X_kbLatchLockState; /* close enough */
+        sn.changed = changed;
+        XkbSendStateNotify(dev, &sn);
+    }
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+	keyboard_handle_keymap,
+	keyboard_handle_enter,
+	keyboard_handle_leave,
+	keyboard_handle_key,
+	keyboard_handle_modifiers,
+};
+
+static void
+add_devices(void *data, struct wl_callback *callback, uint32_t time)
+{
+    struct xwl_seat *xwl_seat = data;
+
+    wl_callback_destroy(callback);
+
+    if (xwl_seat->wl_pointer)
+	xwl_seat->pointer = device_added(xwl_seat, "xwayland-pointer");
+    if (xwl_seat->wl_keyboard)
+	xwl_seat->keyboard = device_added(xwl_seat, "xwayland-keyboard");
+}
+
+static const struct wl_callback_listener add_devices_listener = {
+	add_devices
+};
+
+static void
+seat_handle_capabilities(void *data, struct wl_seat *seat,
+			 enum wl_seat_capability caps)
+{
+	struct xwl_seat *xwl_seat = data;
+	struct wl_callback *callback;
+
+	if (caps & WL_SEAT_CAPABILITY_POINTER) {
+	    xwl_seat->wl_pointer = wl_seat_get_pointer(seat);
+	    wl_pointer_add_listener(xwl_seat->wl_pointer,
+				    &pointer_listener, xwl_seat);
+            xwl_seat_set_cursor(xwl_seat);
+	}
+
+	if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
+	    xwl_seat->wl_keyboard = wl_seat_get_keyboard(seat);
+	    wl_keyboard_add_listener(xwl_seat->wl_keyboard,
+				     &keyboard_listener, xwl_seat);
+
+	}
+        /* FIXME: Touch ... */
+
+	/* Add devices after we've received keymaps. */
+	if (caps) {
+	    callback = wl_display_sync(xwl_seat->xwl_screen->display);
+	    wl_callback_add_listener(callback,
+				     &add_devices_listener, xwl_seat);
+	}
+}
+
+static const struct wl_seat_listener seat_listener = {
+	seat_handle_capabilities,
+};
+
+static void
+create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
+{
+    struct xwl_seat *xwl_seat;
+
+    xwl_seat = calloc(sizeof *xwl_seat, 1);
+    if (xwl_seat == NULL) {
+	ErrorF("create_input ENOMEM");
+	return ;
+    }
+
+    xwl_seat->xwl_screen = xwl_screen;
+    xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
+
+    xwl_seat->seat =
+	wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 1);
+    xwl_seat->id = id;
+
+    xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
+    wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat);
+    wl_array_init(&xwl_seat->keys);
+}
+
+static void
+input_handler(void *data, struct wl_registry *registry, uint32_t id,
+	      const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    if (strcmp (interface, "wl_seat") == 0) {
+        create_input_device(xwl_screen, id);
+    } else if (strcmp(interface, "xserver") == 0) {
+        xwl_screen->xorg_server =
+            wl_registry_bind(registry, id, &xserver_interface, 1);
+        xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
+                             xwl_screen);
+    }
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    /* FIXME */
+}
+
+static const struct wl_registry_listener input_listener = {
+    input_handler,
+    global_remove,
+};
+
+void
+xwl_input_init(struct xwl_screen *xwl_screen)
+{
+    xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
+                             xwl_screen);
+}
diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c
new file mode 100644
index 0000000..a45e213
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-output.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <wayland-client.h>
+
+#include <cursorstr.h>
+#include <xf86Crtc.h>
+#include <mipointrst.h>
+#include <randrstr.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static void
+crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
+{
+}
+
+static Bool
+crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+		    Rotation rotation, int x, int y)
+{
+	return TRUE;
+}
+
+static void
+crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+}
+
+static void
+crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+{
+}
+
+static void
+crtc_show_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+}
+
+static void
+crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
+{
+}
+
+static PixmapPtr
+crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
+{
+	return NULL;
+}
+
+static void *
+crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
+{
+	return NULL;
+}
+
+static void
+crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+}
+
+static void
+crtc_destroy(xf86CrtcPtr crtc)
+{
+    /* Nothing to do here, we only destroy CRTCs when instructed to do
+       so by wl_output changes
+    */
+}
+
+static const xf86CrtcFuncsRec crtc_funcs = {
+    .dpms                = crtc_dpms,
+    .set_mode_major      = crtc_set_mode_major,
+    .set_cursor_colors   = crtc_set_cursor_colors,
+    .set_cursor_position = crtc_set_cursor_position,
+    .show_cursor         = crtc_show_cursor,
+    .hide_cursor         = crtc_hide_cursor,
+    .load_cursor_argb    = crtc_load_cursor_argb,
+    .shadow_create       = crtc_shadow_create,
+    .shadow_allocate     = crtc_shadow_allocate,
+    .shadow_destroy      = crtc_shadow_destroy,
+    .destroy		 = crtc_destroy,
+};
+
+static void
+output_dpms(xf86OutputPtr output, int mode)
+{
+	return;
+}
+
+static xf86OutputStatus
+output_detect(xf86OutputPtr output)
+{
+	return XF86OutputStatusConnected;
+}
+
+static Bool
+output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+{
+	return MODE_OK;
+}
+
+static DisplayModePtr
+output_get_modes(xf86OutputPtr xf86output)
+{
+    struct xwl_output *output = xf86output->driver_private;
+    struct monitor_ranges *ranges;
+    DisplayModePtr modes;
+
+    modes = xf86CVTMode(output->width, output->height, 60, TRUE, FALSE);
+    output->xf86monitor.det_mon[0].type = DS_RANGES;
+    ranges = &output->xf86monitor.det_mon[0].section.ranges;
+    ranges->min_h = modes->HSync - 10;
+    ranges->max_h = modes->HSync + 10;
+    ranges->min_v = modes->VRefresh - 10;
+    ranges->max_v = modes->VRefresh + 10;
+    ranges->max_clock = modes->Clock + 100;
+    output->xf86monitor.det_mon[1].type = DT;
+    output->xf86monitor.det_mon[2].type = DT;
+    output->xf86monitor.det_mon[3].type = DT;
+    output->xf86monitor.no_sections = 0;
+
+    xf86output->MonInfo = &output->xf86monitor;
+
+    return modes;
+}
+
+static void
+output_destroy(xf86OutputPtr xf86output)
+{
+    struct xwl_output *output = xf86output->driver_private;
+
+    free(output);
+}
+
+static const xf86OutputFuncsRec output_funcs = {
+    .dpms	= output_dpms,
+    .detect	= output_detect,
+    .mode_valid	= output_mode_valid,
+    .get_modes	= output_get_modes,
+    .destroy	= output_destroy
+};
+
+struct xwl_output *
+xwl_output_create(struct xwl_screen *xwl_screen)
+{
+    struct xwl_output *xwl_output;
+    xf86OutputPtr xf86output;
+    xf86CrtcPtr xf86crtc;
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(xwl_screen->scrninfo);
+    int crtcId, outputId;
+    static int nameId;
+    char *name;
+
+    xwl_output = calloc(sizeof *xwl_output, 1);
+    if (xwl_output == NULL) {
+	ErrorF("create_output ENOMEM");
+	return NULL;
+    }
+
+    nameId++;
+    if (asprintf(&name, "XWAYLAND-%d", nameId) < 0) {
+        ErrorF("create_output ENOMEM");
+        free(xwl_output);
+        return NULL;
+    }
+
+    xwl_output->xwl_screen = xwl_screen;
+
+    xf86crtc = xf86CrtcCreate(xwl_screen->scrninfo, &crtc_funcs);
+    xf86crtc->enabled = TRUE;
+    xf86crtc->driver_private = xwl_output;
+
+    for (crtcId = 0; crtcId < xf86_config->num_crtc; crtcId++) {
+        if (xf86_config->crtc[crtcId] == xf86crtc)
+            break;
+    }
+
+    xf86output = xf86OutputCreate(xwl_screen->scrninfo,
+				  &output_funcs, name);
+    xf86output->driver_private = xwl_output;
+    xf86output->possible_crtcs = 1 << crtcId;
+
+    for (outputId = 0; outputId < xf86_config->num_output; outputId++) {
+        if (xf86_config->output[outputId] == xf86output)
+            break;
+    }
+
+    xf86output->possible_clones = 1 << outputId;
+
+    xwl_output->xf86output = xf86output;
+    xwl_output->xf86crtc = xf86crtc;
+    xwl_output->xf86output->crtc = xf86crtc;
+
+    free(name);
+
+    return xwl_output;
+}
+
+static Bool
+resize(ScrnInfoPtr scrn, int width, int height)
+{
+    if (scrn->virtualX == width && scrn->virtualY == height)
+	return TRUE;
+    /* We don't handle resize at all, we must match the compositor size */
+    return FALSE;
+}
+
+static const xf86CrtcConfigFuncsRec config_funcs = {
+    resize
+};
+
+static Rotation
+wl_transform_to_xrandr (enum wl_output_transform transform)
+{
+  switch (transform)
+    {
+    case WL_OUTPUT_TRANSFORM_NORMAL:
+      return RR_Rotate_0;
+    case WL_OUTPUT_TRANSFORM_90:
+      return RR_Rotate_90;
+    case WL_OUTPUT_TRANSFORM_180:
+      return RR_Rotate_180;
+    case WL_OUTPUT_TRANSFORM_270:
+      return RR_Rotate_270;
+    case WL_OUTPUT_TRANSFORM_FLIPPED:
+      return RR_Reflect_X | RR_Rotate_0;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+      return RR_Reflect_X | RR_Rotate_90;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+      return RR_Reflect_X | RR_Rotate_180;
+    case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+      return RR_Reflect_X | RR_Rotate_270;
+    }
+
+  return RR_Rotate_0;
+}
+
+static void
+display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
+			int physical_width, int physical_height, int subpixel,
+			const char *make, const char *model, int transform)
+{
+    struct xwl_output *xwl_output = data;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+
+    xwl_output->xf86output->mm_width = physical_width;
+    xwl_output->xf86output->mm_height = physical_height;
+
+    switch (subpixel) {
+    case WL_OUTPUT_SUBPIXEL_UNKNOWN:
+	xwl_output->xf86output->subpixel_order = SubPixelUnknown;
+	break;
+    case WL_OUTPUT_SUBPIXEL_NONE:
+	xwl_output->xf86output->subpixel_order = SubPixelNone;
+	break;
+    case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
+	xwl_output->xf86output->subpixel_order = SubPixelHorizontalRGB;
+	break;
+    case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
+	xwl_output->xf86output->subpixel_order = SubPixelHorizontalBGR;
+	break;
+    case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
+	xwl_output->xf86output->subpixel_order = SubPixelVerticalRGB;
+	break;
+    case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
+	xwl_output->xf86output->subpixel_order = SubPixelVerticalBGR;
+	break;
+    }
+
+    xwl_output->x = x;
+    xwl_output->y = y;
+    xwl_output->rotation = wl_transform_to_xrandr (transform);
+
+    xorg_list_append (&xwl_output->link, &xwl_screen->output_list);
+}
+
+static void
+display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
+		    int width, int height, int refresh)
+{
+    struct xwl_output *xwl_output = data;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+    ScreenPtr pScreen = xwl_screen->screen;
+    ScrnInfoPtr scrn = xwl_screen->scrninfo;
+    CARD16 width_mm, height_mm;
+    DisplayModePtr mode;
+    rrScrPrivPtr rp;
+
+    if (!(flags & WL_OUTPUT_MODE_CURRENT))
+	return;
+
+    xwl_output->width = width;
+    xwl_output->height = height;
+
+    if (xwl_output->x + xwl_output->width > scrn->virtualX ||
+	xwl_output->y + xwl_output->height > scrn->virtualY) {
+	/* Fake a RandR request to resize the screen. It will bounce
+	   back to our crtc_resize, which does nothing.
+	*/
+	/* Preupdate virtualX / virtualY, so that crtc_resize returns TRUE */
+	scrn->virtualX = xwl_output->x + xwl_output->width;
+	scrn->virtualY = xwl_output->y + xwl_output->height;
+
+	/* Ignore the compositor provided values for mm_width/mm_height,
+	   as it doesn't make sense to sum the values of different outputs.
+	   Just make the DPI 96 */
+	width_mm = (scrn->virtualX / 96.0) * 25.4 + 0.5;
+	height_mm = (scrn->virtualY / 96.0) * 25.4 + 0.5;
+
+	/* But! When the server starts, the RandR stuff is not initialized,
+	   so we can't call rrGetScrPriv. We updated virtualX/Y anyway, let's
+	   hope it's enough.
+	*/
+	if (xwl_screen->outputs_initialized) {
+	    rp = rrGetScrPriv(pScreen);
+	    if (rp->rrScreenSetSize)
+		rp->rrScreenSetSize(pScreen, scrn->virtualX, scrn->virtualY, width_mm, height_mm);
+	}
+    }
+
+    xwl_output->xf86crtc->enabled = TRUE;
+    mode = xf86CVTMode(width, height, (float) refresh / 1000, TRUE, FALSE);
+    xf86CrtcSetModeTransform(xwl_output->xf86crtc, mode, xwl_output->rotation,
+                             NULL, xwl_output->x, xwl_output->y);
+}
+
+static const struct wl_output_listener output_listener = {
+    display_handle_geometry,
+    display_handle_mode
+};
+
+static void
+global_handler(void *data, struct wl_registry *registry, uint32_t id,
+	       const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+    struct xwl_output *xwl_output;
+
+    if (strcmp (interface, "wl_output") == 0) {
+	xwl_output = xwl_output_create(xwl_screen);
+	xwl_output->output = wl_registry_bind(registry, id,
+	                                      &wl_output_interface, 1);
+	xwl_output->name = id;
+	wl_output_add_listener(xwl_output->output,
+			       &output_listener, xwl_output);
+    }
+}
+
+void
+xwl_output_remove(struct xwl_output *xwl_output)
+{
+    xorg_list_del (&xwl_output->link);
+    xf86OutputDestroy (xwl_output->xf86output);
+    xf86CrtcDestroy (xwl_output->xf86crtc);
+
+    wl_output_destroy (xwl_output->output);
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    struct xwl_screen *xwl_screen = data;
+    struct xwl_output *xwl_output, *tmp;
+
+    xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) {
+	if (xwl_output->name == name) {
+	    xwl_output_remove(xwl_output);
+	    break;
+	}
+    }
+}
+
+static const struct wl_registry_listener global_listener = {
+    global_handler,
+    global_remove
+};
+
+void
+xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo)
+{
+    int ret;
+
+    xf86CrtcConfigInit(scrninfo, &config_funcs);
+
+    xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192);
+
+    xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
+                             xwl_screen);
+
+    while (xwl_screen->output_list.next == &xwl_screen->output_list) {
+        ret = wl_display_roundtrip(xwl_screen->display);
+        if (ret == -1)
+            FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+    }
+
+    xf86ProbeOutputModes(scrninfo, 0, 0);
+
+    xwl_screen->outputs_initialized = TRUE;
+
+    xf86SetScrnInfoModes(scrninfo);
+}
diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
new file mode 100644
index 0000000..27d68d1
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2010 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef _XWAYLAND_PRIVATE_H_
+#define _XWAYLAND_PRIVATE_H_
+
+#include <xf86Crtc.h>
+
+struct xwl_window {
+    struct xwl_screen		*xwl_screen;
+    struct wl_surface		*surface;
+    struct wl_buffer		*buffer;
+    WindowPtr			 window;
+    DamagePtr			 damage;
+    struct xorg_list		 link;
+    struct xorg_list		 link_damage;
+};
+
+struct xwl_output;
+
+struct xwl_screen {
+    struct xwl_driver		*driver;
+    ScreenPtr			 screen;
+    ScrnInfoPtr			 scrninfo;
+    int				 drm_fd;
+    int				 wayland_fd;
+    struct wl_display		*display;
+    struct wl_registry          *registry;
+    struct wl_registry          *drm_registry;
+    struct wl_registry          *input_registry;
+    struct wl_registry          *output_registry;
+    struct wl_compositor	*compositor;
+    struct wl_drm		*drm;
+    struct wl_shm		*shm;
+    struct xserver		*xorg_server;
+    uint32_t			 mask;
+    uint32_t			 flags;
+    char			*device_name;
+    uint32_t			 authenticated;
+    struct xorg_list		 output_list;
+    struct xorg_list		 seat_list;
+    struct xorg_list		 damage_window_list;
+    struct xorg_list		 window_list;
+    struct xorg_list		 authenticate_client_list;
+    uint32_t			 serial;
+    Bool                         outputs_initialized;
+
+    DevPrivateKeyRec             cursor_private_key;
+
+    CreateWindowProcPtr		 CreateWindow;
+    DestroyWindowProcPtr	 DestroyWindow;
+    RealizeWindowProcPtr	 RealizeWindow;
+    UnrealizeWindowProcPtr	 UnrealizeWindow;
+    SetWindowPixmapProcPtr	 SetWindowPixmap;
+    MoveWindowProcPtr		 MoveWindow;
+    miPointerSpriteFuncPtr	 sprite_funcs;
+};
+
+struct xwl_output {
+    struct xorg_list             link;
+    struct wl_output		*output;
+    struct xwl_screen		*xwl_screen;
+    int32_t			 x, y, width, height;
+    xf86Monitor			 xf86monitor;
+    xf86OutputPtr		 xf86output;
+    xf86CrtcPtr			 xf86crtc;
+    int32_t                      name;
+    Rotation                     rotation;
+};
+
+
+#define MODIFIER_META 0x01
+
+struct xwl_seat {
+    DeviceIntPtr		 pointer;
+    char                         pointer_name[32];
+    DeviceIntPtr		 keyboard;
+    char                         keyboard_name[32];
+    struct xwl_screen		*xwl_screen;
+    struct wl_seat		*seat;
+    struct wl_pointer		*wl_pointer;
+    struct wl_keyboard		*wl_keyboard;
+    struct wl_array		 keys;
+    struct wl_surface		*cursor;
+    struct xwl_window		*focus_window;
+    uint32_t			 id;
+    uint32_t			 pointer_enter_serial;
+    struct xorg_list		 link;
+    CursorPtr                    x_cursor;
+
+    wl_fixed_t			 horizontal_scroll;
+    wl_fixed_t			 vertical_scroll;
+    uint32_t			 scroll_time;
+
+    size_t			 keymap_size;
+    char			*keymap;
+    struct wl_surface           *keyboard_focus;
+};
+
+
+struct xwl_screen *xwl_screen_get(ScreenPtr screen);
+
+void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo);
+
+int xwl_screen_init_cursor(struct xwl_screen *xwl_screen, ScreenPtr screen);
+int xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen);
+
+struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen);
+
+void xwl_input_init(struct xwl_screen *screen);
+
+Bool xwl_drm_initialised(struct xwl_screen *screen);
+
+void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
+
+void xwl_output_remove(struct xwl_output *output);
+
+extern const struct xserver_listener xwl_server_listener;
+
+#endif /* _XWAYLAND_PRIVATE_H_ */
diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwayland-window.c
new file mode 100644
index 0000000..a2a8206
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <wayland-client.h>
+
+#include <xf86Crtc.h>
+#include <selection.h>
+#include <exevents.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+static DevPrivateKeyRec xwl_window_private_key;
+
+static void
+free_pixmap(void *data, struct wl_callback *callback, uint32_t time)
+{
+    PixmapPtr pixmap = data;
+    ScreenPtr screen = pixmap->drawable.pScreen;
+
+    (*screen->DestroyPixmap)(pixmap);
+    wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener free_pixmap_listener = {
+	free_pixmap,
+};
+
+static void
+xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap)
+{
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+    struct wl_callback *callback;
+
+    /* We can safely destroy the buffer because we only use one buffer
+     * per surface in xwayland model */
+    if (xwl_window->buffer)
+        wl_buffer_destroy(xwl_window->buffer);
+
+    xwl_screen->driver->create_window_buffer(xwl_window, pixmap);
+
+    if (!xwl_window->buffer) {
+        ErrorF("failed to create buffer\n");
+	return;
+    }
+
+    wl_surface_attach(xwl_window->surface, xwl_window->buffer, 0, 0);
+    wl_surface_damage(xwl_window->surface, 0, 0,
+		      pixmap->drawable.width,
+		      pixmap->drawable.height);
+
+    callback = wl_display_sync(xwl_screen->display);
+    wl_callback_add_listener(callback, &free_pixmap_listener, pixmap);
+    pixmap->refcnt++;
+}
+
+static void
+damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
+{
+    struct xwl_window *xwl_window = data;
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+
+    xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
+}
+
+static void
+damage_destroy(DamagePtr pDamage, void *data)
+{
+}
+
+static Bool
+xwl_realize_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+    Bool ret;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->RealizeWindow = xwl_screen->RealizeWindow;
+    ret = (*screen->RealizeWindow)(window);
+    xwl_screen->RealizeWindow = screen->RealizeWindow;
+    screen->RealizeWindow = xwl_realize_window;
+
+    if (xwl_screen->flags & XWL_FLAGS_ROOTLESS) {
+	if (window->redirectDraw != RedirectDrawManual)
+	    return ret;
+    } else {
+	if (window->parent)
+	    return ret;
+    }
+
+    xwl_window = calloc(sizeof *xwl_window, 1);
+    xwl_window->xwl_screen = xwl_screen;
+    xwl_window->window = window;
+    xwl_window->surface =
+	wl_compositor_create_surface(xwl_screen->compositor);
+    if (xwl_window->surface == NULL) {
+	ErrorF("wl_display_create_surface failed\n");
+	return FALSE;
+    }
+
+    if (xwl_screen->xorg_server)
+	xserver_set_window_id(xwl_screen->xorg_server,
+			      xwl_window->surface, window->drawable.id);
+
+    wl_surface_set_user_data(xwl_window->surface, xwl_window);
+    xwl_window_attach(xwl_window, (*screen->GetWindowPixmap)(window));
+
+    dixSetPrivate(&window->devPrivates,
+		  &xwl_window_private_key, xwl_window);
+
+    xwl_window->damage =
+	DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
+		     FALSE, screen, xwl_window);
+    DamageRegister(&window->drawable, xwl_window->damage);
+    DamageSetReportAfterOp(xwl_window->damage, TRUE);
+
+    xorg_list_add(&xwl_window->link, &xwl_screen->window_list);
+    xorg_list_init(&xwl_window->link_damage);
+
+    return ret;
+}
+
+static Bool
+xwl_unrealize_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+    struct xwl_seat *xwl_seat;
+    Bool ret;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    xorg_list_for_each_entry(xwl_seat,
+			     &xwl_screen->seat_list, link) {
+	if (!xwl_seat->focus_window)
+	    continue ;
+	if (xwl_seat->focus_window->window == window) {
+	    xwl_seat->focus_window = NULL;
+	    SetDeviceRedirectWindow(xwl_seat->pointer, PointerRootWin);
+	}
+    }
+
+    screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
+    ret = (*screen->UnrealizeWindow)(window);
+    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
+    screen->UnrealizeWindow = xwl_unrealize_window;
+
+    xwl_window =
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
+    if (!xwl_window)
+	return ret;
+
+    if (xwl_window->buffer)
+	wl_buffer_destroy(xwl_window->buffer);
+    wl_surface_destroy(xwl_window->surface);
+    xorg_list_del(&xwl_window->link);
+    if (RegionNotEmpty(DamageRegion(xwl_window->damage)))
+	xorg_list_del(&xwl_window->link_damage);
+    DamageUnregister(xwl_window->damage);
+    DamageDestroy(xwl_window->damage);
+    free(xwl_window);
+    dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
+
+    return ret;
+}
+
+static void
+xwl_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->SetWindowPixmap = xwl_screen->SetWindowPixmap;
+    (*screen->SetWindowPixmap)(window, pixmap);
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
+
+    xwl_window =
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
+    if (xwl_window)
+	xwl_window_attach(xwl_window, pixmap);
+}
+
+static void
+xwl_move_window(WindowPtr window, int x, int y,
+		   WindowPtr sibling, VTKind kind)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->MoveWindow = xwl_screen->MoveWindow;
+    (*screen->MoveWindow)(window, x, y, sibling, kind);
+    xwl_screen->MoveWindow = screen->MoveWindow;
+    screen->MoveWindow = xwl_move_window;
+
+    xwl_window =
+	dixLookupPrivate(&window->devPrivates, &xwl_window_private_key);
+    if (xwl_window == NULL)
+	return;
+}
+
+int
+xwl_screen_init_window(struct xwl_screen *xwl_screen, ScreenPtr screen)
+{
+    if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0))
+	return BadAlloc;
+
+    xwl_screen->RealizeWindow = screen->RealizeWindow;
+    screen->RealizeWindow = xwl_realize_window;
+
+    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
+    screen->UnrealizeWindow = xwl_unrealize_window;
+
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
+
+    xwl_screen->MoveWindow = screen->MoveWindow;
+    screen->MoveWindow = xwl_move_window;
+
+    return Success;
+}
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
new file mode 100644
index 0000000..122346c
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include "xorg-config.h"
+#endif
+
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <wayland-util.h>
+#include <wayland-client.h>
+
+#include <extinit.h>
+
+#include <xf86Xinput.h>
+#include <xf86Crtc.h>
+#include <xf86Priv.h>
+#include <os.h>
+#include <selection.h>
+
+#include "xwayland.h"
+#include "xwayland-private.h"
+#include "xserver-client-protocol.h"
+
+/*
+ * TODO:
+ *  - lose X kb focus when wayland surface loses it
+ *  - active grabs, grab owner crack
+ */
+
+static DevPrivateKeyRec xwl_screen_private_key;
+
+static void
+xserver_client(void *data, struct xserver *xserver, int fd)
+{
+    AddClientOnOpenFD(fd);
+}
+
+static void
+xserver_listen_socket(void *data, struct xserver *xserver, int fd)
+{
+    ListenOnOpenFD(fd, TRUE);
+}
+
+const struct xserver_listener xwl_server_listener = {
+    xserver_client,
+    xserver_listen_socket
+};
+
+static void
+xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    ErrorF("xwl_input_delayed_init\n");
+
+    wl_callback_destroy(callback);
+    xwl_input_init(xwl_screen);
+}
+
+static const struct wl_callback_listener delayed_init_listner = {
+	xwl_input_delayed_init
+};
+
+static void
+registry_global(void *data, struct wl_registry *registry, uint32_t id,
+	        const char *interface, uint32_t version)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    if (strcmp (interface, "wl_compositor") == 0) {
+	xwl_screen->compositor =
+            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+    } else if (strcmp(interface, "wl_shm") == 0) {
+        xwl_screen->shm =
+            wl_registry_bind(registry, id, &wl_shm_interface, 1);
+    }
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+    /* Nothing to do here, wl_compositor and wl_shm should not be removed */
+}
+
+static const struct wl_registry_listener registry_listener = {
+    registry_global,
+    global_remove
+};
+
+static void
+wakeup_handler(void *data, int err, void *read_mask)
+{
+    struct xwl_screen *xwl_screen = data;
+    int ret;
+
+    if (err < 0)
+        return;
+
+    if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
+        return;
+
+    ret = wl_display_dispatch(xwl_screen->display);
+    if (ret == -1)
+        FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+}
+
+static void
+block_handler(void *data, struct timeval **tv, void *read_mask)
+{
+    struct xwl_screen *xwl_screen = data;
+    int ret;
+
+    ret = wl_display_dispatch_pending(xwl_screen->display);
+    if (ret == -1)
+	FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
+
+    ret = wl_display_flush(xwl_screen->display);
+    if (ret == -1)
+        FatalError("failed to write to XWayland fd: %s\n", strerror(errno));
+}
+
+int
+xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen)
+{
+    struct wl_callback *callback;
+
+    xwl_screen->screen = screen;
+
+    if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
+	return BadAlloc;
+
+    dixSetPrivate(&screen->devPrivates,
+		  &xwl_screen_private_key, xwl_screen);
+
+    xwl_screen_init_window(xwl_screen, screen);
+
+    xwl_screen_init_cursor(xwl_screen, screen);
+
+    AddGeneralSocket(xwl_screen->wayland_fd);
+    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
+
+    callback = wl_display_sync(xwl_screen->display);
+    wl_callback_add_listener(callback, &delayed_init_listner, xwl_screen);
+
+    return Success;
+}
+
+struct xwl_screen *
+xwl_screen_get(ScreenPtr screen)
+{
+    return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
+}
+
+struct xwl_screen *
+xwl_screen_create(void)
+{
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = calloc(sizeof *xwl_screen, 1);
+    if (xwl_screen == NULL) {
+	ErrorF("calloc failed\n");
+	return NULL;
+    }
+
+    xwl_screen->display = wl_display_connect(NULL);
+    if (xwl_screen->display == NULL) {
+	ErrorF("wl_display_create failed\n");
+	return NULL;
+    }
+
+    return xwl_screen;
+}
+
+Bool
+xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
+		    uint32_t flags, struct xwl_driver *driver)
+{
+    int ret;
+
+    noScreenSaverExtension = TRUE;
+
+    xorg_list_init(&xwl_screen->output_list);
+    xorg_list_init(&xwl_screen->seat_list);
+    xorg_list_init(&xwl_screen->damage_window_list);
+    xorg_list_init(&xwl_screen->window_list);
+    xorg_list_init(&xwl_screen->authenticate_client_list);
+    xwl_screen->scrninfo = scrninfo;
+    xwl_screen->driver = driver;
+    xwl_screen->flags = flags;
+    xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
+
+    if (xorgRootless)
+	xwl_screen->flags |= XWL_FLAGS_ROOTLESS;
+
+    /* Set up listener so we'll catch all events. */
+    xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
+    wl_registry_add_listener(xwl_screen->registry, &registry_listener,
+                             xwl_screen);
+    ret = wl_display_roundtrip(xwl_screen->display);
+    if (ret == -1) {
+        xf86DrvMsg(scrninfo->scrnIndex, X_ERROR,
+                   "failed to dispatch Wayland events: %s\n", strerror(errno));
+        return FALSE;
+    }
+
+#ifdef WITH_LIBDRM
+    if (xwl_screen->driver->use_drm && !xwl_drm_initialised(xwl_screen))
+	if (xwl_drm_pre_init(xwl_screen) != Success)
+            return FALSE;
+#endif
+
+    xwayland_screen_preinit_output(xwl_screen, scrninfo);
+
+    return TRUE;
+}
+
+int
+xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, int fd)
+{
+    struct wl_shm_pool *pool;
+    WindowPtr window = xwl_window->window;
+    ScreenPtr screen = window->drawable.pScreen;
+    VisualID visual = wVisual(window);
+    uint32_t format;
+    int size, stride, bpp, i;
+
+    for (i = 0; i < screen->numVisuals; i++)
+        if (screen->visuals[i].vid == visual)
+            break;
+
+    switch (screen->visuals[i].nplanes) {
+    case 32:
+        format = WL_SHM_FORMAT_ARGB8888;
+        bpp = 4;
+        break;
+    case 24:
+    default:
+        format = WL_SHM_FORMAT_XRGB8888;
+        bpp = 4;
+        break;
+#ifdef WL_SHM_FORMAT_RGB565
+    case 16:
+        /* XXX: Check run-time protocol version too */
+        format = WL_SHM_FORMAT_RGB565;
+        bpp = 2;
+        break;
+#endif
+    }
+
+    stride = pixmap->drawable.width * bpp;
+    size = stride * pixmap->drawable.height;
+
+    pool = wl_shm_create_pool(xwl_window->xwl_screen->shm, fd, size);
+    xwl_window->buffer =  wl_shm_pool_create_buffer(pool, 0,
+			   pixmap->drawable.width,
+			   pixmap->drawable.height,
+			   stride, format);
+    wl_shm_pool_destroy(pool);
+
+    return xwl_window->buffer ? Success : BadDrawable;
+}
+
+void xwl_screen_close(struct xwl_screen *xwl_screen)
+{
+    struct xwl_seat *xwl_seat, *itmp;
+    struct xwl_window *xwl_window, *wtmp;
+
+    if (xwl_screen->registry)
+        wl_registry_destroy(xwl_screen->registry);
+    xwl_screen->registry = NULL;
+
+    xorg_list_for_each_entry_safe(xwl_seat, itmp,
+				  &xwl_screen->seat_list, link) {
+	wl_seat_destroy(xwl_seat->seat);
+	free(xwl_seat);
+    }
+    xorg_list_for_each_entry_safe(xwl_window, wtmp,
+				  &xwl_screen->window_list, link) {
+	wl_buffer_destroy(xwl_window->buffer);
+	wl_surface_destroy(xwl_window->surface);
+	free(xwl_window);
+    }
+
+    xorg_list_init(&xwl_screen->seat_list);
+    xorg_list_init(&xwl_screen->damage_window_list);
+    xorg_list_init(&xwl_screen->window_list);
+    xorg_list_init(&xwl_screen->authenticate_client_list);
+
+    wl_display_roundtrip(xwl_screen->display);
+}
+
+void xwl_screen_destroy(struct xwl_screen *xwl_screen)
+{
+    struct xwl_output *xwl_output, *tmp;
+
+    xorg_list_for_each_entry_safe (xwl_output, tmp, &xwl_screen->output_list, link) {
+	xwl_output_remove(xwl_output);
+	break;
+    }
+
+    free(xwl_screen);
+}
+
+/* DDX driver must call this after submitting the rendering */
+void xwl_screen_post_damage(struct xwl_screen *xwl_screen)
+{
+    struct xwl_window *xwl_window;
+    RegionPtr region;
+    BoxPtr box;
+    int count, i;
+
+    xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list,
+			     link_damage) {
+	region = DamageRegion(xwl_window->damage);
+	count = RegionNumRects(region);
+	for (i = 0; i < count; i++) {
+	    box = &RegionRects(region)[i];
+	    wl_surface_damage(xwl_window->surface,
+			      box->x1, box->y1,
+			      box->x2 - box->x1,
+			      box->y2 - box->y1);
+	}
+	wl_surface_attach(xwl_window->surface,
+			  xwl_window->buffer,
+			  0, 0);
+	wl_surface_commit(xwl_window->surface);
+	DamageEmpty(xwl_window->damage);
+    }
+
+    xorg_list_init(&xwl_screen->damage_window_list);
+}
+
+static void *
+xwl_setup(void *module, void *opts, int *errmaj, int *errmin)
+{
+    return module;
+}
+
+static void
+xwl_teardown(void *p)
+{
+}
+
+static XF86ModuleVersionInfo xwl_version_info = {
+    "xwayland",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    1, 0, 0,
+    ABI_CLASS_EXTENSION,
+    ABI_EXTENSION_VERSION,
+    MOD_CLASS_NONE,
+    { 0, 0, 0, 0 }
+};
+
+_X_EXPORT const XF86ModuleData xwaylandModuleData = {
+    &xwl_version_info,
+    &xwl_setup,
+    &xwl_teardown
+};
+
+int
+xwl_version(void)
+{
+    return xwl_version_info.minorversion;
+}
diff --git a/hw/xfree86/xwayland/xwayland.h b/hw/xfree86/xwayland/xwayland.h
new file mode 100644
index 0000000..7f81e2c
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef _XWAYLAND_H_
+#define _XWAYLAND_H_
+
+#include <xf86str.h>
+
+
+#define XWL_VERSION 2
+
+struct xwl_window;
+struct xwl_screen;
+
+struct xwl_driver {
+    int version;
+    int use_drm;
+    int (*create_window_buffer)(struct xwl_window *xwl_window,
+                                PixmapPtr pixmap);
+};
+
+#define XWL_FLAGS_ROOTLESS 0x01
+
+extern _X_EXPORT int
+xwl_version(void);
+
+extern _X_EXPORT struct xwl_screen *
+xwl_screen_create(void);
+
+extern _X_EXPORT Bool
+xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
+		    uint32_t flags, struct xwl_driver *driver);
+
+extern _X_EXPORT int
+xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen);
+
+extern _X_EXPORT int
+xwl_drm_pre_init(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT int
+xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT void
+xwl_screen_close(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT void
+xwl_screen_destroy(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT void
+xwl_screen_post_damage(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT int
+xwl_drm_authenticate(ClientPtr client, struct xwl_screen *xwl_screen,
+		     uint32_t magic);
+
+extern _X_EXPORT int
+xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, uint32_t name);
+
+extern _X_EXPORT int
+xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
+			     PixmapPtr pixmap, int fd);
+
+#endif /* _XWAYLAND_H_ */
diff --git a/include/input.h b/include/input.h
index 36463f2..afbb370 100644
--- a/include/input.h
+++ b/include/input.h
@@ -508,7 +508,7 @@ extern int AttachDevice(ClientPtr client,
                         DeviceIntPtr slave, DeviceIntPtr master);
 
 extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
-extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
+extern _X_EXPORT DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
 
 extern _X_EXPORT int AllocDevicePair(ClientPtr client,
                                      const char *name,
diff --git a/include/os.h b/include/os.h
index 3b4e8f3..5be3bcc 100644
--- a/include/os.h
+++ b/include/os.h
@@ -166,10 +166,9 @@ extern _X_EXPORT void MakeClientGrabImpervious(ClientPtr /*client */ );
 
 extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client */ );
 
-#if defined(XQUARTZ) || defined(XORG_WAYLAND)
 extern _X_EXPORT void ListenOnOpenFD(int /* fd */ , int /* noxauth */ );
+
 extern _X_EXPORT void AddClientOnOpenFD(int /* fd */ );
-#endif
 
 extern _X_EXPORT CARD32 GetTimeInMillis(void);
 extern _X_EXPORT CARD64 GetTimeInMicros(void);
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index 487d7ad..b5b0ed4 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -145,4 +145,7 @@
 /* Support APM/ACPI power management in the server */
 #undef XF86PM
 
+/* Building Xorg server. */
+#undef XORG_WAYLAND
+
 #endif /* _XORG_CONFIG_H_ */
diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in
index 8bf9d38..b4180f4 100644
--- a/include/xorg-server.h.in
+++ b/include/xorg-server.h.in
@@ -227,4 +227,7 @@
 /* Ask fontsproto to make font path element names const */
 #define FONT_PATH_ELEMENT_NAME_CONST    1
 
+/* Building Xorg server. */
+#undef XORG_WAYLAND
+
 #endif /* _XORG_SERVER_H_ */
diff --git a/os/connection.c b/os/connection.c
index b0e999e..848e723 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -64,7 +64,6 @@ SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#include <xorg-server.h>
 #ifdef WIN32
 #include <X11/Xwinsock.h>
 #endif
@@ -1259,7 +1258,6 @@ MakeClientGrabPervious(ClientPtr client)
     }
 }
 
-#if defined(XQUARTZ) || defined(XORG_WAYLAND)
 /* Add a fd (from launchd) to our listeners */
 void
 ListenOnOpenFD(int fd, int noxauth)
@@ -1334,5 +1332,3 @@ AddClientOnOpenFD(int fd)
         return;
     }
 }
-
-#endif
commit 945ca467d64d4785b5fb2d2cd01dd645d8716f3c
Author: Tiago Vignatti <tiago.vignatti at intel.com>
Date:   Wed Aug 21 21:23:09 2013 -0700

    dri2: Introduce a third version of the AuthMagic function
    
    This most recent version takes a client pointer to allow xwayland to
    asynchronously authenticate a client.

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 729a323..c70f72e 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -121,8 +121,9 @@ typedef struct _DRI2Screen {
     DRI2ScheduleSwapProcPtr ScheduleSwap;
     DRI2GetMSCProcPtr GetMSC;
     DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
-    DRI2AuthMagic2ProcPtr AuthMagic;
     DRI2AuthMagicProcPtr LegacyAuthMagic;
+    DRI2AuthMagic2ProcPtr LegacyAuthMagic2;
+    DRI2AuthMagic3ProcPtr AuthMagic;
     DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify;
     DRI2SwapLimitValidateProcPtr SwapLimitValidate;
     DRI2GetParamProcPtr GetParam;
@@ -1352,7 +1353,7 @@ DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic)
         return FALSE;
 
     primescreen = GetScreenPrime(pScreen, dri2_client->prime_id);
-    if ((*ds->AuthMagic)(primescreen, magic))
+    if ((*ds->AuthMagic)(client, primescreen, magic))
         return FALSE;
     return TRUE;
 }
@@ -1457,8 +1458,11 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
         cur_minor = 1;
     }
 
+    if (info->version >= 10) {
+        ds->AuthMagic = info->AuthMagic3;
+    }
     if (info->version >= 8) {
-        ds->AuthMagic = info->AuthMagic2;
+        ds->LegacyAuthMagic2 = info->AuthMagic2;
     }
     if (info->version >= 5) {
         ds->LegacyAuthMagic = info->AuthMagic;
@@ -1497,7 +1501,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
          * If the driver doesn't provide an AuthMagic function
          * it relies on the old method (using libdrm) or fails
          */
-        if (!ds->LegacyAuthMagic)
+        if (!ds->LegacyAuthMagic2 && !ds->LegacyAuthMagic)
 #ifdef WITH_LIBDRM
             ds->LegacyAuthMagic = drmAuthMagic;
 #else
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 1e7afdd..38b4f58 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -65,6 +65,8 @@ typedef void (*DRI2CopyRegionProcPtr) (DrawablePtr pDraw,
 typedef void (*DRI2WaitProcPtr) (WindowPtr pWin, unsigned int sequence);
 typedef int (*DRI2AuthMagicProcPtr) (int fd, uint32_t magic);
 typedef int (*DRI2AuthMagic2ProcPtr) (ScreenPtr pScreen, uint32_t magic);
+typedef int (*DRI2AuthMagic3ProcPtr) (ClientPtr client,
+                                      ScreenPtr pScreen, uint32_t magic);
 
 /**
  * Schedule a buffer swap
@@ -252,6 +254,9 @@ typedef struct {
     DRI2CreateBuffer2ProcPtr CreateBuffer2;
     DRI2DestroyBuffer2ProcPtr DestroyBuffer2;
     DRI2CopyRegion2ProcPtr CopyRegion2;
+
+    /* added in version 10 */
+    DRI2AuthMagic3ProcPtr AuthMagic3;
 } DRI2InfoRec, *DRI2InfoPtr;
 
 extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info);
@@ -268,6 +273,8 @@ extern _X_EXPORT Bool DRI2Connect(ClientPtr client, ScreenPtr pScreen,
 
 extern _X_EXPORT Bool DRI2Authenticate(ClientPtr client, ScreenPtr pScreen, uint32_t magic);
 
+extern _X_EXPORT void DRI2SendAuthReply(ClientPtr client, Bool status);
+
 extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
                                         DrawablePtr pDraw,
                                         XID id,
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index ffd66fa..b858213 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -136,11 +136,23 @@ ProcDRI2Connect(ClientPtr client)
     return Success;
 }
 
+void
+DRI2SendAuthReply(ClientPtr client, Bool status)
+{
+    xDRI2AuthenticateReply rep = {
+        .type = X_Reply,
+        .sequenceNumber = client->sequence,
+        .length = 0,
+        .authenticated = status
+    };
+
+    WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
+}
+
 static int
 ProcDRI2Authenticate(ClientPtr client)
 {
     REQUEST(xDRI2AuthenticateReq);
-    xDRI2AuthenticateReply rep;
     DrawablePtr pDraw;
     int status;
 
@@ -149,13 +161,12 @@ ProcDRI2Authenticate(ClientPtr client)
                        &pDraw, &status))
         return status;
 
-    rep = (xDRI2AuthenticateReply) {
-        .type = X_Reply,
-        .sequenceNumber = client->sequence,
-        .length = 0,
-        .authenticated = DRI2Authenticate(client, pDraw->pScreen, stuff->magic)
-    };
-    WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
+    status = DRI2Authenticate(client, pDraw->pScreen, stuff->magic);
+
+    /* if non-blocking authentication is in progress, then don't send a reply
+     * now but later in the implementation (e.g. drm_handle_authenticated) */
+    if (client->ignoreCount == 0)
+        DRI2SendAuthReply(client, status);
 
     return Success;
 }
commit 2fe5f4d571079c864c1bc2e468f1a151a89aa805
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Fri Sep 18 22:09:03 2009 -0400

    Add redirect window for input device feature

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9c207eb..37f4a60 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -2044,6 +2044,19 @@ DeliverTouchEvents(DeviceIntPtr dev, TouchPointInfoPtr ti,
     }
 }
 
+void
+SetDeviceRedirectWindow(DeviceIntPtr dev, WindowPtr window)
+{
+    SpritePtr pSprite = dev->spriteInfo->sprite;
+    DeviceIntPtr mouse;
+
+    mouse = IsMaster(dev) ? dev : GetMaster(dev, MASTER_POINTER);
+
+    pSprite->redirectWindow = window;
+
+    CheckMotion(NULL, mouse);
+}
+
 int
 InitProximityClassDeviceStruct(DeviceIntPtr dev)
 {
diff --git a/dix/events.c b/dix/events.c
index f05dada..7c7afa8 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2880,7 +2880,16 @@ XYToWindow(SpritePtr pSprite, int x, int y)
     BoxRec box;
 
     pSprite->spriteTraceGood = 1;       /* root window still there */
-    pWin = RootWindow(pSprite)->firstChild;
+    if (pSprite->redirectWindow == PointerRootWin) {
+        return RootWindow(pSprite);
+    }
+    else if (pSprite->redirectWindow) {
+        pWin = pSprite->redirectWindow;
+        pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+        pWin = pWin->firstChild;
+    }
+    else
+        pWin = RootWindow(pSprite)->firstChild;
     while (pWin) {
         if ((pWin->mapped) &&
             (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
diff --git a/include/exevents.h b/include/exevents.h
index 321fc42..ba93be3 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -162,6 +162,10 @@ extern void
  ProcessOtherEvent(InternalEvent * /* ev */ ,
                    DeviceIntPtr /* other */ );
 
+extern _X_EXPORT void
+  SetDeviceRedirectWindow(DeviceIntPtr /* dev */ ,
+                        WindowPtr /* window */ );
+
 extern int
  CheckGrabValues(ClientPtr /* client */ ,
                  GrabParameters * /* param */ );
diff --git a/include/inputstr.h b/include/inputstr.h
index f6cfb04..35dd469 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -246,6 +246,8 @@ typedef struct _SpriteRec {
     ScreenPtr pEnqueueScreen;
     ScreenPtr pDequeueScreen;
 
+    WindowPtr redirectWindow;
+
 } SpriteRec;
 
 typedef struct _KeyClassRec {
commit e1ac91071d5351fea9b27d6e72cb3c0add4d3546
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Jun 21 21:28:31 2011 -0400

    os: Add a function to create a client for an fd

diff --git a/include/opaque.h b/include/opaque.h
index 73d40c3..7ec1d85 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -74,5 +74,6 @@ extern _X_EXPORT Bool whiteRoot;
 extern _X_EXPORT Bool bgNoneRoot;
 
 extern _X_EXPORT Bool CoreDump;
+extern _X_EXPORT Bool NoListenAll;
 
 #endif                          /* OPAQUE_H */
diff --git a/include/os.h b/include/os.h
index e5f86d6..3b4e8f3 100644
--- a/include/os.h
+++ b/include/os.h
@@ -166,8 +166,9 @@ extern _X_EXPORT void MakeClientGrabImpervious(ClientPtr /*client */ );
 
 extern _X_EXPORT void MakeClientGrabPervious(ClientPtr /*client */ );
 
-#ifdef XQUARTZ
-extern void ListenOnOpenFD(int /* fd */ , int /* noxauth */ );
+#if defined(XQUARTZ) || defined(XORG_WAYLAND)
+extern _X_EXPORT void ListenOnOpenFD(int /* fd */ , int /* noxauth */ );
+extern _X_EXPORT void AddClientOnOpenFD(int /* fd */ );
 #endif
 
 extern _X_EXPORT CARD32 GetTimeInMillis(void);
diff --git a/os/connection.c b/os/connection.c
index ddf4f0a..b0e999e 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -64,6 +64,7 @@ SOFTWARE.
 #include <dix-config.h>
 #endif
 
+#include <xorg-server.h>
 #ifdef WIN32
 #include <X11/Xwinsock.h>
 #endif
@@ -138,6 +139,7 @@ fd_set OutputPending;           /* clients with reply/event data ready to go */
 int MaxClients = 0;
 Bool NewOutputPending;          /* not yet attempted to write some new output */
 Bool AnyClientsWriteBlocked;    /* true if some client blocked on write */
+Bool NoListenAll;               /* Don't establish any listening sockets */
 
 static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
 Bool RunFromSigStopParent;      /* send SIGSTOP to our own process; Upstart (or
@@ -406,7 +408,10 @@ CreateWellKnownSockets(void)
     /* display is initialized to "0" by main(). It is then set to the display
      * number if specified on the command line, or to NULL when the -displayfd
      * option is used. */
-    if (display) {
+    if (NoListenAll) {
+        ListenTransCount = 0;
+    }
+    else if (display) {
         if (TryCreateSocket(atoi(display), &partial) &&
             ListenTransCount >= 1)
             if (!PartialNetwork && partial)
@@ -440,9 +445,10 @@ CreateWellKnownSockets(void)
             DefineSelf (fd);
     }
 
-    if (!XFD_ANYSET(&WellKnownConnections))
+    if (!XFD_ANYSET(&WellKnownConnections) && !NoListenAll)
         FatalError
             ("Cannot establish any listening sockets - Make sure an X server isn't already running");
+
 #if !defined(WIN32)
     OsSignal(SIGPIPE, SIG_IGN);
     OsSignal(SIGHUP, AutoResetServer);
@@ -1253,7 +1259,7 @@ MakeClientGrabPervious(ClientPtr client)
     }
 }
 
-#ifdef XQUARTZ
+#if defined(XQUARTZ) || defined(XORG_WAYLAND)
 /* Add a fd (from launchd) to our listeners */
 void
 ListenOnOpenFD(int fd, int noxauth)
@@ -1309,4 +1315,24 @@ ListenOnOpenFD(int fd, int noxauth)
 #endif
 }
 
+/* based on TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) */
+void
+AddClientOnOpenFD(int fd)
+{
+    XtransConnInfo ciptr;
+    CARD32 connect_time;
+
+    ciptr = _XSERVTransReopenCOTSServer(5, fd, "@anonymous");
+
+    _XSERVTransSetOption(ciptr, TRANS_NONBLOCKING, 1);
+    ciptr->flags |= TRANS_NOXAUTH;
+
+    connect_time = GetTimeInMillis();
+
+    if (!AllocNewConnection(ciptr, fd, connect_time)) {
+        fprintf(stderr, "failed to create client for wayland server\n");
+        return;
+    }
+}
+
 #endif
diff --git a/os/utils.c b/os/utils.c
index 497779b..8b6ca4b 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -832,7 +832,11 @@ ProcessCommandLine(int argc, char *argv[])
 #endif
         else if (strcmp(argv[i], "-nolisten") == 0) {
             if (++i < argc) {
-                if (_XSERVTransNoListen(argv[i]))
+                if (strcmp(argv[i], "all") == 0) {
+                    NoListenAll = TRUE;
+                    nolock = TRUE;
+                }
+                else if (_XSERVTransNoListen(argv[i]))
                     ErrorF("Failed to disable listen for %s transport",
                            argv[i]);
             }
commit 8e355f542571be34e9f61879bf8a7e5b67b57912
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Mon Oct 21 14:41:53 2013 +0200

    xkb: Factor out a function to copy a keymap's controls unto another

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 5d8e409..49e236d 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -837,6 +837,9 @@ extern void XkbFakeDeviceButton(DeviceIntPtr /* dev */ ,
                                 int /* press */ ,
                                 int /* button */ );
 
+extern _X_EXPORT void XkbCopyControls(XkbDescPtr /* dst */ ,
+                                      XkbDescPtr /* src */ );
+
 #include "xkbfile.h"
 #include "xkbrules.h"
 
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 6196a17..dc570f0 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5950,25 +5950,13 @@ ProcXkbGetKbdByName(ClientPtr client)
     if (rep.loaded) {
         XkbDescPtr old_xkb;
         xkbNewKeyboardNotify nkn;
-        int i, nG, nTG;
 
         old_xkb = xkb;
         xkb = new;
         dev->key->xkbInfo->desc = xkb;
         new = old_xkb;          /* so it'll get freed automatically */
 
-        *xkb->ctrls = *old_xkb->ctrls;
-        for (nG = nTG = 0, i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
-            nG = XkbKeyNumGroups(xkb, i);
-            if (nG >= XkbNumKbdGroups) {
-                nTG = XkbNumKbdGroups;
-                break;
-            }
-            if (nG > nTG) {
-                nTG = nG;
-            }
-        }
-        xkb->ctrls->num_groups = nTG;
+        XkbCopyControls(xkb, old_xkb);
 
         nkn.deviceID = nkn.oldDeviceID = dev->id;
         nkn.minKeyCode = new->min_key_code;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 1f8a839..6cf6e79 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
         xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
     }
 }
+
+void
+XkbCopyControls(XkbDescPtr dst, XkbDescPtr src)
+{
+    int i, nG, nTG;
+
+    if (!dst || !src)
+        return;
+
+    *dst->ctrls = *src->ctrls;
+
+    for (nG = nTG = 0, i = dst->min_key_code; i <= dst->max_key_code; i++) {
+        nG = XkbKeyNumGroups(dst, i);
+        if (nG >= XkbNumKbdGroups) {
+            nTG = XkbNumKbdGroups;
+            break;
+        }
+        if (nG > nTG) {
+            nTG = nG;
+        }
+    }
+    dst->ctrls->num_groups = nTG;
+}
commit e6e865981c3fa4da0695f3f555708fc39bc9d158
Author: Rui Matos <tiagomatos at gmail.com>
Date:   Tue Oct 22 16:50:29 2013 +0200

    xkb: Repurpose XkbCopyDeviceKeymap to apply a given keymap to a device
    
    This will also make it useful for cases when we have a new keymap to
    apply to a device but don't have a source device.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e9f670e..9c207eb 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -230,7 +230,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 
     mk->sourceid = device->id;
 
-    if (!XkbCopyDeviceKeymap(master, device))
+    if (!XkbDeviceApplyKeymap(master, device->key->xkbInfo->desc))
         FatalError("Couldn't pivot keymap from device to core!\n");
 }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 253612e..5d8e409 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -820,8 +820,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr /* kbd */ ,
 extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
                           XkbDescPtr /* src */ );
 
-extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
-                                          DeviceIntPtr /* src */ );
+extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
+                                           XkbDescPtr /* src */ );
 
 extern void XkbFilterEvents(ClientPtr /* pClient */ ,
                             int /* nEvents */ ,
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 31bb8d3..6196a17 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5991,7 +5991,7 @@ ProcXkbGetKbdByName(ClientPtr client)
                 continue;
 
             if (tmpd != dev)
-                XkbCopyDeviceKeymap(tmpd, dev);
+                XkbDeviceApplyKeymap(tmpd, xkb);
 
             if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
                 old_sli = tmpd->kbdfeed->xkb_sli;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6c6af60..1f8a839 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
 }
 
 Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
 {
     xkbNewKeyboardNotify nkn;
     Bool ret;
 
-    if (!dst->key || !src->key)
+    if (!dst->key || !desc)
         return FALSE;
 
     memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
     nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
     nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
     nkn.deviceID = dst->id;
-    nkn.oldDeviceID = dst->id;  /* maybe src->id? */
-    nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
-    nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
+    nkn.oldDeviceID = dst->id;
+    nkn.minKeyCode = desc->min_key_code;
+    nkn.maxKeyCode = desc->max_key_code;
     nkn.requestMajor = XkbReqCode;
     nkn.requestMinor = X_kbSetMap;      /* Near enough's good enough. */
     nkn.changed = XkbNKN_KeycodesMask;
-    if (src->key->xkbInfo->desc->geom)
+    if (desc->geom)
         nkn.changed |= XkbNKN_GeometryMask;
 
-    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
+    ret = XkbCopyKeymap(dst->key->xkbInfo->desc, desc);
     if (ret)
         XkbSendNewKeyboardNotify(dst, &nkn);
 
commit 0c1dead8ecbd091814a2847d141023359e450966
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Apr 9 17:45:08 2013 -0400

    xkb: Add XkbCompileKeymapFromString()
    
    This new function compiles a keymap from an in-memory string.  We use it
    to add a new keyooard device init function,
    InitKeyboardDeviceStructFromString(), which inits a keyboard device with
    a keymap specified as a string instead of a rmlvo set.
    
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/include/input.h b/include/input.h
index 93c4510..36463f2 100644
--- a/include/input.h
+++ b/include/input.h
@@ -385,6 +385,12 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr /*device */ ,
                                                KbdCtrlProcPtr /*controlProc */
                                                );
 
+extern _X_EXPORT Bool InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+							 const char *keymap,
+							 int keymap_length,
+							 BellProcPtr bell_func,
+							 KbdCtrlProcPtr ctrl_func);
+
 extern int ApplyPointerMapping(DeviceIntPtr /* pDev */ ,
                                CARD8 * /* map */ ,
                                int /* len */ ,
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index e799799..253612e 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -869,4 +869,8 @@ extern _X_EXPORT XkbDescPtr XkbCompileKeymap(DeviceIntPtr /* dev */ ,
                                              XkbRMLVOSet *      /* rmlvo */
     );
 
+extern _X_EXPORT XkbDescPtr XkbCompileKeymapFromString(DeviceIntPtr dev,
+						       const char *keymap,
+						       int keymap_length);
+
 #endif                          /* _XKBSRV_H_ */
diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index d266b36..d4281a0 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -262,6 +262,35 @@ XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
     return file;
 }
 
+static unsigned
+LoadXKM(unsigned want, unsigned need, XkbCompContextPtr ctx, XkbDescPtr *xkbRtrn)
+{
+    FILE *file;
+    char fileName[PATH_MAX];
+    unsigned missing;
+
+    file = XkbDDXOpenConfigFile(ctx->keymap, fileName, PATH_MAX);
+    if (file == NULL) {
+        LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
+                   fileName);
+        return 0;
+    }
+    missing = XkmReadFile(file, need, want, xkbRtrn);
+    if (*xkbRtrn == NULL) {
+        LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
+        fclose(file);
+        (void) unlink(fileName);
+        return 0;
+    }
+    else {
+        DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
+               (*xkbRtrn)->defined);
+    }
+    fclose(file);
+    (void) unlink(fileName);
+    return (need | want) & (~missing);
+}
+
 unsigned
 XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                         XkbComponentNamesPtr names,
@@ -270,9 +299,6 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                         XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
 {
     XkbDescPtr xkb;
-    FILE *file;
-    char fileName[PATH_MAX];
-    unsigned missing;
     XkbCompContextRec ctx;
 
     *xkbRtrn = NULL;
@@ -292,26 +318,30 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
         LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
         return 0;
     }
-    file = XkbDDXOpenConfigFile(ctx.keymap, fileName, PATH_MAX);
-    if (file == NULL) {
-        LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
-                   fileName);
-        return 0;
-    }
-    missing = XkmReadFile(file, need, want, xkbRtrn);
-    if (*xkbRtrn == NULL) {
-        LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
-        fclose(file);
-        (void) unlink(fileName);
+
+    return LoadXKM(want, need, &ctx, xkbRtrn);
+}
+
+static unsigned
+XkbDDXLoadKeymapFromString(DeviceIntPtr keybd,
+			   const char *keymap, int keymap_length,
+			   unsigned want,
+			   unsigned need,
+			   XkbDescPtr *xkbRtrn)
+{
+    XkbCompContextRec ctx;
+
+    *xkbRtrn = NULL;
+
+    if (StartXkbComp(&ctx))
+	fwrite(keymap, keymap_length, 1, ctx.out);
+
+    if (!FinishXkbComp(&ctx)) {
+        LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
         return 0;
     }
-    else {
-        DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
-               (*xkbRtrn)->defined);
-    }
-    fclose(file);
-    (void) unlink(fileName);
-    return (need | want) & (~missing);
+
+    return LoadXKM(want, need, &ctx, xkbRtrn);
 }
 
 Bool
@@ -407,6 +437,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need)
     return xkb;
 }
 
+static XkbDescPtr
+KeymapOrDefaults(DeviceIntPtr dev, XkbDescPtr xkb)
+{
+    XkbRMLVOSet dflts;
+
+    if (xkb)
+	return xkb;
+
+    /* we didn't get what we really needed. And that will likely leave
+     * us with a keyboard that doesn't work. Use the defaults instead */
+    LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
+	       "keymap instead.\n");
+
+    XkbGetRulesDflts(&dflts);
+
+    xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
+
+    XkbFreeRMLVOSet(&dflts, FALSE);
+
+    return xkb;
+}
+
+
 XkbDescPtr
 XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 {
@@ -424,20 +477,34 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
 
     xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
 
-    if (!xkb) {
-        XkbRMLVOSet dflts;
+    return KeymapOrDefaults(dev, xkb);
+}
 
-        /* we didn't get what we really needed. And that will likely leave
-         * us with a keyboard that doesn't work. Use the defaults instead */
-        LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
-                   "keymap instead.\n");
+XkbDescPtr
+XkbCompileKeymapFromString(DeviceIntPtr dev,
+			   const char *keymap, int keymap_length)
+{
+    XkbDescPtr xkb;
+    unsigned int need, provided;
 
-        XkbGetRulesDflts(&dflts);
+    if (!dev || !keymap) {
+        LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
+        return NULL;
+    }
 
-        xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
+    /* These are the components we really really need */
+    need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask |
+        XkmKeyNamesMask | XkmVirtualModsMask;
 
-        XkbFreeRMLVOSet(&dflts, FALSE);
+    provided =
+	XkbDDXLoadKeymapFromString(dev, keymap, keymap_length,
+				   XkmAllIndicesMask, need, &xkb);
+    if ((need & provided) != need) {
+	if (xkb) {
+	    XkbFreeKeyboard(xkb, 0, TRUE);
+	    xkb = NULL;
+	}
     }
 
-    return xkb;
+    return KeymapOrDefaults(dev, xkb);
 }
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 33420b6..766ca7b 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -505,9 +505,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
     return Success;
 }
 
-_X_EXPORT Bool
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
-                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+static Bool
+InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+				 const char *keymap, int keymap_length,
+				 BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
 {
     int i;
     unsigned int check;
@@ -522,7 +523,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     BUG_RETURN_VAL(dev->key != NULL, FALSE);
     BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
 
-    if (!rmlvo) {
+    if (!rmlvo && !keymap) {
         rmlvo = &rmlvo_dflts;
         XkbGetRulesDflts(rmlvo);
     }
@@ -550,19 +551,26 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     }
     dev->key->xkbInfo = xkbi;
 
-    if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+    if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
         XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
         xkb_cached_map = NULL;
     }
 
     if (xkb_cached_map)
         LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
-    else {
+    else if (rmlvo) {
         xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
         if (!xkb_cached_map) {
             ErrorF("XKB: Failed to compile keymap\n");
             goto unwind_info;
         }
+    } else {
+	xkb_cached_map = XkbCompileKeymapFromString(dev,
+						    keymap, keymap_length);
+        if (!xkb_cached_map) {
+            ErrorF("XKB: Failed to compile keymap from string\n");
+            goto unwind_info;
+        }
     }
 
     xkb = XkbAllocKeyboard();
@@ -627,8 +635,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
 
     dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
 
-    XkbSetRulesDflts(rmlvo);
-    XkbSetRulesUsed(rmlvo);
+    if (rmlvo) {
+	XkbSetRulesDflts(rmlvo);
+	XkbSetRulesUsed(rmlvo);
+    }
     XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
 
     return TRUE;
@@ -647,6 +657,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
     return FALSE;
 }
 
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+                         BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+    return InitKeyboardDeviceStructInternal(dev, rmlvo,
+					    NULL, 0, bell_func, ctrl_func);
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+				   const char *keymap, int keymap_length,
+				   BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+    return InitKeyboardDeviceStructInternal(dev, NULL,
+					    keymap, keymap_length,
+					    bell_func, ctrl_func);
+}
+
 /***====================================================================***/
 
         /*
commit 3edc35c723dd992fb69d09ac1e8dd1d946eefc45
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Apr 9 17:11:03 2013 -0400

    xkb: Split out code to start and finish xkbcomp
    
    Using the context struct from previous commit, we can now split out
    code to start xkbcomp and to finish and clean up after it.
    
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index cf9faa4..d266b36 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -99,10 +99,7 @@ typedef struct XkbCompContext {
 } XkbCompContextRec, *XkbCompContextPtr;
 
 static Bool
-XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
-                           XkbComponentNamesPtr names,
-                           unsigned want,
-                           unsigned need, XkbCompContextPtr ctx)
+StartXkbComp(XkbCompContextPtr ctx)
 {
     char xkm_output_dir[PATH_MAX];
 
@@ -168,14 +165,15 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     ctx->out = fopen(ctx->tmpname, "w");
 #endif
 
+    return ctx->out != NULL;
+}
+
+static Bool
+FinishXkbComp(XkbCompContextPtr ctx)
+{
+    if (!ctx->buf)
+	return FALSE;
     if (ctx->out != NULL) {
-#ifdef DEBUG
-        if (xkbDebugFlags) {
-            ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
-            XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
-        }
-#endif
-        XkbWriteXKBKeymapForNames(ctx->out, names, xkb, want, need);
 #ifndef WIN32
         if (Pclose(ctx->out) == 0)
 #else
@@ -209,6 +207,25 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     return FALSE;
 }
 
+static Bool
+XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
+                           XkbComponentNamesPtr names,
+                           unsigned want,
+                           unsigned need, XkbCompContextPtr ctx)
+{
+    if (StartXkbComp(ctx)) {
+#ifdef DEBUG
+        if (xkbDebugFlags) {
+            ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
+            XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
+        }
+#endif
+        XkbWriteXKBKeymapForNames(ctx->out, names, xkb, want, need);
+    }
+
+    return FinishXkbComp(ctx);
+}
+
 static FILE *
 XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
 {
commit 38ee54b5d2a39ca15769a2c647db6284b0e3c554
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Tue Apr 9 16:54:55 2013 -0400

    xkb: Add struct XkbCompContext
    
    This commit adds a struct that contains most of the context for starting,
    running and cleaning up after xkbcomp.
    
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c
index f458e3b..cf9faa4 100644
--- a/xkb/ddxLoad.c
+++ b/xkb/ddxLoad.c
@@ -90,14 +90,21 @@ OutputDirectory(char *outdir, size_t size)
     }
 }
 
+typedef struct XkbCompContext {
+    char keymap[PATH_MAX];
+    FILE *out;
+    char *buf;
+    char tmpname[PATH_MAX];
+    const char *xkmfile;
+} XkbCompContextRec, *XkbCompContextPtr;
+
 static Bool
 XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
                            XkbComponentNamesPtr names,
                            unsigned want,
-                           unsigned need, char *nameRtrn, int nameRtrnLen)
+                           unsigned need, XkbCompContextPtr ctx)
 {
-    FILE *out;
-    char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
+    char xkm_output_dir[PATH_MAX];
 
     const char *emptystring = "";
     char *xkbbasedirflag = NULL;
@@ -105,22 +112,19 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
     const char *xkbbindirsep = emptystring;
 
 #ifdef WIN32
-    /* WIN32 has no popen. The input must be stored in a file which is
-       used as input for xkbcomp. xkbcomp does not read from stdin. */
-    char tmpname[PATH_MAX];
-    const char *xkmfile = tmpname;
+    ctx->xkmfile = ctx->tmpname;
 #else
-    const char *xkmfile = "-";
+    ctx->xkmfile = "-";
 #endif
 
-    snprintf(keymap, sizeof(keymap), "server-%s", display);
+    snprintf(ctx->keymap, sizeof(ctx->keymap), "server-%s", display);
 
     OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
 
 #ifdef WIN32
-    strcpy(tmpname, Win32TempDir());
-    strcat(tmpname, "\\xkb_XXXXXX");
-    (void) mktemp(tmpname);
+    strcpy(ctx->tmpname, Win32TempDir());
+    strcat(ctx->tmpname, "\\xkb_XXXXXX");
+    (void) mktemp(ctx->tmpname);
 #endif
 
     if (XkbBaseDirectory != NULL) {
@@ -139,73 +143,69 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
         }
     }
 
-    if (asprintf(&buf,
+    if (asprintf(&ctx->buf,
                  "\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" "
                  "-em1 %s -emp %s -eml %s \"%s%s.xkm\"",
                  xkbbindir, xkbbindirsep,
                  ((xkbDebugFlags < 2) ? 1 :
                   ((xkbDebugFlags > 10) ? 10 : (int) xkbDebugFlags)),
-                 xkbbasedirflag ? xkbbasedirflag : "", xkmfile,
+                 xkbbasedirflag ? xkbbasedirflag : "", ctx->xkmfile,
                  PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1,
-                 xkm_output_dir, keymap) == -1)
-        buf = NULL;
+                 xkm_output_dir, ctx->keymap) == -1)
+        ctx->buf = NULL;
 
     free(xkbbasedirflag);
 
-    if (!buf) {
+    if (!ctx->buf) {
         LogMessage(X_ERROR,
                    "XKB: Could not invoke xkbcomp: not enough memory\n");
         return FALSE;
     }
 
 #ifndef WIN32
-    out = Popen(buf, "w");
+    ctx->out = Popen(ctx->buf, "w");
 #else
-    out = fopen(tmpname, "w");
+    ctx->out = fopen(ctx->tmpname, "w");
 #endif
 
-    if (out != NULL) {
+    if (ctx->out != NULL) {
 #ifdef DEBUG
         if (xkbDebugFlags) {
             ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
             XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
         }
 #endif
-        XkbWriteXKBKeymapForNames(out, names, xkb, want, need);
+        XkbWriteXKBKeymapForNames(ctx->out, names, xkb, want, need);
 #ifndef WIN32
-        if (Pclose(out) == 0)
+        if (Pclose(ctx->out) == 0)
 #else
-        if (fclose(out) == 0 && System(buf) >= 0)
+        if (fclose(ctx->out) == 0 && System(ctx->buf) >= 0)
 #endif
         {
             if (xkbDebugFlags)
-                DebugF("[xkb] xkb executes: %s\n", buf);
-            if (nameRtrn) {
-                strlcpy(nameRtrn, keymap, nameRtrnLen);
-            }
-            free(buf);
+                DebugF("[xkb] xkb executes: %s\n", ctx->buf);
+            free(ctx->buf);
 #ifdef WIN32
-            unlink(tmpname);
+            unlink(ctx->tmpname);
 #endif
             return TRUE;
         }
         else
-            LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
+            LogMessage(X_ERROR, "Error compiling keymap (%s)\n", ctx->keymap);
 #ifdef WIN32
         /* remove the temporary file */
-        unlink(tmpname);
+        unlink(ctx->tmpname);
 #endif
     }
     else {
 #ifndef WIN32
         LogMessage(X_ERROR, "XKB: Could not invoke xkbcomp\n");
 #else
-        LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
+        LogMessage(X_ERROR, "Could not open file %s\n", ctx->tmpname);
 #endif
     }
-    if (nameRtrn)
-        nameRtrn[0] = '\0';
-    free(buf);
+    ctx->keymap[0] = '\0';
+    free(ctx->buf);
     return FALSE;
 }
 
@@ -256,6 +256,7 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
     FILE *file;
     char fileName[PATH_MAX];
     unsigned missing;
+    XkbCompContextRec ctx;
 
     *xkbRtrn = NULL;
     if ((keybd == NULL) || (keybd->key == NULL) ||
@@ -270,12 +271,11 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
                    keybd->name ? keybd->name : "(unnamed keyboard)");
         return 0;
     }
-    else if (!XkbDDXCompileKeymapByNames(xkb, names, want, need,
-                                         nameRtrn, nameRtrnLen)) {
+    else if (!XkbDDXCompileKeymapByNames(xkb, names, want, need, &ctx)) {
         LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
         return 0;
     }
-    file = XkbDDXOpenConfigFile(nameRtrn, fileName, PATH_MAX);
+    file = XkbDDXOpenConfigFile(ctx.keymap, fileName, PATH_MAX);
     if (file == NULL) {
         LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
                    fileName);


More information about the xorg-commit mailing list