[PATCH 3/3] Fix crashes in clients when no DRM is present.

Yuval Fledel yuvalfl at gmail.com
Mon Nov 29 11:41:50 PST 2010


When no DRM present, clients (window.c actually) now either exit orderly,
or if that check is removed - crash (unsurprisingly).
This patch relieves this assumption, and allow some clients (terminal,
image, flower) to run in a non-DRM environment

---
 clients/window.c |  129 ++++++++++++++++++++++++++++++------------------------
 1 files changed, 72 insertions(+), 57 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index ae55819..9ee13c7 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -453,10 +453,11 @@ display_create_surface(struct display *display,
 		       struct rectangle *rectangle)
 {
 #ifdef HAVE_CAIRO_GL
-	return display_create_drm_surface(display, rectangle);
-#else
-	return display_create_shm_surface(display, rectangle);
+	if (display->drm) {
+		return display_create_drm_surface(display, rectangle);
+	}
 #endif
+	return display_create_shm_surface(display, rectangle);
 }

 cairo_surface_t *
@@ -465,10 +466,11 @@ display_create_surface_from_file(struct display *display,
 				 struct rectangle *rectangle)
 {
 #ifdef HAVE_CAIRO_GL
-	return display_create_drm_surface_from_file(display, filename, rectangle);
-#else
-	return display_create_shm_surface_from_file(display, filename, rectangle);
+	if (display->drm) {
+		return display_create_drm_surface_from_file(display, filename, rectangle);
+	}
 #endif
+	return display_create_shm_surface_from_file(display, filename, rectangle);
 }

 static const struct {
@@ -1231,10 +1233,11 @@ window_create(struct display *display, const
char *title,
 	window->margin = 16;
 	window->decoration = 1;

-#ifdef HAVE_CAIRO_GL
-	window->buffer_type = WINDOW_BUFFER_TYPE_DRM;
-#else
 	window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
+#ifdef HAVE_CAIRO_GL
+	if (display->drm) {
+		window->buffer_type = WINDOW_BUFFER_TYPE_DRM;
+	}
 #endif

 	wl_surface_set_user_data(window->surface, window);
@@ -1391,16 +1394,69 @@ init_xkb(struct display *d)
 	}
 }

+static int
+display_drm_init(struct display *d)
+{
+	EGLint major, minor;
+	int fd;
+	drm_magic_t magic;
+
+	fd = open(d->device_name, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "drm open failed: %m\n");
+		return FALSE;
+	}
+
+	if (drmGetMagic(fd, &magic)) {
+		fprintf(stderr, "DRI2: failed to get drm magic");
+		return FALSE;
+	}
+
+	/* Wait for authenticated event */
+	wl_drm_authenticate(d->drm, magic);
+	wl_display_iterate(d->display, WL_DISPLAY_WRITABLE);
+	while (!d->authenticated)
+		wl_display_iterate(d->display, WL_DISPLAY_READABLE);
+
+	d->dpy = eglGetDRMDisplayMESA(fd);
+	if (!eglInitialize(d->dpy, &major, &minor)) {
+		fprintf(stderr, "failed to initialize display\n");
+		return FALSE;
+	}
+
+	if (!eglBindAPI(EGL_OPENGL_API)) {
+		fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
+		return FALSE;
+	}
+
+	d->ctx = eglCreateContext(d->dpy, NULL, EGL_NO_CONTEXT, NULL);
+	if (d->ctx == NULL) {
+		fprintf(stderr, "failed to create context\n");
+		return FALSE;
+	}
+
+	if (!eglMakeCurrent(d->dpy, NULL, NULL, d->ctx)) {
+		fprintf(stderr, "faile to make context current\n");
+		return FALSE;
+	}
+
+#ifdef HAVE_CAIRO_GL
+	d->device = cairo_egl_device_create(d->dpy, d->ctx);
+	if (d->device == NULL) {
+		fprintf(stderr, "failed to get cairo drm device\n");
+		return FALSE;
+	}
+#endif
+	return TRUE;
+}
+
 struct display *
 display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
 {
 	struct display *d;
-	EGLint major, minor;
-	int fd;
 	GOptionContext *context;
 	GOptionGroup *xkb_option_group;
 	GError *error;
-	drm_magic_t magic;

 	g_type_init();

@@ -1440,52 +1496,11 @@ display_create(int *argc, char **argv[], const
GOptionEntry *option_entries)
 	/* Process connection events. */
 	wl_display_iterate(d->display, WL_DISPLAY_READABLE);

-	fd = open(d->device_name, O_RDWR);
-	if (fd < 0) {
-		fprintf(stderr, "drm open failed: %m\n");
-		return NULL;
-	}
-
-	if (drmGetMagic(fd, &magic)) {
-		fprintf(stderr, "DRI2: failed to get drm magic");
-		return NULL;
-	}
-
-	/* Wait for authenticated event */
-	wl_drm_authenticate(d->drm, magic);
-	wl_display_iterate(d->display, WL_DISPLAY_WRITABLE);
-	while (!d->authenticated)
-		wl_display_iterate(d->display, WL_DISPLAY_READABLE);
-
-	d->dpy = eglGetDRMDisplayMESA(fd);
-	if (!eglInitialize(d->dpy, &major, &minor)) {
-		fprintf(stderr, "failed to initialize display\n");
-		return NULL;
-	}
-
-	if (!eglBindAPI(EGL_OPENGL_API)) {
-		fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
-		return NULL;
-	}
-
-	d->ctx = eglCreateContext(d->dpy, NULL, EGL_NO_CONTEXT, NULL);
-	if (d->ctx == NULL) {
-		fprintf(stderr, "failed to create context\n");
-		return NULL;
-	}
-
-	if (!eglMakeCurrent(d->dpy, NULL, NULL, d->ctx)) {
-		fprintf(stderr, "faile to make context current\n");
-		return NULL;
-	}
-
-#ifdef HAVE_CAIRO_GL
-	d->device = cairo_egl_device_create(d->dpy, d->ctx);
-	if (d->device == NULL) {
-		fprintf(stderr, "failed to get cairo drm device\n");
-		return NULL;
+	if (d->device_name) {
+		if (!display_drm_init(d)) {
+			return NULL;
+		}
 	}
-#endif

 	create_pointer_surfaces(d);

-- 
1.7.1


More information about the wayland-devel mailing list