initailize drm depending on the window system platforms 73/26073/1
authorSooChan Lim <sc1.lim@samsung.com>
Wed, 13 Aug 2014 13:05:06 +0000 (22:05 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 14 Aug 2014 09:05:59 +0000 (18:05 +0900)
Change-Id: I7705b7731c88a63c82484cc5b23bcef78d19628c

configure.ac
packaging/libtbm.spec
src/Makefile.am
src/tbm_bufmgr.c
src/tbm_bufmgr_int.h
src/tbm_wayland.c [new file with mode: 0644]
src/tbm_x11.c [new file with mode: 0644]
src/wayland-drm/Makefile.am [new file with mode: 0644]
src/wayland-drm/wayland-drm.c [new file with mode: 0644]
src/wayland-drm/wayland-drm.h [new file with mode: 0644]
src/wayland-drm/wayland-drm.xml [new file with mode: 0644]

index c4440d3..de8ed47 100644 (file)
@@ -36,6 +36,14 @@ AC_FUNC_ALLOCA
 # Enable quiet compiles on automake 1.11.
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
+dnl Make sure the pkg-config macros are defined
+m4_ifndef([PKG_PROG_PKG_CONFIG],
+    [m4_fatal([Could not locate the pkg-config autoconf macros.
+  These are usually located in /usr/share/aclocal/pkg.m4. If your macros
+  are in a different location, try setting the environment variable
+  ACLOCAL="aclocal -I/other/macro/dir" before running autoreconf.])])
+PKG_PROG_PKG_CONFIG()
+
 # set the dir for the tbm module
 DEFAULT_BUFMGR_MODULE_PATH="/usr/lib/bufmgr"
 AC_ARG_WITH(bufmgr-module-path, AS_HELP_STRING([--with-bufmgr-module-path=PATH], [tbm bufmgr module dir]),
@@ -56,17 +64,34 @@ AC_CHECK_FUNCS([clock_gettime], [CLOCK_LIB=],
                              [AC_MSG_ERROR([Couldn't find clock_gettime])])])
 AC_SUBST([CLOCK_LIB])
 
-PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs)
-PKG_CHECK_MODULES(LIBDRM, libdrm)
-PKG_CHECK_MODULES(LIBDRI2, libdri2)
-PKG_CHECK_MODULES(X11, x11)
+
+if test "x$TBM_PLATFORM" = "xX11"; then
+    PKG_CHECK_MODULES(LIBDRI2, libdri2)
+    PKG_CHECK_MODULES(X11, x11)
+    LIBTBM_CFLAGS="$LIBDRI2_CFLAGS $X11_CFLAGS"
+    LIBTBM_LIBS="$LIBDRI2_LIBS $X11_LIBS"
+fi
+
+if test "x$TBM_PLATFORM" = "xWAYLAND"; then
+    PKG_CHECK_MODULES(WAYLAND_CLIENT, wayland-client)
+    LIBTBM_CFLAGS="$WAYLAND_CLIENT_CFLAGS"
+    LIBTBM_LIBS="$WAYLAND_CLIENT_LIBS"
+
+       WAYLAND_PREFIX=`$PKG_CONFIG --variable=prefix wayland-client`
+    AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner],,
+                   [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH])
+fi
+
 PKG_CHECK_MODULES(CAPI, [capi-base-common >= 0.1.1], [capi_0.1.1=yes], [capi_0.1.1=no])
 if test x"$capi_0.1.1" = xyes; then
        AC_DEFINE(HAVE_CAPI_0_1_1,1,[The version of capi-base-common is over 0.1.1])
 fi
 
-LIBTBM_CFLAGS="$PTHREADSTUBS_CFLAGS $LIBDRM_CFLAGS $LIBDRI2_CFLAGS $X11_CFLAGS $CAPI_CFLAGS"
-LIBTBM_LIBS="$PTHREADSTUBS_LIBS $LIBDRM_LIBS $LIBDRI2_LIBS $X11_LIBS $CAPI_LIBS"
+PKG_CHECK_MODULES(LIBDRM, libdrm)
+PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs)
+
+LIBTBM_CFLAGS+="$LIBTBM_CFALGS $LIBDRM_CFLAGS $PTHREADSTUBS_CFLAGS $CAPI_CFLAGS"
+LIBTBM_LIBS+="$LIBTBM_LIBS $LIBDRM_LIBS $PTHREADSTUBS_LIBS $CAPI_LIBS"
 AC_SUBST(LIBTBM_CFLAGS)
 AC_SUBST(LIBTBM_LIBS)
 
@@ -76,8 +101,12 @@ else
        AC_DEFINE(HAVE_WAYLAND,1,[The window system is WAYLAND.])
 fi
 
+AM_CONDITIONAL(HAVE_TBM_PLATFORM_X11, test "x$TBM_PLATFORM" = "xX11")
+AM_CONDITIONAL(HAVE_TBM_PLATFORM_WAYLAND, test "x$TBM_PLATFORM" = "xWAYLAND")
+
 AC_OUTPUT([
     src/Makefile
+       src/wayland-drm/Makefile
     drm_slp/Makefile
        Makefile
        libtbm.pc])
index 4cbd0be..66cf919 100644 (file)
@@ -1,4 +1,4 @@
-#%bcond_with x
+%bcond_with x
 %bcond_with wayland
 
 Name:           libtbm
@@ -9,9 +9,12 @@ Summary:        The library for Tizen Buffer Manager
 Group:          System/Libraries
 Source0:        %{name}-%{version}.tar.gz
 
-BuildRequires:  pkgconfig(pthread-stubs)
 BuildRequires:  pkgconfig(libdrm)
+BuildRequires:  pkgconfig(pthread-stubs)
 %if %{with wayland}
+BuildRequires:  pkgconfig
+BuildRequires:  pkgconfig(wayland-client)
+#BuildRequires:  pkgconfig(wayland-drm)
 %else
 BuildRequires:  pkgconfig(x11)
 BuildRequires:  pkgconfig(libdri2)
@@ -66,10 +69,7 @@ rm -rf %{buildroot}
 %defattr(-,root,root,-)
 /usr/share/license/%{name}
 %{_libdir}/libtbm.so.*
-%if %{with wayland}
-%else
 %{_libdir}/libdrm_slp.so.*
-%endif
 
 %files devel
 %defattr(-,root,root,-)
@@ -80,9 +80,6 @@ rm -rf %{buildroot}
 %{_includedir}/tbm_bufmgr_backend.h
 %{_includedir}/tbm_type.h
 %{_libdir}/libtbm.so
-%if %{with wayland}
-%else
 %{_libdir}/libdrm_slp.so
-%endif
 %{_libdir}/pkgconfig/libtbm.pc
 
index 2e4ce26..6849935 100644 (file)
@@ -1,7 +1,12 @@
-SUBDIRS = .
+SUBDIRS =
+
+if HAVE_TBM_PLATFORM_WAYLAND
+SUBDIRS += wayland-drm
+endif
 
 AM_CFLAGS = \
        $(WARN_CFLAGS) \
+       -I./ \
        -I$(top_srcdir) \
        -I$(top_srcdir)/src \
        $(PTHREADSTUBS_CFLAGS) \
@@ -12,7 +17,22 @@ libtbm_ladir = $(libdir)
 libtbm_la_LDFLAGS = -version-number 1:0:0 -no-undefined
 libtbm_la_LIBADD = @LIBTBM_LIBS@ @PTHREADSTUBS_LIBS@ @CLOCK_LIB@ -ldl
 
-libtbm_la_SOURCES = \
+libtbm_la_SOURCES =
+
+if HAVE_TBM_PLATFORM_X11
+    libtbm_la_SOURCES += \
+           tbm_x11.c
+endif
+
+if HAVE_TBM_PLATFORM_WAYLAND
+    AM_CFLAGS += \
+           -I$(top_srcdir)/src/wayland-drm
+    libtbm_la_LIBADD += $(top_builddir)/src/egl/wayland/wayland-drm/libwayland-drm.la
+    libtbm_la_SOURCES += \
+           tbm_wayland.c
+endif
+
+libtbm_la_SOURCES += \
        tbm_surface_internal.c \
        tbm_surface.c \
        tbm_bufmgr_backend.c \
index 35d6885..debfd57 100755 (executable)
@@ -36,11 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "tbm_bufmgr_backend.h"
 #include "tbm_bufmgr_tgl.h"
 #include "list.h"
-#ifdef HAVE_X11
-#include <X11/Xmd.h>
-#include <dri2.h>
-#include <xf86drm.h>
-#endif
 
 #define DEBUG
 #ifdef DEBUG
@@ -809,95 +804,6 @@ static int _tbm_load_module (tbm_bufmgr bufmgr, int fd)
     return ret;
 }
 
-#ifdef HAVE_X11
-static int
-_tbm_bufmgr_get_drm_fd_x11()
-{
-    int screen;
-    Display *display;
-    int dri2Major, dri2Minor;
-    int eventBase, errorBase;
-    drm_magic_t magic;
-    char *driver_name, *device_name;
-    int fd;
-
-    display = XOpenDisplay(NULL);
-    if (!display)
-    {
-        TBM_LOG ("[libtbm:%d] Fail XOpenDisplay\n", getpid());
-        return -1;
-    }
-
-    screen = DefaultScreen(display);
-
-    if (!DRI2QueryExtension (display, &eventBase, &errorBase))
-    {
-        TBM_LOG ("[libtbm:%d] Fail DRI2QueryExtention\n", getpid());
-        XCloseDisplay(display);
-        return -1;
-    }
-
-    if (!DRI2QueryVersion (display, &dri2Major, &dri2Minor))
-    {
-        TBM_LOG ("[libtbm:%d] Fail DRI2QueryVersion\n", getpid());
-        XCloseDisplay(display);
-        return -1;
-    }
-
-    if (!DRI2Connect (display, RootWindow(display, screen), &driver_name, &device_name))
-    {
-        TBM_LOG ("[libtbm:%d] Fail DRI2Connect\n", getpid());
-        XCloseDisplay(display);
-        return -1;
-    }
-
-    fd = open (device_name, O_RDWR);
-    if (fd < 0)
-    {
-        TBM_LOG ("[libtbm:%d] cannot open drm device (%s)\n", getpid(), device_name);
-        free (driver_name);
-        free (device_name);
-        XCloseDisplay(display);
-        return -1;
-    }
-
-    if (drmGetMagic (fd, &magic))
-    {
-        TBM_LOG ("[libtbm:%d] Fail drmGetMagic\n", getpid());
-        free (driver_name);
-        free (device_name);
-        close(fd);
-        XCloseDisplay(display);
-        return -1;
-    }
-
-    if (!DRI2Authenticate(display, RootWindow(display, screen), magic))
-    {
-        TBM_LOG ("[libtbm:%d] Fail DRI2Authenticate\n", getpid());
-        free (driver_name);
-        free (device_name);
-        close(fd);
-        XCloseDisplay(display);
-        return -1;
-    }
-
-    if(!drmAuthMagic(fd, magic))
-    {
-        TBM_LOG ("[libtbm:%d] Fail drmAuthMagic\n", getpid());
-        free (driver_name);
-        free (device_name);
-        close(fd);
-        XCloseDisplay(display);
-        return -1;
-    }
-
-    free (driver_name);
-    free (device_name);
-    XCloseDisplay(display);
-    return fd;
-}
-#endif
-
 tbm_bufmgr
 tbm_bufmgr_init (int fd)
 {
@@ -931,7 +837,9 @@ tbm_bufmgr_init (int fd)
     if (fd < 0)
     {
 #ifdef HAVE_X11
-        fd = _tbm_bufmgr_get_drm_fd_x11();
+        fd = tbm_bufmgr_get_drm_fd_x11();
+#elif HAVE_WAYLAND
+        fd = tbm_bufmgr_get_drm_fd_wayland();
 #endif
         if (fd < 0)
         {
index ca0e8f9..74b16d7 100755 (executable)
@@ -188,4 +188,7 @@ struct _tbm_surface {
     struct list_head item_link; /* link of surface */
 };
 
+int tbm_bufmgr_get_drm_fd_x11(void);
+int tbm_bufmgr_get_drm_fd_wayland(void);
+
 #endif  /* _TBM_BUFMGR_INT_H_ */
diff --git a/src/tbm_wayland.c b/src/tbm_wayland.c
new file mode 100644 (file)
index 0000000..f0922e4
--- /dev/null
@@ -0,0 +1,186 @@
+/**************************************************************************
+
+libtbm
+
+Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
+Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "config.h"
+
+#include "tbm_bufmgr_int.h"
+#include <xf86drm.h>
+#include <wayland-client.h>
+#include <wayland-drm-client-protocol.h>
+
+struct display {
+       struct wl_display *display;
+       struct wl_registry *registry;
+
+       struct wl_drm   *wl_drm;
+       uint32_t                drm_fd;
+       char*                   drm_device_name;
+};
+
+/* initialize drm device */
+static void
+_drm_handle_device( void *data, struct wl_drm *drm, const char *device )
+{
+       struct display *d = data;
+
+       d->drm_device_name = strdup(device);
+       return;
+}
+
+/* handle format of drm device */
+static void
+_drm_handle_format( void *data, struct wl_drm *drm, uint32_t format )
+{
+       return;
+}
+
+/* handle authentication of drm device */
+static void
+_drm_handle_authenticated( void *data, struct wl_drm *drm )
+{
+       struct display *d = data;
+
+       printf("DRM authenticated: name:%s fd:%d\n", d->drm_device_name, d->drm_fd);
+       return;
+}
+
+static void
+_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
+{
+       return;
+}
+
+static const struct wl_drm_listener drm_listener = {
+       _drm_handle_device,
+       _drm_handle_format,
+       _drm_handle_authenticated,
+       _drm_handle_capabilities
+};
+
+
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+                      uint32_t id, const char *interface, uint32_t version)
+{
+       struct display *d = data;
+
+       if (strcmp(interface, "wl_drm") == 0) {
+               d->wl_drm =
+                       wl_registry_bind(registry, id, &wl_drm_interface, version);
+               wl_drm_add_listener(d->wl_drm, &drm_listener, d);
+       }
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+                             uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+       registry_handle_global,
+       registry_handle_global_remove
+};
+
+static struct display *
+create_display(void)
+{
+       struct display *display;
+    int magin;
+
+       display = malloc(sizeof *display);
+       if (display == NULL) {
+        TBM_LOG ("[libtbm:%d] out of memory\n", getpid());
+        return NULL;
+       }
+       display->display = wl_display_connect(NULL);
+    if (display->display == NULL) {
+        TBM_LOG ("[libtbm:%d] fail to wl display\n", getpid());
+        return NULL;
+    }
+
+       display->registry = wl_display_get_registry(display->display);
+       wl_registry_add_listener(display->registry,
+                                &registry_listener, display);
+       wl_display_roundtrip(display->display);
+
+    if (display->wl_drm == NULL) {
+        TBM_LOG ("[libtbm:%d] No wl_drm global\n", getpid());
+        return NULL;
+    }
+    wl_display_roundtrip(display->display);
+
+    if (!display->drm_device_name) {
+        TBM_LOG ("[libtbm:%d] No drm device name\n", getpid());
+        return NULL;
+    }
+
+    display->drm_fd = open( display->drm_device_name, O_RDWR | O_CLOEXEC );
+    if (display->drm_fd < 0) {
+        TBM_LOG ("[libtbm:%d] Cannot open drm device\n", getpid());
+        return NULL;
+    }
+
+    drmGetMagic(display->drm_fd, &magic);
+    wl_drm_authenticate(display->wl_drm, magic);
+    wl_display_roundtrip(display->display);
+
+       return display;
+}
+
+static void
+destroy_display(struct display *display)
+{
+       if (display->wl_drm)
+               wl_drm_destroy(display->wl_drm);
+
+       wl_registry_destroy(display->registry);
+       wl_display_flush(display->display);
+       wl_display_disconnect(display->display);
+       free(display);
+}
+
+int
+tbm_bufmgr_get_drm_fd_wl()
+{
+       struct display *display = NULL;
+
+       display = create_display();
+    if (display == NULL) {
+        TBM_LOG ("[libtbm:%d] fail to create display\n", getpid());
+        return -1;
+    }
+
+       destroy_display(display);
+
+    return display->drm_fd;
+}
+
diff --git a/src/tbm_x11.c b/src/tbm_x11.c
new file mode 100644 (file)
index 0000000..f4e8a87
--- /dev/null
@@ -0,0 +1,127 @@
+/**************************************************************************
+
+libtbm
+
+Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
+Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "config.h"
+
+#include "tbm_bufmgr.h"
+#include "tbm_bufmgr_int.h"
+#include <xf86drm.h>
+#include <X11/Xmd.h>
+#include <dri2.h>
+
+int
+tbm_bufmgr_get_drm_fd_x11()
+{
+    int screen;
+    Display *display;
+    int dri2Major, dri2Minor;
+    int eventBase, errorBase;
+    drm_magic_t magic;
+    char *driver_name, *device_name;
+    int fd;
+
+    display = XOpenDisplay(NULL);
+    if (!display)
+    {
+        TBM_LOG ("[libtbm:%d] Fail XOpenDisplay\n", getpid());
+        return -1;
+    }
+
+    screen = DefaultScreen(display);
+
+    if (!DRI2QueryExtension (display, &eventBase, &errorBase))
+    {
+        TBM_LOG ("[libtbm:%d] Fail DRI2QueryExtention\n", getpid());
+        XCloseDisplay(display);
+        return -1;
+    }
+
+    if (!DRI2QueryVersion (display, &dri2Major, &dri2Minor))
+    {
+        TBM_LOG ("[libtbm:%d] Fail DRI2QueryVersion\n", getpid());
+        XCloseDisplay(display);
+        return -1;
+    }
+
+    if (!DRI2Connect (display, RootWindow(display, screen), &driver_name, &device_name))
+    {
+        TBM_LOG ("[libtbm:%d] Fail DRI2Connect\n", getpid());
+        XCloseDisplay(display);
+        return -1;
+    }
+
+    fd = open (device_name, O_RDWR);
+    if (fd < 0)
+    {
+        TBM_LOG ("[libtbm:%d] cannot open drm device (%s)\n", getpid(), device_name);
+        free (driver_name);
+        free (device_name);
+        XCloseDisplay(display);
+        return -1;
+    }
+
+    if (drmGetMagic (fd, &magic))
+    {
+        TBM_LOG ("[libtbm:%d] Fail drmGetMagic\n", getpid());
+        free (driver_name);
+        free (device_name);
+        close(fd);
+        XCloseDisplay(display);
+        return -1;
+    }
+
+    if (!DRI2Authenticate(display, RootWindow(display, screen), magic))
+    {
+        TBM_LOG ("[libtbm:%d] Fail DRI2Authenticate\n", getpid());
+        free (driver_name);
+        free (device_name);
+        close(fd);
+        XCloseDisplay(display);
+        return -1;
+    }
+
+    if(!drmAuthMagic(fd, magic))
+    {
+        TBM_LOG ("[libtbm:%d] Fail drmAuthMagic\n", getpid());
+        free (driver_name);
+        free (device_name);
+        close(fd);
+        XCloseDisplay(display);
+        return -1;
+    }
+
+    free (driver_name);
+    free (device_name);
+    XCloseDisplay(display);
+
+    return fd;
+}
+
diff --git a/src/wayland-drm/Makefile.am b/src/wayland-drm/Makefile.am
new file mode 100644 (file)
index 0000000..d66a12e
--- /dev/null
@@ -0,0 +1,24 @@
+AM_CFLAGS = \
+       -I./ \
+       -I$(top_srcdir) \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/wayland-drm \
+       $(WAYLAND_CFLAGS)
+
+noinst_LTLIBRARIES = libwayland-drm.la
+libwayland_drm_la_SOURCES = wayland-drm.c wayland-drm-protocol.c
+noinst_HEADERS = wayland-drm.h
+
+BUILT_SOURCES = wayland-drm-protocol.c \
+               wayland-drm-client-protocol.h \
+               wayland-drm-server-protocol.h
+CLEANFILES = $(BUILT_SOURCES)
+
+%-protocol.c : %.xml
+       $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
+
+%-server-protocol.h : %.xml
+       $(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@
+
+%-client-protocol.h : %.xml
+       $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
diff --git a/src/wayland-drm/wayland-drm.c b/src/wayland-drm/wayland-drm.c
new file mode 100644 (file)
index 0000000..e9c6e0a
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Copyright © 2011 Kristian Høgsberg
+ * Copyright © 2011 Benjamin Franzke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh@bitplanet.net>
+ *    Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <wayland-server.h>
+#include "wayland-drm.h"
+#include "wayland-drm-server-protocol.h"
+
+#define MIN(x,y) (((x)<(y))?(x):(y))
+
+struct wl_drm {
+       struct wl_display *display;
+       struct wl_global *wl_drm_global;
+
+       void *user_data;
+       char *device_name;
+        uint32_t flags;
+
+       struct wayland_drm_callbacks *callbacks;
+
+        struct wl_buffer_interface buffer_interface;
+};
+
+static void
+destroy_buffer(struct wl_resource *resource)
+{
+       struct wl_drm_buffer *buffer = resource->data;
+       struct wl_drm *drm = buffer->drm;
+
+       drm->callbacks->release_buffer(drm->user_data, buffer);
+       free(buffer);
+}
+
+static void
+buffer_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+       wl_resource_destroy(resource);
+}
+
+static void
+create_buffer(struct wl_client *client, struct wl_resource *resource,
+              uint32_t id, uint32_t name, int fd,
+              int32_t width, int32_t height,
+              uint32_t format,
+              int32_t offset0, int32_t stride0,
+              int32_t offset1, int32_t stride1,
+              int32_t offset2, int32_t stride2)
+{
+       struct wl_drm *drm = resource->data;
+       struct wl_drm_buffer *buffer;
+
+       buffer = calloc(1, sizeof *buffer);
+       if (buffer == NULL) {
+               wl_resource_post_no_memory(resource);
+               return;
+       }
+
+       buffer->drm = drm;
+       buffer->width = width;
+       buffer->height = height;
+       buffer->format = format;
+       buffer->offset[0] = offset0;
+       buffer->stride[0] = stride0;
+       buffer->offset[1] = offset1;
+       buffer->stride[1] = stride1;
+       buffer->offset[2] = offset2;
+       buffer->stride[2] = stride2;
+
+        drm->callbacks->reference_buffer(drm->user_data, name, fd, buffer);
+       if (buffer->driver_buffer == NULL) {
+               wl_resource_post_error(resource,
+                                      WL_DRM_ERROR_INVALID_NAME,
+                                      "invalid name");
+               return;
+       }
+
+       buffer->resource =
+               wl_resource_create(client, &wl_buffer_interface, 1, id);
+       if (!buffer->resource) {
+               wl_resource_post_no_memory(resource);
+               free(buffer);
+               return;
+       }
+
+       wl_resource_set_implementation(buffer->resource,
+                                      (void (**)(void)) &drm->buffer_interface,
+                                      buffer, destroy_buffer);
+}
+
+static void
+drm_create_buffer(struct wl_client *client, struct wl_resource *resource,
+                 uint32_t id, uint32_t name, int32_t width, int32_t height,
+                 uint32_t stride, uint32_t format)
+{
+        switch (format) {
+        case WL_DRM_FORMAT_ARGB8888:
+        case WL_DRM_FORMAT_XRGB8888:
+        case WL_DRM_FORMAT_YUYV:
+        case WL_DRM_FORMAT_RGB565:
+                break;
+        default:
+                wl_resource_post_error(resource,
+                                       WL_DRM_ERROR_INVALID_FORMAT,
+                                       "invalid format");
+           return;
+        }
+
+        create_buffer(client, resource, id,
+                      name, -1, width, height, format, 0, stride, 0, 0, 0, 0);
+}
+
+static void
+drm_create_planar_buffer(struct wl_client *client,
+                         struct wl_resource *resource,
+                         uint32_t id, uint32_t name,
+                         int32_t width, int32_t height, uint32_t format,
+                         int32_t offset0, int32_t stride0,
+                         int32_t offset1, int32_t stride1,
+                         int32_t offset2, int32_t stride2)
+{
+        switch (format) {
+       case WL_DRM_FORMAT_YUV410:
+       case WL_DRM_FORMAT_YUV411:
+       case WL_DRM_FORMAT_YUV420:
+       case WL_DRM_FORMAT_YUV422:
+       case WL_DRM_FORMAT_YUV444:
+       case WL_DRM_FORMAT_NV12:
+        case WL_DRM_FORMAT_NV16:
+                break;
+        default:
+                wl_resource_post_error(resource,
+                                       WL_DRM_ERROR_INVALID_FORMAT,
+                                       "invalid format");
+           return;
+        }
+
+        create_buffer(client, resource, id, name, -1, width, height, format,
+                      offset0, stride0, offset1, stride1, offset2, stride2);
+}
+
+static void
+drm_create_prime_buffer(struct wl_client *client,
+                        struct wl_resource *resource,
+                        uint32_t id, int fd,
+                        int32_t width, int32_t height, uint32_t format,
+                        int32_t offset0, int32_t stride0,
+                        int32_t offset1, int32_t stride1,
+                        int32_t offset2, int32_t stride2)
+{
+        create_buffer(client, resource, id, 0, fd, width, height, format,
+                      offset0, stride0, offset1, stride1, offset2, stride2);
+        close(fd);
+}
+
+static void
+drm_authenticate(struct wl_client *client,
+                struct wl_resource *resource, uint32_t id)
+{
+       struct wl_drm *drm = resource->data;
+
+       if (drm->callbacks->authenticate(drm->user_data, id) < 0)
+               wl_resource_post_error(resource,
+                                      WL_DRM_ERROR_AUTHENTICATE_FAIL,
+                                      "authenicate failed");
+       else
+               wl_resource_post_event(resource, WL_DRM_AUTHENTICATED);
+}
+
+const static struct wl_drm_interface drm_interface = {
+       drm_authenticate,
+       drm_create_buffer,
+        drm_create_planar_buffer,
+        drm_create_prime_buffer
+};
+
+static void
+bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+       struct wl_drm *drm = data;
+       struct wl_resource *resource;
+        uint32_t capabilities;
+
+       resource = wl_resource_create(client, &wl_drm_interface,
+                                     MIN(version, 2), id);
+       if (!resource) {
+               wl_client_post_no_memory(client);
+               return;
+       }
+
+       wl_resource_set_implementation(resource, &drm_interface, data, NULL);
+
+       wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name);
+       wl_resource_post_event(resource, WL_DRM_FORMAT,
+                              WL_DRM_FORMAT_ARGB8888);
+       wl_resource_post_event(resource, WL_DRM_FORMAT,
+                              WL_DRM_FORMAT_XRGB8888);
+        wl_resource_post_event(resource, WL_DRM_FORMAT,
+                               WL_DRM_FORMAT_RGB565);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV410);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV411);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV420);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV422);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV444);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV12);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV16);
+        wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUYV);
+
+        capabilities = 0;
+        if (drm->flags & WAYLAND_DRM_PRIME)
+           capabilities |= WL_DRM_CAPABILITY_PRIME;
+
+        if (version >= 2)
+           wl_resource_post_event(resource, WL_DRM_CAPABILITIES, capabilities);
+}
+
+struct wl_drm_buffer *
+wayland_drm_buffer_get(struct wl_drm *drm, struct wl_resource *resource)
+{
+       if (resource == NULL)
+               return NULL;
+
+        if (wl_resource_instance_of(resource, &wl_buffer_interface,
+                                    &drm->buffer_interface))
+               return wl_resource_get_user_data(resource);
+        else
+               return NULL;
+}
+
+struct wl_drm *
+wayland_drm_init(struct wl_display *display, char *device_name,
+                 struct wayland_drm_callbacks *callbacks, void *user_data,
+                 uint32_t flags)
+{
+       struct wl_drm *drm;
+
+       drm = malloc(sizeof *drm);
+
+       drm->display = display;
+       drm->device_name = strdup(device_name);
+       drm->callbacks = callbacks;
+       drm->user_data = user_data;
+        drm->flags = flags;
+
+        drm->buffer_interface.destroy = buffer_destroy;
+
+       drm->wl_drm_global =
+               wl_global_create(display, &wl_drm_interface, 2,
+                                drm, bind_drm);
+
+       return drm;
+}
+
+void
+wayland_drm_uninit(struct wl_drm *drm)
+{
+       free(drm->device_name);
+
+       wl_global_destroy(drm->wl_drm_global);
+
+       free(drm);
+}
+
+uint32_t
+wayland_drm_buffer_get_format(struct wl_drm_buffer *buffer)
+{
+       return buffer->format;
+}
+
+void *
+wayland_drm_buffer_get_buffer(struct wl_drm_buffer *buffer)
+{
+       return buffer->driver_buffer;
+}
diff --git a/src/wayland-drm/wayland-drm.h b/src/wayland-drm/wayland-drm.h
new file mode 100644 (file)
index 0000000..7892d56
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef WAYLAND_DRM_H
+#define WAYLAND_DRM_H
+
+#include <wayland-server.h>
+
+#ifndef WL_DRM_FORMAT_ENUM
+#define WL_DRM_FORMAT_ENUM
+enum wl_drm_format {
+       WL_DRM_FORMAT_C8 = 0x20203843,
+       WL_DRM_FORMAT_RGB332 = 0x38424752,
+       WL_DRM_FORMAT_BGR233 = 0x38524742,
+       WL_DRM_FORMAT_XRGB4444 = 0x32315258,
+       WL_DRM_FORMAT_XBGR4444 = 0x32314258,
+       WL_DRM_FORMAT_RGBX4444 = 0x32315852,
+       WL_DRM_FORMAT_BGRX4444 = 0x32315842,
+       WL_DRM_FORMAT_ARGB4444 = 0x32315241,
+       WL_DRM_FORMAT_ABGR4444 = 0x32314241,
+       WL_DRM_FORMAT_RGBA4444 = 0x32314152,
+       WL_DRM_FORMAT_BGRA4444 = 0x32314142,
+       WL_DRM_FORMAT_XRGB1555 = 0x35315258,
+       WL_DRM_FORMAT_XBGR1555 = 0x35314258,
+       WL_DRM_FORMAT_RGBX5551 = 0x35315852,
+       WL_DRM_FORMAT_BGRX5551 = 0x35315842,
+       WL_DRM_FORMAT_ARGB1555 = 0x35315241,
+       WL_DRM_FORMAT_ABGR1555 = 0x35314241,
+       WL_DRM_FORMAT_RGBA5551 = 0x35314152,
+       WL_DRM_FORMAT_BGRA5551 = 0x35314142,
+       WL_DRM_FORMAT_RGB565 = 0x36314752,
+       WL_DRM_FORMAT_BGR565 = 0x36314742,
+       WL_DRM_FORMAT_RGB888 = 0x34324752,
+       WL_DRM_FORMAT_BGR888 = 0x34324742,
+       WL_DRM_FORMAT_XRGB8888 = 0x34325258,
+       WL_DRM_FORMAT_XBGR8888 = 0x34324258,
+       WL_DRM_FORMAT_RGBX8888 = 0x34325852,
+       WL_DRM_FORMAT_BGRX8888 = 0x34325842,
+       WL_DRM_FORMAT_ARGB8888 = 0x34325241,
+       WL_DRM_FORMAT_ABGR8888 = 0x34324241,
+       WL_DRM_FORMAT_RGBA8888 = 0x34324152,
+       WL_DRM_FORMAT_BGRA8888 = 0x34324142,
+       WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
+       WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
+       WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
+       WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
+       WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
+       WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
+       WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
+       WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
+       WL_DRM_FORMAT_YUYV = 0x56595559,
+       WL_DRM_FORMAT_YVYU = 0x55595659,
+       WL_DRM_FORMAT_UYVY = 0x59565955,
+       WL_DRM_FORMAT_VYUY = 0x59555956,
+       WL_DRM_FORMAT_AYUV = 0x56555941,
+       WL_DRM_FORMAT_NV12 = 0x3231564e,
+       WL_DRM_FORMAT_NV21 = 0x3132564e,
+       WL_DRM_FORMAT_NV16 = 0x3631564e,
+       WL_DRM_FORMAT_NV61 = 0x3136564e,
+       WL_DRM_FORMAT_YUV410 = 0x39565559,
+       WL_DRM_FORMAT_YVU410 = 0x39555659,
+       WL_DRM_FORMAT_YUV411 = 0x31315559,
+       WL_DRM_FORMAT_YVU411 = 0x31315659,
+       WL_DRM_FORMAT_YUV420 = 0x32315559,
+       WL_DRM_FORMAT_YVU420 = 0x32315659,
+       WL_DRM_FORMAT_YUV422 = 0x36315559,
+       WL_DRM_FORMAT_YVU422 = 0x36315659,
+       WL_DRM_FORMAT_YUV444 = 0x34325559,
+       WL_DRM_FORMAT_YVU444 = 0x34325659,
+};
+#endif /* WL_DRM_FORMAT_ENUM */
+
+struct wl_drm;
+
+struct wl_drm_buffer {
+       struct wl_resource *resource;
+       struct wl_drm *drm;
+       int32_t width, height;
+       uint32_t format;
+        const void *driver_format;
+        int32_t offset[3];
+        int32_t stride[3];
+       void *driver_buffer;
+};
+
+struct wayland_drm_callbacks {
+       int (*authenticate)(void *user_data, uint32_t id);
+
+        void (*reference_buffer)(void *user_data, uint32_t name, int fd,
+                                 struct wl_drm_buffer *buffer);
+
+       void (*release_buffer)(void *user_data, struct wl_drm_buffer *buffer);
+};
+
+enum { WAYLAND_DRM_PRIME = 0x01 };
+
+struct wl_drm_buffer *
+wayland_drm_buffer_get(struct wl_drm *drm, struct wl_resource *resource);
+
+struct wl_drm *
+wayland_drm_init(struct wl_display *display, char *device_name,
+                struct wayland_drm_callbacks *callbacks, void *user_data,
+                 uint32_t flags);
+
+void
+wayland_drm_uninit(struct wl_drm *drm);
+
+uint32_t
+wayland_drm_buffer_get_format(struct wl_drm_buffer *buffer);
+
+void *
+wayland_drm_buffer_get_buffer(struct wl_drm_buffer *buffer);
+
+#endif
diff --git a/src/wayland-drm/wayland-drm.xml b/src/wayland-drm/wayland-drm.xml
new file mode 100644 (file)
index 0000000..8a3ad69
--- /dev/null
@@ -0,0 +1,182 @@
+<?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="2">
+    <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>
+
+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
+         surface must have a name using the flink ioctl -->
+    <request name="create_planar_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="format" type="uint"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </request>
+
+    <!-- Create a wayland buffer for the prime fd.  Use for regular and planar
+         buffers.  Pass 0 for offset and stride for unused planes. -->
+    <request name="create_prime_buffer" since="2">
+      <arg name="id" type="new_id" interface="wl_buffer"/>
+      <arg name="name" type="fd"/>
+      <arg name="width" type="int"/>
+      <arg name="height" type="int"/>
+      <arg name="format" type="uint"/>
+      <arg name="offset0" type="int"/>
+      <arg name="stride0" type="int"/>
+      <arg name="offset1" type="int"/>
+      <arg name="stride1" type="int"/>
+      <arg name="offset2" type="int"/>
+      <arg name="stride2" type="int"/>
+    </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"/>
+
+    <enum name="capability" since="2">
+      <description summary="wl_drm capability bitmask">
+        Bitmask of capabilities.
+      </description>
+      <entry name="prime" value="1" summary="wl_drm prime available"/>
+    </enum>
+
+    <event name="capabilities">
+      <arg name="value" type="uint"/>
+    </event>
+  </interface>
+
+</protocol>