summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorentin Chary <corentin.chary@gmail.com>2011-06-14 16:13:52 +0200
committerKristian Høgsberg <krh@bitplanet.net>2012-03-27 09:31:57 -0400
commit1f85a0c047a55f19eaa92afb8bb6a758f7e02cbe (patch)
tree512415b8e1872e2d6e6f927968e6bc00969681ac
parent36a370bd461a9d07b7ca6d36d8495f9bca9eb950 (diff)
xwayland: fix drm support
- use a dedicated drm global handler - introduce a better force_roundtrip helper, and use it in different places - also fix non-related input memory leaks Original patch by krh Signed-off-by: Corentin Chary <corentin.chary@gmail.com>
-rw-r--r--hw/xfree86/xwayland/xwayland-client.c111
-rw-r--r--hw/xfree86/xwayland/xwayland-drm.c62
-rw-r--r--hw/xfree86/xwayland/xwayland-input.c16
-rw-r--r--hw/xfree86/xwayland/xwayland-private.h12
-rw-r--r--hw/xfree86/xwayland/xwayland.c53
5 files changed, 104 insertions, 150 deletions
diff --git a/hw/xfree86/xwayland/xwayland-client.c b/hw/xfree86/xwayland/xwayland-client.c
index 944db6165..859cf626c 100644
--- a/hw/xfree86/xwayland/xwayland-client.c
+++ b/hw/xfree86/xwayland/xwayland-client.c
@@ -37,7 +37,6 @@
#include "xwayland.h"
#include "xwayland-private.h"
-#include "drm-client-protocol.h"
static void
compositor_handle_visual(void *data,
@@ -114,12 +113,6 @@ global_handler(struct wl_display *display,
wl_compositor_create (xwl_screen->display, id, 1);
wl_compositor_add_listener(xwl_screen->compositor,
&compositor_listener, xwl_screen);
-#ifdef WITH_LIBDRMM
- } else if (strcmp (interface, "wl_drm") == 0) {
- xwl_screen->drm = wl_drm_create (xwl_screen->display, id);
- wl_drm_add_listener (xwl_screen->drm,
- &drm_listener, xwl_screen);
-#endif
} else if (strcmp (interface, "wl_shm") == 0) {
xwl_screen->shm = wl_shm_create (xwl_screen->display, id, 1);
} else if (strcmp (interface, "wl_output") == 0) {
@@ -166,11 +159,30 @@ sync_callback(void *data)
*done = 1;
}
-int
-wayland_screen_init(struct xwl_screen *xwl_screen, int use_drm)
+void
+xwl_force_roundtrip(struct xwl_screen *xwl_screen)
{
int done = 0;
+ wl_display_sync_callback(xwl_screen->display, sync_callback, &done);
+ wl_display_iterate(xwl_screen->display, WL_DISPLAY_WRITABLE);
+ while (!done)
+ wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
+}
+
+int
+wayland_screen_init(struct xwl_screen *xwl_screen)
+{
+ AddGeneralSocket(xwl_screen->wayland_fd);
+ RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
+ return Success;
+}
+
+int
+wayland_screen_pre_init(struct xwl_screen *xwl_screen, int use_drm)
+{
+ int ret;
+
xwl_screen->display = wl_display_connect(NULL);
if (xwl_screen->display == NULL) {
ErrorF("wl_display_create failed\n");
@@ -186,37 +198,19 @@ wayland_screen_init(struct xwl_screen *xwl_screen, int use_drm)
wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
xwl_screen->wayland_fd =
- wl_display_get_fd(xwl_screen->display,
- source_update, xwl_screen);
-
- AddGeneralSocket(xwl_screen->wayland_fd);
- RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler,
- xwl_screen);
+ wl_display_get_fd(xwl_screen->display, source_update, xwl_screen);
#ifdef WITH_LIBDRM
- if (use_drm) {
- int ret;
-
- if ((ret = wayland_drm_screen_init(xwl_screen)) != Success)
- return ret;
-
- wl_display_iterate(xwl_screen->display, WL_DISPLAY_WRITABLE);
- while (!xwl_screen->authenticated)
- wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
- }
+ if (use_drm)
+ ret = xwl_drm_pre_init(xwl_screen);
+ if (use_drm && ret != Success)
+ return ret;
#endif
- if (!xwl_screen->premultiplied_argb_visual || !xwl_screen->rgb_visual) {
- wl_display_sync_callback(xwl_screen->display, sync_callback, &done);
- wl_display_iterate(xwl_screen->display, WL_DISPLAY_WRITABLE);
- while (!done)
- wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
- if (!xwl_screen->premultiplied_argb_visual ||
- !xwl_screen->rgb_visual) {
- ErrorF("visuals missing");
- exit(1);
- }
- }
+ if (!xwl_screen->premultiplied_argb_visual || !xwl_screen->rgb_visual)
+ xwl_force_roundtrip(xwl_screen);
+ if (!xwl_screen->premultiplied_argb_visual || !xwl_screen->rgb_visual)
+ return BadMatch;
return Success;
}
@@ -227,17 +221,10 @@ wayland_screen_close(struct xwl_screen *xwl_screen)
struct xwl_input_device *xwl_input_device, *itmp;
struct xwl_window *xwl_window, *wtmp;
- if (xwl_screen->global_listener)
- wl_display_remove_global_listener(xwl_screen->display,
- xwl_screen->global_listener);
-
if (xwl_screen->input_listener)
wl_display_remove_global_listener(xwl_screen->display,
xwl_screen->input_listener);
- if (xwl_screen->drm_fd >= 0)
- close(xwl_screen->drm_fd);
- free(xwl_screen->device_name);
list_for_each_entry_safe(xwl_input_device, itmp,
&xwl_screen->input_device_list, link) {
@@ -251,49 +238,13 @@ wayland_screen_close(struct xwl_screen *xwl_screen)
free(xwl_window);
}
-#ifdef WITH_LIBDRM
- if (xwl_screen->drm)
- wl_drm_destroy(xwl_screen->drm);
-#endif
- if (xwl_screen->shm)
- wl_shm_destroy(xwl_screen->shm);
- if (xwl_screen->argb_visual)
- wl_visual_destroy(xwl_screen->argb_visual);
- if (xwl_screen->rgb_visual)
- wl_visual_destroy(xwl_screen->rgb_visual);
- if (xwl_screen->argb_visual)
- wl_visual_destroy(xwl_screen->premultiplied_argb_visual);
- if (xwl_screen->xwl_output && xwl_screen->xwl_output->output) {
- wl_output_destroy(xwl_screen->xwl_output->output);
- }
- if (xwl_screen->compositor)
- wl_compositor_destroy(xwl_screen->compositor);
- if (xwl_screen->display) {
- RemoveGeneralSocket(xwl_screen->wayland_fd);
- wl_display_destroy(xwl_screen->display);
- }
-
- xwl_screen->drm_fd = -1;
- xwl_screen->wayland_fd = -1;
- xwl_screen->global_listener = NULL;
xwl_screen->input_listener = NULL;
- xwl_screen->display = NULL;
- xwl_screen->compositor = NULL;
- xwl_screen->drm = NULL;
- xwl_screen->shm = NULL;
- xwl_screen->argb_visual = NULL;
- xwl_screen->rgb_visual = NULL;
- xwl_screen->premultiplied_argb_visual = NULL;
- xwl_screen->mask = 0;
- xwl_screen->device_name = NULL;
- xwl_screen->authenticated = 0;
list_init(&xwl_screen->input_device_list);
list_init(&xwl_screen->damage_window_list);
list_init(&xwl_screen->window_list);
xwl_screen->root_x = 0;
xwl_screen->root_y = 0;
- if (xwl_screen->xwl_output)
- xwl_screen->xwl_output->output = NULL;
+ xwl_force_roundtrip(xwl_screen);
return Success;
}
diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
index 70497ce33..f02e0e9e8 100644
--- a/hw/xfree86/xwayland/xwayland-drm.c
+++ b/hw/xfree86/xwayland/xwayland-drm.c
@@ -33,7 +33,7 @@
#include <xf86drm.h>
#include <wayland-util.h>
#include <wayland-client.h>
-#include <wayland-drm-client-protocol.h>
+#include <drm-client-protocol.h>
#include <xf86Xinput.h>
#include <xf86Crtc.h>
@@ -62,17 +62,41 @@ drm_handle_authenticated (void *data, struct wl_drm *drm)
xwl_screen->authenticated = 1;
}
-static const struct wl_drm_listener drm_listener =
+const struct wl_drm_listener xwl_drm_listener =
{
drm_handle_device,
drm_handle_authenticated
};
+static void
+drm_handler(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version,
+ void *data)
+{
+ struct xwl_screen *xwl_screen = data;
+
+ if (strcmp (interface, "wl_drm") == 0) {
+ xwl_screen->drm = wl_drm_create (xwl_screen->display, id, 1);
+ wl_drm_add_listener (xwl_screen->drm, &xwl_drm_listener, xwl_screen);
+ }
+}
+
int
-wayland_drm_screen_init(struct xwl_screen *xwl_screen)
+xwl_drm_pre_init(struct xwl_screen *xwl_screen)
{
uint32_t magic;
+ xwl_screen->drm_listener =
+ wl_display_add_global_listener(xwl_screen->display,
+ drm_handler, xwl_screen);
+
+ xwl_force_roundtrip(xwl_screen);
+
+ 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) {
ErrorF("failed to open the drm fd\n");
@@ -85,5 +109,37 @@ wayland_drm_screen_init(struct xwl_screen *xwl_screen)
}
wl_drm_authenticate(xwl_screen->drm, magic);
+
+ xwl_force_roundtrip(xwl_screen);
+
+ ErrorF("opened drm fd: %d\n", xwl_screen->drm_fd);
+
+ if (!xwl_screen->authenticated) {
+ ErrorF("Failed to auth drm fd\n");
+ return BadAccess;
+ }
+
return Success;
}
+
+int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
+{
+ return xwl_screen->drm_fd;
+}
+
+#ifdef WITH_LIBDRM
+int
+xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
+ PixmapPtr pixmap, uint32_t name)
+{
+ xwl_window->buffer =
+ wl_drm_create_buffer(xwl_window->xwl_screen->drm,
+ name,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->devKind,
+ xwl_window->visual);
+
+ return xwl_window->buffer ? Success : BadDrawable;
+}
+#endif
diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
index 19a597408..118d20dff 100644
--- a/hw/xfree86/xwayland/xwayland-input.c
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -168,7 +168,6 @@ xwl_keyboard_proc(DeviceIntPtr device, int what)
static void
xwl_keyboard_uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
{
- xwl_keyboard_proc(pInfo->dev, DEVICE_OFF);
}
static int
@@ -196,7 +195,6 @@ _X_EXPORT InputDriverRec xwl_keyboard_driver = {
static void
xwl_pointer_uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
{
- xwl_pointer_proc(pInfo->dev, DEVICE_OFF);
}
static int
@@ -258,7 +256,6 @@ device_added(struct xwl_input_device *xwl_input_device, const char *driver)
InputAttributes attrs = {0};
DeviceIntPtr dev = NULL;
char *config_info = NULL;
- char *xwl_input_ptr = NULL;
char *name = NULL;
int rc;
@@ -267,11 +264,6 @@ device_added(struct xwl_input_device *xwl_input_device, const char *driver)
goto unwind;
}
- if (asprintf(&xwl_input_ptr, "%p", xwl_input_device) == -1) {
- xwl_input_ptr = NULL;
- goto unwind;
- }
-
name = config_info;
options = calloc(sizeof(*options), 1);
@@ -287,9 +279,6 @@ device_added(struct xwl_input_device *xwl_input_device, const char *driver)
add_option(&options, "config_info", config_info);
add_option(&options, "driver", driver);
- /* Wow ! super ugly ! */
- add_option(&options, "xwl_input_ptr", xwl_input_ptr);
-
if (strstr(driver, "keyboard"))
attrs.flags |= ATTR_KEYBOARD;
if (strstr(driver, "pointer"))
@@ -305,11 +294,8 @@ device_added(struct xwl_input_device *xwl_input_device, const char *driver)
pInfo->private = xwl_input_device;
}
- return dev;
-
unwind:
free(config_info);
- free(xwl_input_ptr);
while ((tmpo = options)) {
options = tmpo->next;
free(tmpo->key); /* NULL if dev != NULL */
@@ -317,7 +303,7 @@ unwind:
free(tmpo);
}
- return NULL;
+ return dev;
}
/* Use that code if the compositor want to delete an input device
diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
index 0ad2aa87e..83f0a561d 100644
--- a/hw/xfree86/xwayland/xwayland-private.h
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -49,6 +49,7 @@ struct xwl_screen {
struct wl_display *display;
struct wl_compositor *compositor;
struct wl_global_listener *global_listener;
+ struct wl_global_listener *drm_listener;
struct wl_global_listener *input_listener;
struct wl_drm *drm;
struct wl_shm *shm;
@@ -59,7 +60,6 @@ struct xwl_screen {
uint32_t flags;
char *device_name;
uint32_t authenticated;
- uint32_t input_initialized;
struct list input_device_list;
struct list damage_window_list;
struct list window_list;
@@ -102,16 +102,18 @@ struct xwl_input_device {
struct list link;
};
-struct xwl_output *
-xwl_output_create(struct xwl_screen *xwl_screen);
+struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen);
void xwl_input_teardown(pointer p);
pointer xwl_input_setup(pointer module, pointer opts, int *errmaj, int *errmin);
void xwl_input_init(struct xwl_screen *screen);
-int wayland_screen_init(struct xwl_screen *screen, int use_drm);
+void xwl_force_roundtrip(struct xwl_screen *xwl_screen);
+
+int wayland_screen_pre_init(struct xwl_screen *screen, int use_drm);
+int wayland_screen_init(struct xwl_screen *screen);
int wayland_screen_close(struct xwl_screen *screen);
-int wayland_drm_screen_init(struct xwl_screen *screen);
+int xwl_drm_pre_init(struct xwl_screen *screen);
#endif /* _XWAYLAND_PRIVATE_H_ */
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
index c78095829..17afda2db 100644
--- a/hw/xfree86/xwayland/xwayland.c
+++ b/hw/xfree86/xwayland/xwayland.c
@@ -47,11 +47,6 @@
#include "xwayland.h"
#include "xwayland-private.h"
-#include "drm-client-protocol.h"
-
-#ifdef WITH_LIBDRM
-#include "wayland-drm-client-protocol.h"
-#endif
/*
* TODO:
@@ -673,9 +668,6 @@ xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen)
{
miPointerScreenPtr pointer_priv;
- if (wayland_screen_init(xwl_screen, xwl_screen->driver->use_drm) != Success)
- return BadAlloc;
-
xwl_screen->screen = screen;
if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
@@ -709,6 +701,7 @@ xwl_screen_init(struct xwl_screen *xwl_screen, ScreenPtr screen)
xwl_screen->sprite_funcs = pointer_priv->spriteFuncs;
pointer_priv->spriteFuncs = &xwl_pointer_sprite_funcs;
+ wayland_screen_init(xwl_screen);
TimerSet(NULL, 0, 1, xwl_input_delayed_init, xwl_screen);
return Success;
}
@@ -718,6 +711,7 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo,
uint32_t flags, struct xwl_driver *driver)
{
struct xwl_screen *xwl_screen;
+ int ret;
xwl_screen = calloc(sizeof *xwl_screen, 1);
if (xwl_screen == NULL) {
@@ -741,31 +735,12 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo,
xf86InitialConfiguration(scrninfo, TRUE);
- return xwl_screen;
-}
-
-int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
-{
- return xwl_screen->drm_fd;
-}
-
-
-#ifdef WITH_LIBDRM
-int
-xwl_create_window_buffer_drm(struct xwl_window *xwl_window,
- PixmapPtr pixmap, uint32_t name)
-{
- xwl_window->buffer =
- wl_drm_create_buffer(xwl_window->xwl_screen->drm,
- name,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->devKind,
- xwl_window->visual);
+ ret = wayland_screen_pre_init(xwl_screen, xwl_screen->driver->use_drm);
+ if (ret != Success)
+ return NULL;
- return xwl_window->buffer ? Success : BadDrawable;
+ return xwl_screen;
}
-#endif
int
xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
@@ -782,7 +757,6 @@ xwl_create_window_buffer_shm(struct xwl_window *xwl_window,
void xwl_screen_close(struct xwl_screen *xwl_screen)
{
wayland_screen_close(xwl_screen);
- xwl_screen->input_initialized = 0;
}
void xwl_screen_destroy(struct xwl_screen *xwl_screen)
@@ -796,21 +770,6 @@ void xwl_screen_destroy(struct xwl_screen *xwl_screen)
free(xwl_screen);
}
-int xwl_screen_authenticate(struct xwl_screen *xwl_screen,
- uint32_t magic)
-{
- xwl_screen->authenticated = 0;
-#ifdef WITH_LIBDRM
- if (xwl_screen->drm)
- wl_drm_authenticate (xwl_screen->drm, magic);
-#endif
- wl_display_iterate (xwl_screen->display, WL_DISPLAY_WRITABLE);
- while (!xwl_screen->authenticated)
- wl_display_iterate (xwl_screen->display, WL_DISPLAY_READABLE);
-
- return Success;
-}
-
/* DDX driver must call this after submitting the rendering */
void xwl_screen_post_damage(struct xwl_screen *xwl_screen)
{