[PATCH] Add a FreeRds backend, take 6

2014-01-16 Thread Hardening
FreeRDS is a FreeRDP based RDP server, the server handles incoming connections 
and
talks RDP with the peers. FreeRds cooperates with an out-service: the 
out-service creates
the content to display, and FreeRds will take care of encoding the content in 
the
appropriate format (bitmapUpdate, remoteFx or NsCodec).
To communicate, they use a unix socket for passing commands, and a shared 
buffer for
the screen content. A vblank signal sent by FreeRds via the command channel 
allows
to share the framebuffer nicely.
This patch adds a backend to create a FreeRDS compositor and have weston being 
an out-service
for FreeRds.

This new revision uses the refcounting of IPC shm to have the last process that 
shmdt() to
remove the segment. It also fixes a bug with the damaged region not resetted on 
mode_switch()
leading to invalid read accesses.
---
 configure.ac |   12 +-
 src/Makefile.am  |   17 +-
 src/compositor-freerds.c | 1206 ++
 3 files changed, 1233 insertions(+), 2 deletions(-)
 create mode 100644 src/compositor-freerds.c

diff --git a/configure.ac b/configure.ac
index 571bf60..51f3197 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,7 +55,7 @@ AC_CHECK_DECL(CLOCK_MONOTONIC,[],
  [[#include time.h]])
 AC_CHECK_HEADERS([execinfo.h])
 
-AC_CHECK_FUNCS([mkostemp strchrnul initgroups posix_fallocate])
+AC_CHECK_FUNCS([accept4 mkostemp strchrnul initgroups posix_fallocate])
 
 COMPOSITOR_MODULES=wayland-server = 1.3.90 pixman-1
 
@@ -206,6 +206,15 @@ if test x$enable_rdp_compositor = xyes; then
   PKG_CHECK_MODULES(RDP_COMPOSITOR, [freerdp = 1.1.0])
 fi
 
+AC_ARG_ENABLE([freerds-compositor], [  --enable-freerds-compositor],,
+  enable_freerds_compositor=no)
+AM_CONDITIONAL([ENABLE_FREERDS_COMPOSITOR],
+   [test x$enable_freerds_compositor = xyes])
+if test x$enable_freerds_compositor = xyes; then
+  AC_DEFINE([BUILD_FREERDS_COMPOSITOR], [1], [Build the FreeRDS compositor])
+  PKG_CHECK_MODULES(FREERDS_COMPOSITOR, [freerds-backend])
+fi
+
 AC_ARG_WITH(cairo,
AS_HELP_STRING([--with-cairo=@:@image|gl|glesv2@:@]
   [Which Cairo renderer to use for the clients]),
@@ -526,6 +535,7 @@ AC_MSG_RESULT([
RPI Compositor  ${enable_rpi_compositor}
FBDEV Compositor${enable_fbdev_compositor}
RDP Compositor  ${enable_rdp_compositor}
+   FreeRDS Compositor  ${enable_freerds_compositor}
 
Raspberry Pi BCM headers${have_bcm_host}
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 446639c..588625e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -117,7 +117,9 @@ module_LTLIBRARIES =\
$(wayland_backend)  \
$(headless_backend) \
$(fbdev_backend)\
-   $(rdp_backend)
+   $(rdp_backend)  \
+   $(freerds_backend)
+   
 
 if INSTALL_RPI_COMPOSITOR
 module_LTLIBRARIES += $(rpi_backend)
@@ -280,6 +282,19 @@ rdp_backend_la_CFLAGS =\
 rdp_backend_la_SOURCES = compositor-rdp.c
 endif
 
+if ENABLE_FREERDS_COMPOSITOR
+freerds_backend = freerds-backend.la
+freerds_backend_la_LDFLAGS = -module -avoid-version
+freerds_backend_la_LIBADD = $(COMPOSITOR_LIBS) \
+   $(FREERDS_COMPOSITOR_LIBS) \
+   ../shared/libshared.la -lwinpr-input -lfreerdp-core
+freerds_backend_la_CFLAGS =\
+   $(COMPOSITOR_CFLAGS)\
+   $(FREERDS_COMPOSITOR_CFLAGS) \
+   $(GCC_CFLAGS)
+freerds_backend_la_SOURCES = compositor-freerds.c
+endif
+
 if HAVE_LCMS
 cms_static = cms-static.la
 cms_static_la_LDFLAGS = -module -avoid-version
diff --git a/src/compositor-freerds.c b/src/compositor-freerds.c
new file mode 100644
index 000..7e23f10
--- /dev/null
+++ b/src/compositor-freerds.c
@@ -0,0 +1,1206 @@
+/**
+ * Copyright © 2013 Hardening cont...@hardening-consulting.com
+ *
+ * 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
+ * 

[PATCH 2/4 v2] Add support to render-nodes.

2014-01-16 Thread Axel Davy
And allows to create wl_buffers from fds instead of gem names.

Signed-off-by: Axel Davy axel.d...@ens.fr
---
v2: fix indentation
 hw/xfree86/xwayland/drm.xml|  45 +-
 hw/xfree86/xwayland/xwayland-drm.c | 108 +
 hw/xfree86/xwayland/xwayland-private.h |   1 +
 hw/xfree86/xwayland/xwayland.h |   7 +++
 4 files changed, 147 insertions(+), 14 deletions(-)

diff --git a/hw/xfree86/xwayland/drm.xml b/hw/xfree86/xwayland/drm.xml
index 89fd8f0..8a3ad69 100644
--- a/hw/xfree86/xwayland/drm.xml
+++ b/hw/xfree86/xwayland/drm.xml
@@ -29,7 +29,7 @@
 
   !-- drm support. This object is created by the server and published
using the display's global event. --
-  interface name=wl_drm version=1
+  interface name=wl_drm version=2
 enum name=error
   entry name=authenticate_fail value=0/
   entry name=invalid_format value=1/
@@ -119,6 +119,38 @@
   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
@@ -134,6 +166,17 @@
 
 !-- 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
diff --git a/hw/xfree86/xwayland/xwayland-drm.c 
b/hw/xfree86/xwayland/xwayland-drm.c
index 30ec176..076fb68 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -29,6 +29,7 @@
 
 #include unistd.h
 #include fcntl.h
+#include sys/stat.h
 
 #include xf86drm.h
 #include wayland-util.h
@@ -99,11 +100,20 @@ drm_handle_authenticated (void *data, struct wl_drm *drm)
 }
 }
 
+static void
+drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
+{
+struct xwl_screen *xwl_screen = data;
+
+xwl_screen-drm_capabilities = value;
+}
+
 static const struct wl_drm_listener xwl_drm_listener =
 {
 drm_handle_device,
 drm_handle_format,
-drm_handle_authenticated
+drm_handle_authenticated,
+drm_handle_capabilities
 };
 
 static void
@@ -114,7 +124,7 @@ drm_handler(void *data, struct wl_registry *registry, 
uint32_t id,
 
 if (strcmp (interface, wl_drm) == 0) {
xwl_screen-drm = wl_registry_bind(xwl_screen-registry, id,
-   wl_drm_interface, 1);
+   wl_drm_interface, 2);
wl_drm_add_listener(xwl_screen-drm, xwl_drm_listener, xwl_screen);
 }
 }
@@ -130,6 +140,22 @@ static const struct wl_registry_listener drm_listener = {
 global_remove
 };
 
+static char
+is_fd_render_node(int fd)
+{
+struct stat render;
+
+if (fstat(fd, render))
+   return 0;
+
+if (!S_ISCHR(render.st_mode))
+   return 0;
+
+if (render.st_rdev  0x80)
+   return 1;
+return 0;
+}
+
 int
 xwl_drm_pre_init(struct xwl_screen *xwl_screen)
 {
@@ -137,7 +163,7 @@ xwl_drm_pre_init(struct xwl_screen *xwl_screen)
 
 xwl_screen-drm_registry = wl_display_get_registry(xwl_screen-display);
 wl_registry_add_listener(xwl_screen-drm_registry, drm_listener,
- xwl_screen);
+xwl_screen);
 
 /* Ensure drm_handler has seen all the interfaces */
 wl_display_roundtrip(xwl_screen-display);
@@ -153,20 +179,25 @@ xwl_drm_pre_init(struct xwl_screen *xwl_screen)
return BadAccess;
 }
 
-if (drmGetMagic(xwl_screen-drm_fd, magic)) {
-   

[PATCH 4/4 v2] Add XWayland API with Present support in mind.

2014-01-16 Thread Axel Davy
The API enables to use the frame event and the buffer event.

Signed-off-by: Axel Davy axel.d...@ens.fr
---
v2: fix indentation + move a call from patch 1 to here + add a missing call
 hw/xfree86/xwayland/Makefile.am|   1 +
 hw/xfree86/xwayland/xwayland-events.c  | 216 +
 hw/xfree86/xwayland/xwayland-private.h |   8 ++
 hw/xfree86/xwayland/xwayland-window.c  |   6 +
 hw/xfree86/xwayland/xwayland.h |  14 +++
 5 files changed, 245 insertions(+)
 create mode 100644 hw/xfree86/xwayland/xwayland-events.c

diff --git a/hw/xfree86/xwayland/Makefile.am b/hw/xfree86/xwayland/Makefile.am
index 22ab154..cc45444 100644
--- a/hw/xfree86/xwayland/Makefile.am
+++ b/hw/xfree86/xwayland/Makefile.am
@@ -21,6 +21,7 @@ libxwayland_la_SOURCES =  \
xwayland-output.c   \
xwayland-cursor.c   \
xwayland-window.c   \
+   xwayland-events.c   \
xwayland-private.h  \
drm-client-protocol.h   \
drm-protocol.c  \
diff --git a/hw/xfree86/xwayland/xwayland-events.c 
b/hw/xfree86/xwayland/xwayland-events.c
new file mode 100644
index 000..3a986bf
--- /dev/null
+++ b/hw/xfree86/xwayland/xwayland-events.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright © 2014 Axel Davy
+ *
+ * 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.
+ */
+
+
+#include unistd.h
+
+#include wayland-util.h
+#include wayland-client.h
+
+#include xf86Crtc.h
+#include xwayland.h
+#include xwayland-private.h
+
+
+/*
+ * Handling of frame events and buffer events.
+ * API to use them
+ */
+
+struct _todo
+{
+union
+{
+   todo_func_frame tff;
+   todo_func_buffer tfb;
+} tocall;
+void *args;
+struct wl_list link;
+};
+
+static void
+event_todo_free(struct wl_list *todo_list)
+{
+struct _todo *pos, *tmp;
+wl_list_for_each_safe(pos, tmp, todo_list, link) {
+   wl_list_remove(pos-link);
+   free(pos);
+}
+}
+
+static const struct wl_callback_listener frame_listener;
+
+static void
+frame_listener_callback(void *data,
+   struct wl_callback *callback, uint32_t time)
+{
+struct xwl_window *xwl_window = data;
+struct wl_list todo_list;
+struct _todo *todo;
+
+wl_callback_destroy(xwl_window-frame_callback);
+xwl_window-frame_callback = wl_surface_frame(xwl_window-surface);
+wl_callback_add_listener(xwl_window-frame_callback,
+frame_listener, xwl_window);
+
+if (wl_list_empty(xwl_window-frame_todo))
+   return;
+
+/* todo funcs are able to ask to be recalled */
+
+wl_list_init(todo_list);
+wl_list_insert_list(todo_list, xwl_window-frame_todo);
+wl_list_init(xwl_window-frame_todo);
+wl_list_for_each(todo, todo_list, link)
+   todo-tocall.tff(0, time, todo-args);
+event_todo_free(todo_list);
+
+/* We need to commit to let the compositor know the new frame callback */
+if (!wl_list_empty(xwl_window-frame_todo)) {
+   /* reverse the list. It is useful to keep the order between two
+* waiting functions that keep adding themselves to the todo list */
+   wl_list_init(todo_list);
+   wl_list_insert_list(todo_list, xwl_window-frame_todo);
+   wl_list_init(xwl_window-frame_todo);
+   wl_list_for_each(todo, todo_list, link)
+   wl_list_insert(xwl_window-frame_todo, todo-link);
+   wl_surface_commit(xwl_window-surface);
+}
+}
+
+
+
+static const struct wl_callback_listener frame_listener = {
+frame_listener_callback
+};
+
+
+static void
+wl_buffer_release_event(void *data, struct wl_buffer *buffer)
+{
+struct xwl_pixmap *xwl_pixmap = data;
+struct wl_list todo_list;
+struct _todo *todo;
+
+if 

[PATCH 1/4 v2] Move the wl_buffer from xwl_window to xwl_pixmap

2014-01-16 Thread Axel Davy
This change enables to change the window pixmap, and have
xwayland send the correct buffer to the Wayland compositor.

Signed-off-by: Axel Davy axel.d...@ens.fr
---
v2: fix indentation and remove a call that had to be in patch 4
 hw/xfree86/xwayland/xwayland-drm.c | 10 +++-
 hw/xfree86/xwayland/xwayland-private.h | 10 +++-
 hw/xfree86/xwayland/xwayland-window.c  | 83 +-
 hw/xfree86/xwayland/xwayland.c | 38 ++--
 4 files changed, 113 insertions(+), 28 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-drm.c 
b/hw/xfree86/xwayland/xwayland-drm.c
index 5250857..30ec176 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -217,6 +217,7 @@ xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
 VisualID visual;
 WindowPtr window = xwl_window-window;
 ScreenPtr screen = window-drawable.pScreen;
+struct wl_buffer *buffer;
 uint32_t format;
 int i;
 
@@ -238,7 +239,7 @@ xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
 break;
 }
 
-xwl_window-buffer =
+buffer =
   wl_drm_create_buffer(xwl_window-xwl_screen-drm,
   name,
   pixmap-drawable.width,
@@ -246,5 +247,10 @@ xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
   pixmap-devKind,
   format);
 
-return xwl_window-buffer ? Success : BadDrawable;
+if (!buffer)
+   return BadDrawable;
+
+xwl_pixmap_attach_buffer(pixmap, buffer);
+
+return Success;
 }
diff --git a/hw/xfree86/xwayland/xwayland-private.h 
b/hw/xfree86/xwayland/xwayland-private.h
index bdecf8a..853ab3b 100644
--- a/hw/xfree86/xwayland/xwayland-private.h
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -29,13 +29,16 @@
 struct xwl_window {
 struct xwl_screen  *xwl_screen;
 struct wl_surface  *surface;
-struct wl_buffer   *buffer;
 WindowPtr   window;
 DamagePtr   damage;
 struct xorg_listlink;
 struct xorg_listlink_damage;
 };
 
+struct xwl_pixmap {
+struct wl_buffer   *buffer;
+};
+
 struct xwl_output;
 
 struct xwl_screen {
@@ -72,6 +75,7 @@ struct xwl_screen {
 RealizeWindowProcPtrRealizeWindow;
 UnrealizeWindowProcPtr  UnrealizeWindow;
 SetWindowPixmapProcPtr  SetWindowPixmap;
+DestroyPixmapProcPtrDestroyPixmap;
 MoveWindowProcPtr   MoveWindow;
 miPointerSpriteFuncPtr  sprite_funcs;
 };
@@ -135,6 +139,10 @@ void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
 
 void xwl_output_remove(struct xwl_output *output);
 
+void xwl_pixmap_attach_buffer(PixmapPtr pixmap, struct wl_buffer *buffer);
+struct xwl_pixmap *xwl_window_get_buffer(struct xwl_window *xwl_window);
+struct xwl_window *get_xwl_window(WindowPtr window);
+
 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
index a2a8206..1e6c09b 100644
--- a/hw/xfree86/xwayland/xwayland-window.c
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -41,6 +41,13 @@
 #include xserver-client-protocol.h
 
 static DevPrivateKeyRec xwl_window_private_key;
+static DevPrivateKeyRec xwl_pixmap_private_key;
+
+struct xwl_window *
+get_xwl_window(WindowPtr window)
+{
+return dixLookupPrivate(window-devPrivates, xwl_window_private_key);
+}
 
 static void
 free_pixmap(void *data, struct wl_callback *callback, uint32_t time)
@@ -56,25 +63,38 @@ static const struct wl_callback_listener 
free_pixmap_listener = {
free_pixmap,
 };
 
+void
+xwl_pixmap_attach_buffer(PixmapPtr pixmap, struct wl_buffer *buffer)
+{
+struct xwl_pixmap *xwl_pixmap = calloc(sizeof *xwl_pixmap, 1);
+if (!xwl_pixmap) {
+   wl_buffer_destroy(buffer);
+   return;
+}
+xwl_pixmap-buffer = buffer;
+dixSetPrivate(pixmap-devPrivates, xwl_pixmap_private_key, xwl_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;
+struct xwl_pixmap *xwl_pixmap =
+   dixLookupPrivate(pixmap-devPrivates, xwl_pixmap_private_key);
 
-/* 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_pixmap) {
+   xwl_screen-driver-create_window_buffer(xwl_window, pixmap);
+   xwl_pixmap =
+   dixLookupPrivate(pixmap-devPrivates, xwl_pixmap_private_key);
 
-if (!xwl_window-buffer) {
-ErrorF(failed to create buffer\n);
-   return;
+   if (!xwl_pixmap) {
+   ErrorF(failed to create buffer\n);
+   return;
+

[PATCH 3/4 v2] Add function to get new fd of the graphic device

2014-01-16 Thread Axel Davy
neccessary for dri3

Signed-off-by: Axel Davy axel.d...@ens.fr
---
v2: fix indentation
 hw/xfree86/xwayland/xwayland-drm.c | 56 --
 hw/xfree86/xwayland/xwayland.h |  3 ++
 2 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-drm.c 
b/hw/xfree86/xwayland/xwayland-drm.c
index 076fb68..12011bf 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -157,49 +157,63 @@ is_fd_render_node(int fd)
 }
 
 int
-xwl_drm_pre_init(struct xwl_screen *xwl_screen)
+xwl_device_get_fd(struct xwl_screen *xwl_screen)
 {
 uint32_t magic;
+int fd;
 
-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) {
+fd = open(xwl_screen-device_name, O_RDWR);
+if (fd  0) {
ErrorF(failed to open the drm fd\n);
-   return BadAccess;
+   return -1;
 }
 
-if (!is_fd_render_node(xwl_screen-drm_fd)) {
+if (!is_fd_render_node(fd)) {
 
-   if (drmGetMagic(xwl_screen-drm_fd, magic)) {
+   if (drmGetMagic(fd, magic)) {
ErrorF(failed to get drm magic);
-   return BadAccess;
+   close (fd);
+   return -1;
}
 
wl_drm_authenticate(xwl_screen-drm, magic);
 
wl_display_roundtrip(xwl_screen-display);
 
-   ErrorF(opened drm fd: %d\n, xwl_screen-drm_fd);
+   ErrorF(opened drm fd: %d\n, fd);
 
if (!xwl_screen-authenticated) {
ErrorF(Failed to auth drm fd\n);
-   return BadAccess;
+   close (fd);
+   return -1;
}
 } else {
xwl_screen-authenticated = 1;
 }
 
+return fd;
+}
+
+int
+xwl_drm_pre_init(struct xwl_screen *xwl_screen)
+{
+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 = xwl_device_get_fd(xwl_screen);
+if (xwl_screen-drm_fd  0) {
+   return BadAccess;
+}
+
 return Success;
 }
 
diff --git a/hw/xfree86/xwayland/xwayland.h b/hw/xfree86/xwayland/xwayland.h
index 8e484a1..c380618 100644
--- a/hw/xfree86/xwayland/xwayland.h
+++ b/hw/xfree86/xwayland/xwayland.h
@@ -76,6 +76,9 @@ xwl_drm_authenticate(ClientPtr client, struct xwl_screen 
*xwl_screen,
 uint32_t magic);
 
 extern _X_EXPORT int
+xwl_device_get_fd(struct xwl_screen *xwl_screen);
+
+extern _X_EXPORT int
 xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
 PixmapPtr pixmap, uint32_t name);
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH wayland] protocol: Clarify semantics of sub-surface placement requests

2014-01-16 Thread Jonas Ådahl
Clarify some semantics of wl_subsurface.place_below and
wl_subsurface.place_below that were not specified.

Signed-off-by: Jonas Ådahl jad...@gmail.com
---

Hi,

Implementing support for sub-surfaces in mutter we ran in to some
unspecified behaviour in the subsurface placement protocol.

I have documented what I understand is how the implementation in weston
works (please correct me if I'm wrong). Is this the intended semantics?

Jonas

 protocol/wayland.xml | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 61fde84..619567c 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -1952,6 +1952,12 @@
 
A new sub-surface is initially added as the top-most in the stack
of its siblings and parent.
+
+   Between two sub-surface parent commits, the stacking of surfaces in a
+   sub-surface tree are executed as operations in the same order as the
+   requests were made. A placement request may alter two surfaces relative
+   placement by placing itself in-between. A subsequent placement request
+   to a sub-surface replaces any previous requests.
   /description
 
   arg name=sibling type=object interface=wl_surface
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 2/2] gl-renderer: Use eglSwapBuffersWithDamageEXT when available

2014-01-16 Thread Jason Ekstrand
Signed-off-by: Jason Ekstrand ja...@jlekstrand.net
---

The second version properly sets the EGL_SWAP_BEHAVIOR surface attribute to
EGL_BUFFER_PRESERVED.

 src/gl-renderer.c | 104 +-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index c8dfa4b..eddf481 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -124,6 +124,8 @@ struct gl_renderer {
PFNEGLCREATEIMAGEKHRPROC create_image;
PFNEGLDESTROYIMAGEKHRPROC destroy_image;
 
+   PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;
+
int has_unpack_subimage;
 
PFNEGLBINDWAYLANDDISPLAYWL bind_display;
@@ -677,6 +679,17 @@ draw_output_border_texture(struct gl_output_state *go,
glDisableVertexAttribArray(0);
 }
 
+static int
+output_has_borders(struct weston_output *output)
+{
+   struct gl_output_state *go = get_output_state(output);
+
+   return go-borders[GL_RENDERER_BORDER_TOP].data ||
+  go-borders[GL_RENDERER_BORDER_RIGHT].data ||
+  go-borders[GL_RENDERER_BORDER_BOTTOM].data ||
+  go-borders[GL_RENDERER_BORDER_LEFT].data;
+}
+
 static void
 draw_output_borders(struct weston_output *output,
enum gl_border_status border_status)
@@ -732,6 +745,43 @@ draw_output_borders(struct weston_output *output,
 }
 
 static void
+output_get_border_damage(struct weston_output *output,
+enum gl_border_status border_status,
+pixman_region32_t *damage)
+{
+   struct gl_output_state *go = get_output_state(output);
+   struct gl_border_image *top, *bottom, *left, *right;
+   int full_width, full_height;
+
+   if (border_status == BORDER_STATUS_CLEAN)
+   return; /* Clean. Nothing to do. */
+
+   top = go-borders[GL_RENDERER_BORDER_TOP];
+   bottom = go-borders[GL_RENDERER_BORDER_BOTTOM];
+   left = go-borders[GL_RENDERER_BORDER_LEFT];
+   right = go-borders[GL_RENDERER_BORDER_RIGHT];
+
+   full_width = output-current_mode-width + left-width + right-width;
+   full_height = output-current_mode-height + top-height + 
bottom-height;
+   if (border_status  BORDER_TOP_DIRTY)
+   pixman_region32_union_rect(damage, damage,
+  0, 0,
+  full_width, top-height);
+   if (border_status  BORDER_LEFT_DIRTY)
+   pixman_region32_union_rect(damage, damage,
+  0, top-height,
+  left-width, 
output-current_mode-height);
+   if (border_status  BORDER_RIGHT_DIRTY)
+   pixman_region32_union_rect(damage, damage,
+  full_width - right-width, 
top-height,
+  right-width, 
output-current_mode-height);
+   if (border_status  BORDER_BOTTOM_DIRTY)
+   pixman_region32_union_rect(damage, damage,
+  0, full_height - bottom-height,
+  full_width, bottom-height);
+}
+
+static void
 output_get_damage(struct weston_output *output,
  pixman_region32_t *buffer_damage, uint32_t *border_damage)
 {
@@ -802,6 +852,9 @@ gl_renderer_repaint_output(struct weston_output *output,
struct gl_renderer *gr = get_renderer(compositor);
EGLBoolean ret;
static int errored;
+   int i, nrects, buffer_height;
+   EGLint *egl_damage, *d;
+   pixman_box32_t *rects;
pixman_region32_t buffer_damage, total_damage;
enum gl_border_status border_damage = BORDER_STATUS_CLEAN;
 
@@ -847,7 +900,44 @@ gl_renderer_repaint_output(struct weston_output *output,
pixman_region32_copy(output-previous_damage, output_damage);
wl_signal_emit(output-frame_signal, output);
 
-   ret = eglSwapBuffers(gr-egl_display, go-egl_surface);
+   if (gr-swap_buffers_with_damage  gr-has_egl_buffer_age) {
+   pixman_region32_init(buffer_damage);
+   weston_transformed_region(output-width, output-height,
+ output-transform,
+ output-current_scale,
+ output_damage, buffer_damage);
+
+   if (output_has_borders(output)) {
+   pixman_region32_translate(buffer_damage,
+ 
go-borders[GL_RENDERER_BORDER_LEFT].width,
+ 
go-borders[GL_RENDERER_BORDER_TOP].height);
+   output_get_border_damage(output, go-border_status,
+buffer_damage);
+   }
+
+   rects = pixman_region32_rectangles(buffer_damage, nrects);
+   egl_damage = 

Re: [PATCH 2/2] gl-renderer: Use eglSwapBuffersWithDamageEXT when available

2014-01-16 Thread Jason Ekstrand
Never mind, the first one was correct. I misunderstood buffer age.
--Jason
On Jan 16, 2014 10:52 PM, Jason Ekstrand ja...@jlekstrand.net wrote:

 Signed-off-by: Jason Ekstrand ja...@jlekstrand.net
 ---

 The second version properly sets the EGL_SWAP_BEHAVIOR surface attribute to
 EGL_BUFFER_PRESERVED.

  src/gl-renderer.c | 104
 +-
  1 file changed, 103 insertions(+), 1 deletion(-)

 diff --git a/src/gl-renderer.c b/src/gl-renderer.c
 index c8dfa4b..eddf481 100644
 --- a/src/gl-renderer.c
 +++ b/src/gl-renderer.c
 @@ -124,6 +124,8 @@ struct gl_renderer {
 PFNEGLCREATEIMAGEKHRPROC create_image;
 PFNEGLDESTROYIMAGEKHRPROC destroy_image;

 +   PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;
 +
 int has_unpack_subimage;

 PFNEGLBINDWAYLANDDISPLAYWL bind_display;
 @@ -677,6 +679,17 @@ draw_output_border_texture(struct gl_output_state *go,
 glDisableVertexAttribArray(0);
  }

 +static int
 +output_has_borders(struct weston_output *output)
 +{
 +   struct gl_output_state *go = get_output_state(output);
 +
 +   return go-borders[GL_RENDERER_BORDER_TOP].data ||
 +  go-borders[GL_RENDERER_BORDER_RIGHT].data ||
 +  go-borders[GL_RENDERER_BORDER_BOTTOM].data ||
 +  go-borders[GL_RENDERER_BORDER_LEFT].data;
 +}
 +
  static void
  draw_output_borders(struct weston_output *output,
 enum gl_border_status border_status)
 @@ -732,6 +745,43 @@ draw_output_borders(struct weston_output *output,
  }

  static void
 +output_get_border_damage(struct weston_output *output,
 +enum gl_border_status border_status,
 +pixman_region32_t *damage)
 +{
 +   struct gl_output_state *go = get_output_state(output);
 +   struct gl_border_image *top, *bottom, *left, *right;
 +   int full_width, full_height;
 +
 +   if (border_status == BORDER_STATUS_CLEAN)
 +   return; /* Clean. Nothing to do. */
 +
 +   top = go-borders[GL_RENDERER_BORDER_TOP];
 +   bottom = go-borders[GL_RENDERER_BORDER_BOTTOM];
 +   left = go-borders[GL_RENDERER_BORDER_LEFT];
 +   right = go-borders[GL_RENDERER_BORDER_RIGHT];
 +
 +   full_width = output-current_mode-width + left-width +
 right-width;
 +   full_height = output-current_mode-height + top-height +
 bottom-height;
 +   if (border_status  BORDER_TOP_DIRTY)
 +   pixman_region32_union_rect(damage, damage,
 +  0, 0,
 +  full_width, top-height);
 +   if (border_status  BORDER_LEFT_DIRTY)
 +   pixman_region32_union_rect(damage, damage,
 +  0, top-height,
 +  left-width,
 output-current_mode-height);
 +   if (border_status  BORDER_RIGHT_DIRTY)
 +   pixman_region32_union_rect(damage, damage,
 +  full_width - right-width,
 top-height,
 +  right-width,
 output-current_mode-height);
 +   if (border_status  BORDER_BOTTOM_DIRTY)
 +   pixman_region32_union_rect(damage, damage,
 +  0, full_height - bottom-height,
 +  full_width, bottom-height);
 +}
 +
 +static void
  output_get_damage(struct weston_output *output,
   pixman_region32_t *buffer_damage, uint32_t
 *border_damage)
  {
 @@ -802,6 +852,9 @@ gl_renderer_repaint_output(struct weston_output
 *output,
 struct gl_renderer *gr = get_renderer(compositor);
 EGLBoolean ret;
 static int errored;
 +   int i, nrects, buffer_height;
 +   EGLint *egl_damage, *d;
 +   pixman_box32_t *rects;
 pixman_region32_t buffer_damage, total_damage;
 enum gl_border_status border_damage = BORDER_STATUS_CLEAN;

 @@ -847,7 +900,44 @@ gl_renderer_repaint_output(struct weston_output
 *output,
 pixman_region32_copy(output-previous_damage, output_damage);
 wl_signal_emit(output-frame_signal, output);

 -   ret = eglSwapBuffers(gr-egl_display, go-egl_surface);
 +   if (gr-swap_buffers_with_damage  gr-has_egl_buffer_age) {
 +   pixman_region32_init(buffer_damage);
 +   weston_transformed_region(output-width, output-height,
 + output-transform,
 + output-current_scale,
 + output_damage, buffer_damage);
 +
 +   if (output_has_borders(output)) {
 +   pixman_region32_translate(buffer_damage,
 +
 go-borders[GL_RENDERER_BORDER_LEFT].width,
 +
 go-borders[GL_RENDERER_BORDER_TOP].height);
 +   output_get_border_damage(output, go-border_status,
 +