From 1f85a0c047a55f19eaa92afb8bb6a758f7e02cbe Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 14 Jun 2011 16:13:52 +0200 Subject: 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 --- hw/xfree86/xwayland/xwayland-client.c | 111 +++++++++------------------------ hw/xfree86/xwayland/xwayland-drm.c | 62 +++++++++++++++++- hw/xfree86/xwayland/xwayland-input.c | 16 +---- hw/xfree86/xwayland/xwayland-private.h | 12 ++-- hw/xfree86/xwayland/xwayland.c | 53 ++-------------- 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 #include #include -#include +#include #include #include @@ -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) { -- cgit v1.2.3