display-wayland: Wayland backend implementation
authorNikhil Devshatwar <nikhil.nd@ti.com>
Wed, 9 Sep 2015 08:54:01 +0000 (14:24 +0530)
committerNikhil Devshatwar <nikhil.nd@ti.com>
Wed, 11 May 2016 16:31:54 +0000 (22:01 +0530)
Add new backend for the display interface.
Add the drm client protocol and client protocol files
* Use omap_bo to allocate video buffers
* Use wl_drm_create(_planar)_buffer APIs for wayland buffers
Update the Makefile and configure.ac dependencies
Add the viewport to scale based on -w SIZE

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
configure.ac
util/Makefile.am
util/display-wayland.c [new file with mode: 0644]
util/util.c
util/wayland-drm-client-protocol.h [new file with mode: 0644]
util/wayland-drm-protocol.c [new file with mode: 0644]

index c02673315c8d66dae4db5404ed8992f71274b772..2394eb9d05a318ea6c75b2cdd154eca6a72a28bb 100644 (file)
@@ -62,6 +62,18 @@ else
 fi
 AM_CONDITIONAL(ENABLE_KMSCUBE, [test "x$HAVE_KMSCUBE" = xyes])
 
+# Check optional WAYLAND:
+AC_ARG_ENABLE([wayland], AS_HELP_STRING([--disable-wayland], [disable wayland display support]))
+AS_IF([test "x$enable_wayland" != "xno"], [PKG_CHECK_EXISTS(wayland-egl wayland-cursor wayland-client, [HAVE_WAYLAND=yes], [HAVE_WAYLAND=no])])
+if test "x$HAVE_WAYLAND" = "xyes"; then
+       AC_DEFINE(HAVE_WAYLAND, 1, [Have WAYLAND support])
+       PKG_CHECK_MODULES(EGL, egl)
+       PKG_CHECK_MODULES(WAYLAND, wayland-egl wayland-cursor wayland-client)
+else
+       AC_MSG_WARN([No WAYLAND support detected, disabling WAYLAND support])
+fi
+AM_CONDITIONAL(ENABLE_WAYLAND, [test "x$HAVE_WAYLAND" = xyes])
+
 # Check for libdce and libav..
 PKG_CHECK_MODULES(DCE, libdce libavformat libavutil, [HAVE_DCE=yes], [HAVE_DCE=no])
 if test "x$HAVE_DCE" = "xyes"; then
index 7b672877e410e201a7896bdf4becb453d8425e32..a14c0796d7645a175e0d6dd99cb4f6c95db5e32b 100644 (file)
@@ -34,5 +34,12 @@ if ENABLE_KMSCUBE
 libutil_la_SOURCES += display-kmscube.c esTransform.c
 endif
 
+if ENABLE_WAYLAND
+libutil_la_SOURCES += display-wayland.c wayland-drm-protocol.c wayland-scaler-protocol.c
+libutil_la_CFLAGS = @DRM_CFLAGS@
+libutil_la_LDFLAGS = -lwayland-client -lwayland-cursor -ldrm -ldrm_omap -lpthread -lpvr_wlegl
+
+endif
+
 libutil_la_LIBADD = @DRM_LIBS@ @DCE_LIBS@ @GBM_LIBS@ @EGL_LIBS@ @GLES2_LIBS@
 libutil_la_CFLAGS = @DRM_CFLAGS@ @DCE_CFLAGS@ @WARN_CFLAGS@ @GBM_CFLAGS@ @EGL_CFLAGS@ @GLES2_CFLAGS@
