791 lines
23 KiB
Diff
791 lines
23 KiB
Diff
From 31e75c3e5c4f59b603602420d2708588091a07b2 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 20 Jan 2016 12:22:29 -0500
|
|
Subject: [PATCH 1/6] wayland: unlink shm file earlier in create function
|
|
|
|
create_shm_pool unlinks the temporary file a little,
|
|
too late. It should be unlinked before ftruncate()
|
|
is called for two reasons:
|
|
|
|
1) if ftruncate fails, the file is currently not
|
|
getting cleaned up at all
|
|
2) in theory, if the file is public some other process
|
|
could muck with it
|
|
|
|
This commit just moves the unlink call a little higher
|
|
up.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=760897
|
|
---
|
|
gdk/wayland/gdkdisplay-wayland.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
|
|
index 97eebca..2f0c64e 100644
|
|
--- a/gdk/wayland/gdkdisplay-wayland.c
|
|
+++ b/gdk/wayland/gdkdisplay-wayland.c
|
|
@@ -914,73 +914,73 @@ buffer_release_callback (void *_data,
|
|
cairo_surface_t *surface = _data;
|
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
|
|
|
data->busy = FALSE;
|
|
cairo_surface_destroy (surface);
|
|
}
|
|
|
|
static const struct wl_buffer_listener buffer_listener = {
|
|
buffer_release_callback
|
|
};
|
|
|
|
static struct wl_shm_pool *
|
|
create_shm_pool (struct wl_shm *shm,
|
|
int width,
|
|
int height,
|
|
size_t *buf_length,
|
|
void **data_out)
|
|
{
|
|
char filename[] = "/tmp/wayland-shm-XXXXXX";
|
|
struct wl_shm_pool *pool;
|
|
int fd, size, stride;
|
|
void *data;
|
|
|
|
fd = mkstemp (filename);
|
|
if (fd < 0)
|
|
{
|
|
g_critical (G_STRLOC ": Unable to create temporary file (%s): %s",
|
|
filename, g_strerror (errno));
|
|
return NULL;
|
|
}
|
|
+ unlink (filename);
|
|
|
|
stride = width * 4;
|
|
size = stride * height;
|
|
if (ftruncate (fd, size) < 0)
|
|
{
|
|
g_critical (G_STRLOC ": Truncating temporary file failed: %s",
|
|
g_strerror (errno));
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
- unlink (filename);
|
|
|
|
if (data == MAP_FAILED)
|
|
{
|
|
g_critical (G_STRLOC ": mmap'ping temporary file failed: %s",
|
|
g_strerror (errno));
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
pool = wl_shm_create_pool (shm, fd, size);
|
|
|
|
close (fd);
|
|
|
|
*data_out = data;
|
|
*buf_length = size;
|
|
|
|
return pool;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_cairo_surface_destroy (void *p)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data = p;
|
|
|
|
if (data->buffer)
|
|
wl_buffer_destroy (data->buffer);
|
|
|
|
if (data->pool)
|
|
wl_shm_pool_destroy (data->pool);
|
|
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From 743f5ef21afe0c00aa572d49d197658aa9613a01 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 20 Jan 2016 11:40:34 -0500
|
|
Subject: [PATCH 2/6] wayland: clean up stride calculation when creating shm
|
|
surface
|
|
|
|
Right now, we assume the stride for the image surface needs to
|
|
be 4 byte aligned. This is, in fact, true, but it's better to
|
|
ask cairo for the alignment requirement directly rather than
|
|
assume we know the alignment rules.
|
|
|
|
This commit changes the code to use cairo_format_stride_for_width
|
|
to calculate a suitable rowstride for pixman.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=760897
|
|
---
|
|
gdk/wayland/gdkdisplay-wayland.c | 6 +++---
|
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
|
|
index 2f0c64e..bf3c20c 100644
|
|
--- a/gdk/wayland/gdkdisplay-wayland.c
|
|
+++ b/gdk/wayland/gdkdisplay-wayland.c
|
|
@@ -978,76 +978,76 @@ gdk_wayland_cairo_surface_destroy (void *p)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data = p;
|
|
|
|
if (data->buffer)
|
|
wl_buffer_destroy (data->buffer);
|
|
|
|
if (data->pool)
|
|
wl_shm_pool_destroy (data->pool);
|
|
|
|
munmap (data->buf, data->buf_length);
|
|
g_free (data);
|
|
}
|
|
|
|
cairo_surface_t *
|
|
_gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
|
|
int width,
|
|
int height,
|
|
guint scale)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data;
|
|
cairo_surface_t *surface = NULL;
|
|
cairo_status_t status;
|
|
int stride;
|
|
|
|
data = g_new (GdkWaylandCairoSurfaceData, 1);
|
|
data->display = display;
|
|
data->buffer = NULL;
|
|
data->scale = scale;
|
|
data->busy = FALSE;
|
|
|
|
- stride = width * 4;
|
|
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width*scale);
|
|
|
|
data->pool = create_shm_pool (display->shm,
|
|
width*scale, height*scale,
|
|
&data->buf_length,
|
|
&data->buf);
|
|
|
|
surface = cairo_image_surface_create_for_data (data->buf,
|
|
CAIRO_FORMAT_ARGB32,
|
|
width*scale,
|
|
height*scale,
|
|
- stride*scale);
|
|
+ stride);
|
|
|
|
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
|
width*scale, height*scale,
|
|
- stride*scale, WL_SHM_FORMAT_ARGB8888);
|
|
+ stride, WL_SHM_FORMAT_ARGB8888);
|
|
wl_buffer_add_listener (data->buffer, &buffer_listener, surface);
|
|
|
|
cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
|
|
data, gdk_wayland_cairo_surface_destroy);
|
|
|
|
cairo_surface_set_device_scale (surface, scale, scale);
|
|
|
|
status = cairo_surface_status (surface);
|
|
if (status != CAIRO_STATUS_SUCCESS)
|
|
{
|
|
g_critical (G_STRLOC ": Unable to create Cairo image surface: %s",
|
|
cairo_status_to_string (status));
|
|
}
|
|
|
|
return surface;
|
|
}
|
|
|
|
struct wl_buffer *
|
|
_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
|
return data->buffer;
|
|
}
|
|
|
|
void
|
|
_gdk_wayland_shm_surface_set_busy (cairo_surface_t *surface)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
|
data->busy = TRUE;
|
|
cairo_surface_reference (surface);
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From 2e704d3c0f7daaf38701d341186178c2adc442d1 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 20 Jan 2016 12:35:44 -0500
|
|
Subject: [PATCH 3/6] wayland: don't pass in width and height to
|
|
create_shm_pool
|
|
|
|
create_shm_pool doesn't need the width or height, it just needs
|
|
the total size. By passing it in, we're requiring it to redo
|
|
stride calculation unnecessarily.
|
|
|
|
This commit drops the width and height parameters and makes the
|
|
function just take the total size directly.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=760897
|
|
---
|
|
gdk/wayland/gdkdisplay-wayland.c | 9 +++------
|
|
1 file changed, 3 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
|
|
index bf3c20c..7c19a5c 100644
|
|
--- a/gdk/wayland/gdkdisplay-wayland.c
|
|
+++ b/gdk/wayland/gdkdisplay-wayland.c
|
|
@@ -897,81 +897,78 @@ gdk_wayland_display_get_xdg_shell (GdkDisplay *display)
|
|
|
|
static const cairo_user_data_key_t gdk_wayland_cairo_key;
|
|
|
|
typedef struct _GdkWaylandCairoSurfaceData {
|
|
gpointer buf;
|
|
size_t buf_length;
|
|
struct wl_shm_pool *pool;
|
|
struct wl_buffer *buffer;
|
|
GdkWaylandDisplay *display;
|
|
uint32_t scale;
|
|
gboolean busy;
|
|
} GdkWaylandCairoSurfaceData;
|
|
|
|
static void
|
|
buffer_release_callback (void *_data,
|
|
struct wl_buffer *wl_buffer)
|
|
{
|
|
cairo_surface_t *surface = _data;
|
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
|
|
|
data->busy = FALSE;
|
|
cairo_surface_destroy (surface);
|
|
}
|
|
|
|
static const struct wl_buffer_listener buffer_listener = {
|
|
buffer_release_callback
|
|
};
|
|
|
|
static struct wl_shm_pool *
|
|
create_shm_pool (struct wl_shm *shm,
|
|
- int width,
|
|
- int height,
|
|
+ int size,
|
|
size_t *buf_length,
|
|
void **data_out)
|
|
{
|
|
char filename[] = "/tmp/wayland-shm-XXXXXX";
|
|
struct wl_shm_pool *pool;
|
|
- int fd, size, stride;
|
|
+ int fd;
|
|
void *data;
|
|
|
|
fd = mkstemp (filename);
|
|
if (fd < 0)
|
|
{
|
|
g_critical (G_STRLOC ": Unable to create temporary file (%s): %s",
|
|
filename, g_strerror (errno));
|
|
return NULL;
|
|
}
|
|
unlink (filename);
|
|
|
|
- stride = width * 4;
|
|
- size = stride * height;
|
|
if (ftruncate (fd, size) < 0)
|
|
{
|
|
g_critical (G_STRLOC ": Truncating temporary file failed: %s",
|
|
g_strerror (errno));
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
if (data == MAP_FAILED)
|
|
{
|
|
g_critical (G_STRLOC ": mmap'ping temporary file failed: %s",
|
|
g_strerror (errno));
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
pool = wl_shm_create_pool (shm, fd, size);
|
|
|
|
close (fd);
|
|
|
|
*data_out = data;
|
|
*buf_length = size;
|
|
|
|
return pool;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_cairo_surface_destroy (void *p)
|
|
@@ -981,61 +978,61 @@ gdk_wayland_cairo_surface_destroy (void *p)
|
|
if (data->buffer)
|
|
wl_buffer_destroy (data->buffer);
|
|
|
|
if (data->pool)
|
|
wl_shm_pool_destroy (data->pool);
|
|
|
|
munmap (data->buf, data->buf_length);
|
|
g_free (data);
|
|
}
|
|
|
|
cairo_surface_t *
|
|
_gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
|
|
int width,
|
|
int height,
|
|
guint scale)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data;
|
|
cairo_surface_t *surface = NULL;
|
|
cairo_status_t status;
|
|
int stride;
|
|
|
|
data = g_new (GdkWaylandCairoSurfaceData, 1);
|
|
data->display = display;
|
|
data->buffer = NULL;
|
|
data->scale = scale;
|
|
data->busy = FALSE;
|
|
|
|
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width*scale);
|
|
|
|
data->pool = create_shm_pool (display->shm,
|
|
- width*scale, height*scale,
|
|
+ height*scale*stride,
|
|
&data->buf_length,
|
|
&data->buf);
|
|
|
|
surface = cairo_image_surface_create_for_data (data->buf,
|
|
CAIRO_FORMAT_ARGB32,
|
|
width*scale,
|
|
height*scale,
|
|
stride);
|
|
|
|
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
|
width*scale, height*scale,
|
|
stride, WL_SHM_FORMAT_ARGB8888);
|
|
wl_buffer_add_listener (data->buffer, &buffer_listener, surface);
|
|
|
|
cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
|
|
data, gdk_wayland_cairo_surface_destroy);
|
|
|
|
cairo_surface_set_device_scale (surface, scale, scale);
|
|
|
|
status = cairo_surface_status (surface);
|
|
if (status != CAIRO_STATUS_SUCCESS)
|
|
{
|
|
g_critical (G_STRLOC ": Unable to create Cairo image surface: %s",
|
|
cairo_status_to_string (status));
|
|
}
|
|
|
|
return surface;
|
|
}
|
|
|
|
struct wl_buffer *
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From 8717b4221f634e321aee80bc8accb60b6a24552d Mon Sep 17 00:00:00 2001
|
|
From: Matthias Clasen <mclasen@redhat.com>
|
|
Date: Thu, 21 Jan 2016 22:53:06 -0500
|
|
Subject: [PATCH 4/6] wayland: Don't hardcode /tmp
|
|
|
|
As pointed out in https://bugzilla.gnome.org/show_bug.cgi?id=760964,
|
|
we should use the GLib facilities for determining the preferred
|
|
location for temporary files.
|
|
---
|
|
gdk/wayland/gdkdisplay-wayland.c | 15 ++++++++++-----
|
|
1 file changed, 10 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
|
|
index 7c19a5c..5e88d96 100644
|
|
--- a/gdk/wayland/gdkdisplay-wayland.c
|
|
+++ b/gdk/wayland/gdkdisplay-wayland.c
|
|
@@ -901,95 +901,100 @@ typedef struct _GdkWaylandCairoSurfaceData {
|
|
gpointer buf;
|
|
size_t buf_length;
|
|
struct wl_shm_pool *pool;
|
|
struct wl_buffer *buffer;
|
|
GdkWaylandDisplay *display;
|
|
uint32_t scale;
|
|
gboolean busy;
|
|
} GdkWaylandCairoSurfaceData;
|
|
|
|
static void
|
|
buffer_release_callback (void *_data,
|
|
struct wl_buffer *wl_buffer)
|
|
{
|
|
cairo_surface_t *surface = _data;
|
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
|
|
|
data->busy = FALSE;
|
|
cairo_surface_destroy (surface);
|
|
}
|
|
|
|
static const struct wl_buffer_listener buffer_listener = {
|
|
buffer_release_callback
|
|
};
|
|
|
|
static struct wl_shm_pool *
|
|
create_shm_pool (struct wl_shm *shm,
|
|
int size,
|
|
size_t *buf_length,
|
|
void **data_out)
|
|
{
|
|
- char filename[] = "/tmp/wayland-shm-XXXXXX";
|
|
+ char *filename;
|
|
struct wl_shm_pool *pool;
|
|
int fd;
|
|
void *data;
|
|
|
|
+ filename = g_strconcat (g_get_tmp_dir (), G_DIR_SEPARATOR_S, "wayland-shm-XXXXXX", NULL);
|
|
fd = mkstemp (filename);
|
|
if (fd < 0)
|
|
{
|
|
g_critical (G_STRLOC ": Unable to create temporary file (%s): %s",
|
|
filename, g_strerror (errno));
|
|
+ g_free (filename);
|
|
return NULL;
|
|
}
|
|
unlink (filename);
|
|
|
|
if (ftruncate (fd, size) < 0)
|
|
{
|
|
- g_critical (G_STRLOC ": Truncating temporary file failed: %s",
|
|
- g_strerror (errno));
|
|
+ g_critical (G_STRLOC ": Truncating temporary file (%s) failed: %s",
|
|
+ filename, g_strerror (errno));
|
|
+ g_free (filename);
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
if (data == MAP_FAILED)
|
|
{
|
|
- g_critical (G_STRLOC ": mmap'ping temporary file failed: %s",
|
|
- g_strerror (errno));
|
|
+ g_critical (G_STRLOC ": mmap'ping temporary file (%s) failed: %s",
|
|
+ filename, g_strerror (errno));
|
|
+ g_free (filename);
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
pool = wl_shm_create_pool (shm, fd, size);
|
|
|
|
close (fd);
|
|
+ g_free (filename);
|
|
|
|
*data_out = data;
|
|
*buf_length = size;
|
|
|
|
return pool;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_cairo_surface_destroy (void *p)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data = p;
|
|
|
|
if (data->buffer)
|
|
wl_buffer_destroy (data->buffer);
|
|
|
|
if (data->pool)
|
|
wl_shm_pool_destroy (data->pool);
|
|
|
|
munmap (data->buf, data->buf_length);
|
|
g_free (data);
|
|
}
|
|
|
|
cairo_surface_t *
|
|
_gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
|
|
int width,
|
|
int height,
|
|
guint scale)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data;
|
|
cairo_surface_t *surface = NULL;
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From e9ba1539160378dbf484e5760c1e54ca0415f939 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 25 Jan 2016 11:41:23 -0500
|
|
Subject: [PATCH 5/6] wayland: use memfd_create instead of open in tmpdir
|
|
|
|
The tmpdir is used for a wide assortment of things, and
|
|
can easily fill up. If it fills then desktop will start
|
|
crashing with SIGBUS errors.
|
|
|
|
This commit changes the shm pool allocation code, to use
|
|
memfd_create, instead, so the shared memory files will
|
|
be anonymous and not associated with /tmp
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=761095
|
|
---
|
|
gdk/wayland/gdkdisplay-wayland.c | 28 ++++++++++++----------------
|
|
1 file changed, 12 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
|
|
index 5e88d96..360c489 100644
|
|
--- a/gdk/wayland/gdkdisplay-wayland.c
|
|
+++ b/gdk/wayland/gdkdisplay-wayland.c
|
|
@@ -1,55 +1,57 @@
|
|
/*
|
|
* Copyright © 2010 Intel Corporation
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
+#include <linux/memfd.h>
|
|
#include <sys/mman.h>
|
|
+#include <sys/syscall.h>
|
|
|
|
#include <glib.h>
|
|
#include "gdkwayland.h"
|
|
#include "gdkdisplay.h"
|
|
#include "gdkdisplay-wayland.h"
|
|
#include "gdkscreen.h"
|
|
#include "gdkinternals.h"
|
|
#include "gdkdeviceprivate.h"
|
|
#include "gdkdevicemanager.h"
|
|
#include "gdkkeysprivate.h"
|
|
#include "gdkprivate-wayland.h"
|
|
#include "gdkglcontext-wayland.h"
|
|
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
|
|
|
/**
|
|
* SECTION:wayland_interaction
|
|
* @Short_description: Wayland backend-specific functions
|
|
* @Title: Wayland Interaction
|
|
*
|
|
* The functions in this section are specific to the GDK Wayland backend.
|
|
* To use them, you need to include the `<gdk/gdkwayland.h>` header and use
|
|
* the Wayland-specific pkg-config files to build your application (either
|
|
* `gdk-wayland-3.0` or `gtk+-wayland-3.0`).
|
|
*
|
|
* To make your code compile with other GDK backends, guard backend-specific
|
|
* calls by an ifdef as follows. Since GDK may be built with multiple
|
|
* backends, you should also check for the backend that is in use (e.g. by
|
|
* using the GDK_IS_WAYLAND_DISPLAY() macro).
|
|
* |[<!-- language="C" -->
|
|
* #ifdef GDK_WINDOWING_WAYLAND
|
|
@@ -901,100 +903,94 @@ typedef struct _GdkWaylandCairoSurfaceData {
|
|
gpointer buf;
|
|
size_t buf_length;
|
|
struct wl_shm_pool *pool;
|
|
struct wl_buffer *buffer;
|
|
GdkWaylandDisplay *display;
|
|
uint32_t scale;
|
|
gboolean busy;
|
|
} GdkWaylandCairoSurfaceData;
|
|
|
|
static void
|
|
buffer_release_callback (void *_data,
|
|
struct wl_buffer *wl_buffer)
|
|
{
|
|
cairo_surface_t *surface = _data;
|
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
|
|
|
data->busy = FALSE;
|
|
cairo_surface_destroy (surface);
|
|
}
|
|
|
|
static const struct wl_buffer_listener buffer_listener = {
|
|
buffer_release_callback
|
|
};
|
|
|
|
static struct wl_shm_pool *
|
|
create_shm_pool (struct wl_shm *shm,
|
|
int size,
|
|
size_t *buf_length,
|
|
void **data_out)
|
|
{
|
|
- char *filename;
|
|
struct wl_shm_pool *pool;
|
|
- int fd;
|
|
+ int ret, fd;
|
|
void *data;
|
|
|
|
- filename = g_strconcat (g_get_tmp_dir (), G_DIR_SEPARATOR_S, "wayland-shm-XXXXXX", NULL);
|
|
- fd = mkstemp (filename);
|
|
- if (fd < 0)
|
|
+ ret = syscall (SYS_memfd_create, "gdk-wayland", MFD_CLOEXEC);
|
|
+
|
|
+ if (ret < 0)
|
|
{
|
|
- g_critical (G_STRLOC ": Unable to create temporary file (%s): %s",
|
|
- filename, g_strerror (errno));
|
|
- g_free (filename);
|
|
+ g_critical (G_STRLOC ": creating shared memory file failed: %s",
|
|
+ g_strerror (-ret));
|
|
return NULL;
|
|
}
|
|
- unlink (filename);
|
|
+
|
|
+ fd = ret;
|
|
|
|
if (ftruncate (fd, size) < 0)
|
|
{
|
|
- g_critical (G_STRLOC ": Truncating temporary file (%s) failed: %s",
|
|
- filename, g_strerror (errno));
|
|
- g_free (filename);
|
|
+ g_critical (G_STRLOC ": Truncating shared memory file failed: %m");
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
if (data == MAP_FAILED)
|
|
{
|
|
- g_critical (G_STRLOC ": mmap'ping temporary file (%s) failed: %s",
|
|
- filename, g_strerror (errno));
|
|
- g_free (filename);
|
|
+ g_critical (G_STRLOC ": mmap'ping shared memory file failed: %m");
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
pool = wl_shm_create_pool (shm, fd, size);
|
|
|
|
close (fd);
|
|
- g_free (filename);
|
|
|
|
*data_out = data;
|
|
*buf_length = size;
|
|
|
|
return pool;
|
|
}
|
|
|
|
static void
|
|
gdk_wayland_cairo_surface_destroy (void *p)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data = p;
|
|
|
|
if (data->buffer)
|
|
wl_buffer_destroy (data->buffer);
|
|
|
|
if (data->pool)
|
|
wl_shm_pool_destroy (data->pool);
|
|
|
|
munmap (data->buf, data->buf_length);
|
|
g_free (data);
|
|
}
|
|
|
|
cairo_surface_t *
|
|
_gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
|
|
int width,
|
|
int height,
|
|
guint scale)
|
|
{
|
|
GdkWaylandCairoSurfaceData *data;
|
|
cairo_surface_t *surface = NULL;
|
|
--
|
|
2.7.0
|
|
|
|
|
|
From ba8ce203ed2f1723b7f332fba1efb28f96f0a1c4 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 25 Jan 2016 13:55:25 -0500
|
|
Subject: [PATCH 6/6] wayland: __NR_memfd_create instead of SYS_memfd_create
|
|
|
|
It looks like the gnome-continuous headers haven't quite
|
|
caught up yet, so try __NR_memfd_create instead.
|
|
|
|
If that doesn't work, i'll likely just add in a fallback
|
|
code path.
|
|
---
|
|
gdk/wayland/gdkdisplay-wayland.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
|
|
index 360c489..f200800 100644
|
|
--- a/gdk/wayland/gdkdisplay-wayland.c
|
|
+++ b/gdk/wayland/gdkdisplay-wayland.c
|
|
@@ -907,61 +907,61 @@ typedef struct _GdkWaylandCairoSurfaceData {
|
|
GdkWaylandDisplay *display;
|
|
uint32_t scale;
|
|
gboolean busy;
|
|
} GdkWaylandCairoSurfaceData;
|
|
|
|
static void
|
|
buffer_release_callback (void *_data,
|
|
struct wl_buffer *wl_buffer)
|
|
{
|
|
cairo_surface_t *surface = _data;
|
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
|
|
|
data->busy = FALSE;
|
|
cairo_surface_destroy (surface);
|
|
}
|
|
|
|
static const struct wl_buffer_listener buffer_listener = {
|
|
buffer_release_callback
|
|
};
|
|
|
|
static struct wl_shm_pool *
|
|
create_shm_pool (struct wl_shm *shm,
|
|
int size,
|
|
size_t *buf_length,
|
|
void **data_out)
|
|
{
|
|
struct wl_shm_pool *pool;
|
|
int ret, fd;
|
|
void *data;
|
|
|
|
- ret = syscall (SYS_memfd_create, "gdk-wayland", MFD_CLOEXEC);
|
|
+ ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC);
|
|
|
|
if (ret < 0)
|
|
{
|
|
g_critical (G_STRLOC ": creating shared memory file failed: %s",
|
|
g_strerror (-ret));
|
|
return NULL;
|
|
}
|
|
|
|
fd = ret;
|
|
|
|
if (ftruncate (fd, size) < 0)
|
|
{
|
|
g_critical (G_STRLOC ": Truncating shared memory file failed: %m");
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
if (data == MAP_FAILED)
|
|
{
|
|
g_critical (G_STRLOC ": mmap'ping shared memory file failed: %m");
|
|
close (fd);
|
|
return NULL;
|
|
}
|
|
|
|
pool = wl_shm_create_pool (shm, fd, size);
|
|
|
|
close (fd);
|
|
|
|
--
|
|
2.7.0
|
|
|