diff --git a/util/display-wayland.c b/util/display-wayland.c
new file mode 100644 (file)
index 0000000..c0d6175
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Nikhil Devshatwar <nikhil.nd@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "util.h"
+
+#include <xf86drmMode.h>
+#include <wayland-client.h>
+#include <wayland-drm-client-protocol.h>
+#include <wayland-scaler-client-protocol.h>
+
+/* NOTE: healthy dose of recycling from libdrm modetest app.. */
+
+
+#define to_display_wl(x) container_of(x, struct display_wl, base)
+struct display_wl {
+       struct display base;
+
+       uint32_t bo_flags;
+       struct wl_display *display;
+       struct wl_compositor *compositor;
+       struct wl_surface *surface;
+       struct wl_shell *shell;
+       struct wl_drm *drm;
+       struct wl_viewport *viewport;
+       struct wl_scaler *scaler;
+};
+
+#define to_buffer_wl(x) container_of(x, struct buffer_wl, base)
+struct buffer_wl {
+       struct buffer base;
+
+       struct wl_buffer *wl_buf;
+       uint32_t name;
+};
+
+static int global_fd = 0;
+static uint32_t used_planes = 0;
+static int ndisplays = 0;
+
+static struct omap_bo *
+alloc_bo(struct display *disp, uint32_t bpp, uint32_t width, uint32_t height,
+               uint32_t *bo_handle, uint32_t *pitch)
+{
+       struct display_wl *disp_wl = to_display_wl(disp);
+       struct omap_bo *bo;
+       uint32_t bo_flags = disp_wl->bo_flags;
+
+       bo_flags |= OMAP_BO_WC;
+       bo = omap_bo_new(disp->dev, width * height * bpp / 8, bo_flags);
+
+       if (bo) {
+               *bo_handle = omap_bo_handle(bo);
+               *pitch = width * bpp / 8;
+               if (bo_flags & OMAP_BO_TILED)
+                       *pitch = ALIGN2(*pitch, PAGE_SHIFT);
+       }
+
+       return bo;
+}
+
+static struct buffer *
+alloc_buffer(struct display *disp, uint32_t fourcc, uint32_t w, uint32_t h)
+{
+       struct display_wl *disp_wl = to_display_wl(disp);
+       struct buffer_wl *buf_wl;
+       struct buffer *buf;
+       uint32_t bo_handles[4] = {0};
+       uint32_t wl_fmt = WL_DRM_FORMAT_NV12;
+
+       buf_wl = calloc(1, sizeof(*buf_wl));
+       if (!buf_wl) {
+               ERROR("allocation failed");
+               return NULL;
+       }
+       buf = &buf_wl->base;
+
+       buf->fourcc = fourcc;
+       buf->width = w;
+       buf->height = h;
+       buf->multiplanar = true;
+
+       buf->nbo = 1;
+
+       if (!fourcc)
+               fourcc = FOURCC('A','R','2','4');
+
+       switch (fourcc) {
+       case FOURCC('A','R','2','4'):
+               wl_fmt = WL_DRM_FORMAT_ARGB8888;
+               buf->nbo = 1;
+               buf->bo[0] = alloc_bo(disp, 32, buf->width, buf->height,
+                               &bo_handles[0], &buf->pitches[0]);
+               omap_bo_get_name(buf->bo[0], &buf_wl->name);
+
+               /* ARGB: stride is four times width */
+               buf_wl->wl_buf = wl_drm_create_buffer(disp_wl->drm,
+                       buf_wl->name, buf->width, buf->height,
+                       buf->width * 4, wl_fmt);
+               break;
+       case FOURCC('U','Y','V','Y'):
+       case FOURCC('Y','U','Y','V'):
+               wl_fmt = WL_DRM_FORMAT_YUYV;
+               buf->nbo = 1;
+               buf->bo[0] = alloc_bo(disp, 16, buf->width, buf->height,
+                               &bo_handles[0], &buf->pitches[0]);
+
+               omap_bo_get_name(buf->bo[0], &buf_wl->name);
+               /* YUYV; stride is double width */
+               buf_wl->wl_buf = wl_drm_create_buffer(disp_wl->drm,
+                       buf_wl->name, buf->width, buf->height,
+                       buf->width * 2, wl_fmt);
+               break;
+       case FOURCC('N','V','1','2'):
+               wl_fmt = WL_DRM_FORMAT_NV12;
+               buf->nbo = 1;
+               buf->bo[0] = alloc_bo(disp, 8, buf->width, buf->height * 3 / 2,
+                               &bo_handles[0], &buf->pitches[0]);
+
+               omap_bo_get_name(buf->bo[0], &buf_wl->name);
+               /* NV12: Create a planar buffer */
+               buf_wl->wl_buf = wl_drm_create_planar_buffer(disp_wl->drm,
+                       buf_wl->name, buf->width, buf->height, wl_fmt,
+                       0, buf->width,
+                       buf->width * buf->height, buf->width,
+                       0, 0);
+               break;
+       default:
+               ERROR("invalid format: 0x%08x", fourcc);
+               goto fail;
+       }
+
+       return buf;
+
+fail:
+       // XXX cleanup
+       return NULL;
+}
+
+static void
+free_buffers(struct display *disp, uint32_t n)
+{
+       uint32_t i;
+       for (i = 0; i < n; i++) {
+               if (disp->buf[i]) {
+                       close(disp->buf[i]->fd[0]);
+                       omap_bo_del(disp->buf[i]->bo[0]);
+                       if (disp->multiplanar) {
+                               close(disp->buf[i]->fd[1]);
+                               omap_bo_del(disp->buf[i]->bo[1]);
+                       }
+               }
+       }
+       free(disp->buf);
+}
+
+static struct buffer **
+alloc_buffers(struct display *disp, uint32_t n,
+               uint32_t fourcc, uint32_t w, uint32_t h)
+{
+       struct buffer **bufs;
+       uint32_t i = 0;
+
+       bufs = calloc(n, sizeof(*bufs));
+       if (!bufs) {
+               ERROR("allocation failed");
+               goto fail;
+       }
+
+       for (i = 0; i < n; i++) {
+               bufs[i] = alloc_buffer(disp, fourcc, w, h);
+               if (!bufs[i]) {
+                       ERROR("allocation failed");
+                       goto fail;
+               }
+       }
+       disp->buf = bufs;
+       return bufs;
+
+fail:
+       // XXX cleanup
+       return NULL;
+}
+
+static struct buffer **
+get_buffers(struct display *disp, uint32_t n)
+{
+       return alloc_buffers(disp, n, 0, disp->width, disp->height);
+}
+
+static struct buffer **
+get_vid_buffers(struct display *disp, uint32_t n,
+               uint32_t fourcc, uint32_t w, uint32_t h)
+{
+       return alloc_buffers(disp, n, fourcc, w, h);
+}
+
+static int
+post_buffer(struct display *disp, struct buffer *buf)
+{
+       ERROR("post_buffer not supported");
+
+       return -1;
+}
+
+static int
+post_vid_buffer(struct display *disp, struct buffer *buf,
+               uint32_t x, uint32_t y, uint32_t w, uint32_t h)
+{
+       struct display_wl *disp_wl = to_display_wl(disp);
+       struct buffer_wl *buf_wl = to_buffer_wl(buf);
+       int ret = 0;
+
+       wl_surface_attach(disp_wl->surface, buf_wl->wl_buf, 0, 0);
+       wl_surface_commit(disp_wl->surface);
+       wl_display_flush(disp_wl->display);
+
+       return ret;
+}
+
+static void
+close_kms(struct display *disp)
+{
+       omap_device_del(disp->dev);
+       disp->dev = NULL;
+       if (used_planes) {
+               used_planes >>= 1;
+       }
+       if (--ndisplays == 0) {
+               close(global_fd);
+       }
+}
+
+void
+disp_wayland_usage(void)
+{
+       MSG("WAYLAND Display Options:");
+       MSG("\t-w <width>x<height>\tset the dimensions of client window");
+       MSG("\t--pos <X coord>x<Y coord>\tset the position of client window");
+}
+
+static void
+registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
+       const char *interface, uint32_t version)
+{
+       struct display_wl *disp_wl = (struct display_wl *) data;
+
+       if (strcmp(interface, "wl_compositor") == 0) {
+               disp_wl->compositor = wl_registry_bind(registry, id,
+                       &wl_compositor_interface, 3);
+       } else if (strcmp(interface, "wl_shell") == 0) {
+               disp_wl->shell = wl_registry_bind(registry, id,
+                       &wl_shell_interface, 1);
+       } else if (strcmp(interface, "wl_drm") == 0) {
+               disp_wl->drm = wl_registry_bind(registry, id,
+                       &wl_drm_interface, 1);
+       } else if (strcmp(interface, "wl_scaler") == 0) {
+               disp_wl->scaler = wl_registry_bind(registry, id,
+                       &wl_scaler_interface, 2);
+       }
+}
+
+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
+};
+
+
+struct display *
+disp_wayland_open(int argc, char **argv)
+{
+       struct display_wl *disp_wl = NULL;
+       struct display *disp;
+       int i, enabled = 0, width, height, posx, posy;
+
+       struct wl_registry *registry;
+       struct wl_shell_surface *shell_surface;
+       struct wl_region *region;
+       char title[100];
+
+       /* note: set args to NULL after we've parsed them so other modules know
+        * that it is already parsed (since the arg parsing is decentralized)
+        */
+       for (i = 1; i < argc; i++) {
+               if (!argv[i]) {
+                       continue;
+               }
+               if (!strcmp("-1", argv[i])) {
+                       disp->multiplanar = false;
+               } else if (!strcmp("-w", argv[i])) {
+                       argv[i++] = NULL;
+                       if (sscanf(argv[i], "%dx%d", &width, &height) != 2) {
+                               ERROR("invalid arg: -w %s", argv[i]);
+                               goto fail;
+                       }
+                       enabled = 1;
+               } else if (!strcmp("--pos", argv[i])) {
+                       argv[i++] = NULL;
+                       if (sscanf(argv[i], "%dx%d", &posx, &posy) != 2) {
+                               ERROR("invalid arg: -w %s", argv[i]);
+                               goto fail;
+                       }
+               } else {
+                       /* ignore */
+                       continue;
+               }
+               argv[i] = NULL;
+       }
+       // If not explicitely enabled from command line, fail.
+       if (!enabled)
+               goto fail;
+
+       disp_wl = calloc(1, sizeof(*disp_wl));
+       if (!disp_wl) {
+               ERROR("allocation failed");
+               goto fail;
+       }
+       disp = &disp_wl->base;
+
+       if (!global_fd) {
+               global_fd = drmOpen("omapdrm", NULL);
+               if (global_fd < 0) {
+                       ERROR("could not open drm device: %s (%d)",
+                               strerror(errno), errno);
+                       goto fail;
+               }
+       }
+
+       disp->fd = global_fd;
+       ndisplays++;
+
+       disp->dev = omap_device_new(disp->fd);
+       if (!disp->dev) {
+               ERROR("couldn't create device");
+               goto fail;
+       }
+
+       disp->get_buffers = get_buffers;
+       disp->get_vid_buffers = get_vid_buffers;
+       disp->post_buffer = post_buffer;
+       disp->post_vid_buffer = post_vid_buffer;
+       disp->close = close_kms;
+       disp->disp_free_buf = free_buffers;
+
+       disp->multiplanar = true;
+       disp->width = width;
+       disp->height = height;
+
+       disp_wl->bo_flags = OMAP_BO_SCANOUT|OMAP_BO_WC;
+
+       disp_wl->display = wl_display_connect(NULL);
+       if (disp_wl->display == NULL) {
+               ERROR("failed to connect to Wayland display: %m\n");
+               goto fail;
+       } else {
+               MSG("wayland display opened\n");
+       }
+
+       /* Find out what interfaces are implemented, and initialize */
+       registry = wl_display_get_registry(disp_wl->display);
+       wl_registry_add_listener(registry, &registry_listener, disp_wl);
+       wl_display_roundtrip(disp_wl->display);
+       MSG("wayland registries obtained\n");
+
+       disp_wl->surface = wl_compositor_create_surface(disp_wl->compositor);
+       shell_surface = wl_shell_get_shell_surface(disp_wl->shell,
+                                               disp_wl->surface);
+       wl_shell_surface_set_toplevel(shell_surface);
+
+       region = wl_compositor_create_region(disp_wl->compositor);
+       wl_region_add(region, 0, 0, disp->width, disp->height);
+
+       disp_wl->viewport = wl_scaler_get_viewport(disp_wl->scaler,
+                                               disp_wl->surface);
+       wl_viewport_set_destination(disp_wl->viewport, width, height);
+       sprintf(title, "[@position-req=%dx%d]", posx, posy);
+       wl_shell_surface_set_title(shell_surface, title);
+
+       return disp;
+
+fail:
+       // XXX cleanup
+       return NULL;
+}
index 682fba6b3d31ed4f5b111389675d7a36802640e5..e7eb8198667b45bb003787784bce3c2df8d4e5c0 100644 (file)
@@ -40,6 +40,11 @@ void disp_kmscube_usage(void);
 struct display * disp_kmscube_open(int argc, char **argv);
 #endif
 
+#ifdef HAVE_WAYLAND
+void disp_wayland_usage(void);
+struct display *disp_wayland_open(int argc, char **argv);
+#endif
+
 void
 disp_usage(void)
 {
@@ -53,6 +58,9 @@ disp_usage(void)
 #endif
 #ifdef HAVE_KMSCUBE
        disp_kmscube_usage();
+#endif
+#ifdef HAVE_WAYLAND
+       disp_wayland_usage();
 #endif
        disp_kms_usage();
 }
@@ -113,6 +121,11 @@ disp_open(int argc, char **argv)
        if (disp)
                goto out;
 #endif
+#ifdef HAVE_WAYLAND
+       disp = disp_wayland_open(argc, argv);
+       if (disp)
+               goto out;
+#endif
 
        disp = disp_kms_open(argc, argv);
 
diff --git a/util/wayland-drm-client-protocol.h b/util/wayland-drm-client-protocol.h
new file mode 100644 (file)
index 0000000..7ddb614
--- /dev/null
@@ -0,0 +1,213 @@
+/* 
+ * 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.
+ */
+
+#ifndef DRM_CLIENT_PROTOCOL_H
+#define DRM_CLIENT_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct wl_drm;
+
+extern const struct wl_interface wl_drm_interface;
+
+#ifndef WL_DRM_ERROR_ENUM
+#define WL_DRM_ERROR_ENUM
+enum wl_drm_error {
+       WL_DRM_ERROR_AUTHENTICATE_FAIL = 0,
+       WL_DRM_ERROR_INVALID_FORMAT = 1,
+       WL_DRM_ERROR_INVALID_NAME = 2,
+};
+#endif /* WL_DRM_ERROR_ENUM */
+
+#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_listener {
+       /**
+        * device - (none)
+        * @name: (none)
+        */
+       void (*device)(void *data,
+                      struct wl_drm *wl_drm,
+                      const char *name);
+       /**
+        * format - (none)
+        * @format: (none)
+        */
+       void (*format)(void *data,
+                      struct wl_drm *wl_drm,
+                      uint32_t format);
+       /**
+        * authenticated - (none)
+        */
+       void (*authenticated)(void *data,
+                             struct wl_drm *wl_drm);
+};
+
+static inline int
+wl_drm_add_listener(struct wl_drm *wl_drm,
+                   const struct wl_drm_listener *listener, void *data)
+{
+       return wl_proxy_add_listener((struct wl_proxy *) wl_drm,
+                                    (void (**)(void)) listener, data);
+}
+
+#define WL_DRM_AUTHENTICATE    0
+#define WL_DRM_CREATE_BUFFER   1
+#define WL_DRM_CREATE_PLANAR_BUFFER    2
+
+static inline void
+wl_drm_set_user_data(struct wl_drm *wl_drm, void *user_data)
+{
+       wl_proxy_set_user_data((struct wl_proxy *) wl_drm, user_data);
+}
+
+static inline void *
+wl_drm_get_user_data(struct wl_drm *wl_drm)
+{
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_drm);
+}
+
+static inline void
+wl_drm_destroy(struct wl_drm *wl_drm)
+{
+       wl_proxy_destroy((struct wl_proxy *) wl_drm);
+}
+
+static inline void
+wl_drm_authenticate(struct wl_drm *wl_drm, uint32_t id)
+{
+       wl_proxy_marshal((struct wl_proxy *) wl_drm,
+                        WL_DRM_AUTHENTICATE, id);
+}
+
+static inline struct wl_buffer *
+wl_drm_create_buffer(struct wl_drm *wl_drm, uint32_t name, int32_t width, int32_t height, uint32_t stride, uint32_t format)
+{
+       struct wl_proxy *id;
+
+       id = wl_proxy_create((struct wl_proxy *) wl_drm,
+                            &wl_buffer_interface);
+       if (!id)
+               return NULL;
+
+       wl_proxy_marshal((struct wl_proxy *) wl_drm,
+                        WL_DRM_CREATE_BUFFER, id, name, width, height, stride, format);
+
+       return (struct wl_buffer *) id;
+}
+
+static inline struct wl_buffer *
+wl_drm_create_planar_buffer(struct wl_drm *wl_drm, 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)
+{
+       struct wl_proxy *id;
+
+       id = wl_proxy_create((struct wl_proxy *) wl_drm,
+                            &wl_buffer_interface);
+       if (!id)
+               return NULL;
+
+       wl_proxy_marshal((struct wl_proxy *) wl_drm,
+                        WL_DRM_CREATE_PLANAR_BUFFER, id, name, width, height, format, offset0, stride0, offset1, stride1, offset2, stride2);
+
+       return (struct wl_buffer *) id;
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/util/wayland-drm-protocol.c b/util/wayland-drm-protocol.c
new file mode 100644 (file)
index 0000000..939af53
--- /dev/null
@@ -0,0 +1,74 @@
+/* 
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) /sizeof (a)[0])
+
+extern const struct wl_interface wl_buffer_interface;
+extern const struct wl_interface wl_buffer_interface;
+
+static const struct wl_interface *types[] = {
+       NULL,
+       &wl_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &wl_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+};
+
+static const struct wl_message wl_drm_requests[] = {
+       { "authenticate", "u", types + 0 },
+       { "create_buffer", "nuiiuu", types + 1 },
+       { "create_planar_buffer", "nuiiuiiiiii", types + 7 },
+};
+
+static const struct wl_message wl_drm_events[] = {
+       { "device", "s", types + 0 },
+       { "format", "u", types + 0 },
+       { "authenticated", "", types + 0 },
+};
+
+WL_EXPORT const struct wl_interface wl_drm_interface = {
+       "wl_drm", 1,
+       ARRAY_LENGTH(wl_drm_requests), wl_drm_requests,
+       ARRAY_LENGTH(wl_drm_events), wl_drm_events,
+};
+