[PATCH v3 xserver 1/2] xwayland: Port to Wayland 1.0 API
Kristian Høgsberg
hoegsberg at gmail.com
Tue Nov 27 14:21:30 PST 2012
On Thu, Nov 22, 2012 at 06:08:52PM -0200, Tiago Vignatti wrote:
> Co-authored-by: Daniel Stone <daniel at fooishbar.org>
> Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
> ---
> changes from v2:
> - fix wl_registry_bind client version
> - clean-up xwl_drm_authenticate round trips
> - use wl_display_dispatch_pending properly, just before going to sleep at
> block handler.
> - place wl_surface_commit in its correct place. hopefully.
Yeah, this is fine. This and the 5 fixes committed. I rewrote the
axis scaling patch to use the POINTER_SCREEN flag instead when posting
events.
Kristian
> hw/xfree86/xwayland/xwayland-cursor.c | 40 +++++++++-----
> hw/xfree86/xwayland/xwayland-drm.c | 33 +++++++-----
> hw/xfree86/xwayland/xwayland-input.c | 34 +++++++-----
> hw/xfree86/xwayland/xwayland-output.c | 53 +++++++++---------
> hw/xfree86/xwayland/xwayland-private.h | 12 +++--
> hw/xfree86/xwayland/xwayland-window.c | 1 +
> hw/xfree86/xwayland/xwayland.c | 92 +++++++++++++++-----------------
> 7 files changed, 144 insertions(+), 121 deletions(-)
>
> diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c
> index f69601a..f8860bd 100644
> --- a/hw/xfree86/xwayland/xwayland-cursor.c
> +++ b/hw/xfree86/xwayland/xwayland-cursor.c
> @@ -147,16 +147,35 @@ xwl_unrealize_cursor(DeviceIntPtr device,
> return TRUE;
> }
>
> +void
> +xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
> +{
> + struct wl_buffer *buffer;
> +
> + if (!xwl_seat->x_cursor || !xwl_seat->wl_pointer)
> + return;
> +
> + buffer = dixGetPrivate(&xwl_seat->x_cursor->devPrivates,
> + &xwl_cursor_private_key);
> +
> + wl_pointer_set_cursor(xwl_seat->wl_pointer,
> + xwl_seat->pointer_enter_serial,
> + xwl_seat->cursor,
> + xwl_seat->x_cursor->bits->xhot,
> + xwl_seat->x_cursor->bits->yhot);
> + wl_surface_attach(xwl_seat->cursor, buffer, 0, 0);
> + wl_surface_damage(xwl_seat->cursor, 0, 0,
> + xwl_seat->x_cursor->bits->width,
> + xwl_seat->x_cursor->bits->height);
> + wl_surface_commit(xwl_seat->cursor);
> +}
> +
> static void
> xwl_set_cursor(DeviceIntPtr device,
> ScreenPtr screen, CursorPtr cursor, int x, int y)
> {
> struct xwl_screen *xwl_screen;
> struct xwl_seat *xwl_seat;
> - struct wl_buffer *buffer;
> -
> - if (!cursor)
> - return;
>
> xwl_screen = xwl_screen_get(screen);
>
> @@ -164,17 +183,10 @@ xwl_set_cursor(DeviceIntPtr device,
> return;
>
> xwl_seat = xorg_list_first_entry(&xwl_screen->seat_list,
> - struct xwl_seat, link);
> -
> - buffer = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key);
> + struct xwl_seat, link);
>
> - wl_pointer_set_cursor(xwl_seat->wl_pointer,
> - xwl_seat->pointer_enter_serial,
> - xwl_seat->cursor,
> - cursor->bits->xhot, cursor->bits->yhot);
> - wl_surface_attach(xwl_seat->cursor, buffer, 0, 0);
> - wl_surface_damage(xwl_seat->cursor, 0, 0,
> - cursor->bits->width, cursor->bits->height);
> + xwl_seat->x_cursor = cursor;
> + xwl_seat_set_cursor(xwl_seat);
> }
>
> static void
> diff --git a/hw/xfree86/xwayland/xwayland-drm.c b/hw/xfree86/xwayland/xwayland-drm.c
> index 6ac5c7d..c19eb84 100644
> --- a/hw/xfree86/xwayland/xwayland-drm.c
> +++ b/hw/xfree86/xwayland/xwayland-drm.c
> @@ -75,29 +75,30 @@ static const struct wl_drm_listener xwl_drm_listener =
> };
>
> static void
> -drm_handler(struct wl_display *display_,
> - uint32_t id,
> - const char *interface,
> - uint32_t version,
> - void *data)
> +drm_handler(void *data, struct wl_registry *registry, uint32_t id,
> + const char *interface, uint32_t version)
> {
> struct xwl_screen *xwl_screen = data;
>
> if (strcmp (interface, "wl_drm") == 0) {
> - xwl_screen->drm = wl_display_bind(xwl_screen->display,
> - id, &wl_drm_interface);
> - wl_drm_add_listener (xwl_screen->drm, &xwl_drm_listener, xwl_screen);
> + xwl_screen->drm = wl_registry_bind(xwl_screen->registry, id,
> + &wl_drm_interface, 1);
> + wl_drm_add_listener(xwl_screen->drm, &xwl_drm_listener, xwl_screen);
> }
> }
>
> +static const struct wl_registry_listener drm_listener = {
> + drm_handler,
> +};
> +
> int
> 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_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);
> @@ -145,14 +146,18 @@ int xwl_screen_get_drm_fd(struct xwl_screen *xwl_screen)
> int xwl_drm_authenticate(struct xwl_screen *xwl_screen,
> uint32_t magic)
> {
> + int ret;
> +
> xwl_screen->authenticated = 0;
>
> if (xwl_screen->drm)
> wl_drm_authenticate (xwl_screen->drm, magic);
>
> - wl_display_iterate (xwl_screen->display, WL_DISPLAY_WRITABLE);
> - while (!xwl_screen->authenticated)
> - wl_display_iterate (xwl_screen->display, WL_DISPLAY_READABLE);
> + ret = wl_display_roundtrip(xwl_screen->display);
> + if (ret == -1)
> + return BadAlloc;
> + if (!xwl_screen->authenticated)
> + return BadAlloc;
>
> return Success;
> }
> diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
> index d9f352f..44a14ba 100644
> --- a/hw/xfree86/xwayland/xwayland-input.c
> +++ b/hw/xfree86/xwayland/xwayland-input.c
> @@ -27,6 +27,7 @@
> #include "xorg-config.h"
> #endif
>
> +#include <errno.h>
> #include <stdint.h>
> #include <unistd.h>
> #include <linux/input.h>
> @@ -52,6 +53,9 @@
>
> #include "xwayland.h"
> #include "xwayland-private.h"
> +#include "xserver-client-protocol.h"
> +
> +extern const struct xserver_listener xwl_server_listener;
>
> static void
> xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
> @@ -473,6 +477,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
> xwl_seat->wl_pointer = wl_seat_get_pointer(seat);
> wl_pointer_add_listener(xwl_seat->wl_pointer,
> &pointer_listener, xwl_seat);
> + xwl_seat_set_cursor(xwl_seat);
> }
>
> if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
> @@ -488,8 +493,7 @@ static const struct wl_seat_listener seat_listener = {
> };
>
> static void
> -create_input_device(struct xwl_screen *xwl_screen, uint32_t id,
> - uint32_t version)
> +create_input_device(struct xwl_screen *xwl_screen, uint32_t id)
> {
> struct xwl_seat *xwl_seat;
>
> @@ -503,7 +507,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id,
> xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list);
>
> xwl_seat->seat =
> - wl_display_bind(xwl_screen->display, id, &wl_seat_interface);
> + wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 1);
> xwl_seat->id = id;
>
> xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
> @@ -512,23 +516,29 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id,
> }
>
> static void
> -input_handler(struct wl_display *display,
> - uint32_t id,
> - const char *interface,
> - uint32_t version,
> - void *data)
> +input_handler(void *data, struct wl_registry *registry, uint32_t id,
> + const char *interface, uint32_t version)
> {
> struct xwl_screen *xwl_screen = data;
>
> if (strcmp (interface, "wl_seat") == 0) {
> - create_input_device(xwl_screen, id, 1);
> + create_input_device(xwl_screen, id);
> + } else if (strcmp(interface, "xserver") == 0) {
> + xwl_screen->xorg_server =
> + wl_registry_bind(registry, id, &xserver_interface, 1);
> + xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
> + xwl_screen);
> }
> }
>
> +static const struct wl_registry_listener input_listener = {
> + input_handler,
> +};
> +
> void
> xwl_input_init(struct xwl_screen *xwl_screen)
> {
> - xwl_screen->input_listener =
> - wl_display_add_global_listener(xwl_screen->display,
> - input_handler, xwl_screen);
> + xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display);
> + wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
> + xwl_screen);
> }
> diff --git a/hw/xfree86/xwayland/xwayland-output.c b/hw/xfree86/xwayland/xwayland-output.c
> index f9e6067..8f087f6 100644
> --- a/hw/xfree86/xwayland/xwayland-output.c
> +++ b/hw/xfree86/xwayland/xwayland-output.c
> @@ -212,14 +212,9 @@ static const xf86CrtcConfigFuncsRec config_funcs = {
> };
>
> static void
> -display_handle_geometry(void *data,
> - struct wl_output *wl_output,
> - int x, int y,
> - int physical_width,
> - int physical_height,
> - int subpixel,
> - const char *make,
> - const char *model)
> +display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
> + int physical_width, int physical_height, int subpixel,
> + const char *make, const char *model, int transform)
> {
> struct xwl_output *xwl_output = data;
> struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
> @@ -255,12 +250,8 @@ display_handle_geometry(void *data,
> }
>
> static void
> -display_handle_mode(void *data,
> - struct wl_output *wl_output,
> - uint32_t flags,
> - int width,
> - int height,
> - int refresh)
> +display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
> + int width, int height, int refresh)
> {
> struct xwl_output *xwl_output = data;
>
> @@ -276,39 +267,43 @@ static const struct wl_output_listener output_listener = {
> };
>
> static void
> -global_handler(struct wl_display *display_,
> - uint32_t id,
> - const char *interface,
> - uint32_t version,
> - void *data)
> +global_handler(void *data, struct wl_registry *registry, uint32_t id,
> + const char *interface, uint32_t version)
> {
> struct xwl_screen *xwl_screen = data;
> struct xwl_output *xwl_output;
>
> if (strcmp (interface, "wl_output") == 0) {
> xwl_output = xwl_output_create(xwl_screen);
> -
> - xwl_output->output = wl_display_bind(xwl_screen->display,
> - id, &wl_output_interface);
> + xwl_output->output = wl_registry_bind(registry, id,
> + &wl_output_interface, 1);
> wl_output_add_listener(xwl_output->output,
> &output_listener, xwl_output);
> }
> }
>
> +static const struct wl_registry_listener global_listener = {
> + global_handler,
> +};
> +
> void
> xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr scrninfo)
> {
> + int ret;
> +
> xf86CrtcConfigInit(scrninfo, &config_funcs);
>
> xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192);
>
> - xwl_screen->global_listener =
> - wl_display_add_global_listener(xwl_screen->display,
> - global_handler, xwl_screen);
> + xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display);
> + wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
> + xwl_screen);
> +
> + while (!xwl_screen->xwl_output) {
> + ret = wl_display_roundtrip(xwl_screen->display);
> + if (ret == -1)
> + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
> + }
>
> - wl_display_flush(xwl_screen->display);
> - while (xwl_screen->xwl_output == NULL)
> - wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
> -
> xf86InitialConfiguration(scrninfo, TRUE);
> }
> diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
> index 8d8590f..23263d0 100644
> --- a/hw/xfree86/xwayland/xwayland-private.h
> +++ b/hw/xfree86/xwayland/xwayland-private.h
> @@ -46,10 +46,11 @@ struct xwl_screen {
> int wayland_fd;
> struct xwl_output *xwl_output;
> struct wl_display *display;
> + struct wl_registry *registry;
> + struct wl_registry *drm_registry;
> + struct wl_registry *input_registry;
> + struct wl_registry *output_registry;
> 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;
> struct xserver *xorg_server;
> @@ -96,6 +97,7 @@ struct xwl_seat {
> uint32_t id;
> uint32_t pointer_enter_serial;
> struct xorg_list link;
> + CursorPtr x_cursor;
> };
>
> struct xwl_screen *xwl_screen_get(ScreenPtr screen);
> @@ -113,4 +115,8 @@ void xwl_input_init(struct xwl_screen *screen);
>
> Bool xwl_drm_initialised(struct xwl_screen *screen);
>
> +void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
> +
> +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 63d3886..41c4376 100644
> --- a/hw/xfree86/xwayland/xwayland-window.c
> +++ b/hw/xfree86/xwayland/xwayland-window.c
> @@ -81,6 +81,7 @@ xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr pixmap)
> wl_surface_damage(xwl_window->surface, 0, 0,
> pixmap->drawable.width,
> pixmap->drawable.height);
> + wl_surface_commit(xwl_window->surface);
>
> callback = wl_display_sync(xwl_screen->display);
> wl_callback_add_listener(callback, &free_pixmap_listener, pixmap);
> diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
> index 67ac7d4..98e036e 100644
> --- a/hw/xfree86/xwayland/xwayland.c
> +++ b/hw/xfree86/xwayland/xwayland.c
> @@ -68,7 +68,7 @@ xserver_listen_socket(void *data, struct xserver *xserver, int fd)
> ListenOnOpenFD(fd, TRUE);
> }
>
> -static const struct xserver_listener xserver_listener = {
> +const struct xserver_listener xwl_server_listener = {
> xserver_client,
> xserver_listen_socket
> };
> @@ -77,20 +77,11 @@ static void
> xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
> {
> struct xwl_screen *xwl_screen = data;
> - uint32_t id;
>
> ErrorF("xwl_input_delayed_init\n");
>
> wl_callback_destroy(callback);
> xwl_input_init(xwl_screen);
> -
> - id = wl_display_get_global(xwl_screen->display, "xserver", 1);
> - if (id != 0) {
> - xwl_screen->xorg_server = wl_display_bind(xwl_screen->display,
> - id, &xserver_interface);
> - xserver_add_listener(xwl_screen->xorg_server,
> - &xserver_listener, xwl_screen);
> - }
> }
>
> static const struct wl_callback_listener delayed_init_listner = {
> @@ -98,53 +89,54 @@ static const struct wl_callback_listener delayed_init_listner = {
> };
>
> static void
> -global_handler(struct wl_display *display_,
> - uint32_t id,
> - const char *interface,
> - uint32_t version,
> - void *data)
> +registry_global(void *data, struct wl_registry *registry, uint32_t id,
> + const char *interface, uint32_t version)
> {
> struct xwl_screen *xwl_screen = data;
>
> if (strcmp (interface, "wl_compositor") == 0) {
> xwl_screen->compositor =
> - wl_display_bind(xwl_screen->display,
> - id, &wl_compositor_interface);
> - } else if (strcmp (interface, "wl_shm") == 0) {
> - xwl_screen->shm = wl_display_bind(xwl_screen->display,
> - id, &wl_shm_interface);
> + wl_registry_bind(registry, id, &wl_compositor_interface, 1);
> + } else if (strcmp(interface, "wl_shm") == 0) {
> + xwl_screen->shm =
> + wl_registry_bind(registry, id, &wl_shm_interface, 1);
> }
> }
>
> -static int
> -source_update(uint32_t mask, void *data)
> -{
> - struct xwl_screen *xwl_screen = data;
> -
> - xwl_screen->mask = mask;
> -
> - return 0;
> -}
> +static const struct wl_registry_listener registry_listener = {
> + registry_global,
> +};
>
> static void
> wakeup_handler(pointer data, int err, pointer read_mask)
> {
> struct xwl_screen *xwl_screen = data;
> + int ret;
>
> - if (err >= 0 && FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
> - wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
> + if (err < 0)
> + return;
> +
> + if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
> + return;
> +
> + ret = wl_display_dispatch(xwl_screen->display);
> + if (ret == -1)
> + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
> }
>
> static void
> block_handler(pointer data, struct timeval **tv, pointer read_mask)
> {
> struct xwl_screen *xwl_screen = data;
> + int ret;
>
> - /* The X servers "main loop" doesn't let us select for
> - * writable, so let's just do a blocking write here. */
> + ret = wl_display_dispatch_pending(xwl_screen->display);
> + if (ret == -1)
> + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
>
> - while (xwl_screen->mask & WL_DISPLAY_WRITABLE)
> - wl_display_iterate(xwl_screen->display, WL_DISPLAY_WRITABLE);
> + ret = wl_display_flush(xwl_screen->display);
> + if (ret == -1)
> + FatalError("failed to write to XWayland fd: %s\n", strerror(errno));
> }
>
> int
> @@ -228,10 +220,11 @@ Bool
> xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
> uint32_t flags, struct xwl_driver *driver)
> {
> + int ret;
> +
> noScreenSaverExtension = TRUE;
>
> xdnd_atom = MakeAtom("XdndSelection", 13, 1);
> - ErrorF("xdnd_atom: %d\n", xdnd_atom);
> if (!AddCallback(&SelectionCallback,
> xwayland_selection_callback, xwl_screen)) {
> return FALSE;
> @@ -243,19 +236,21 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen *xwl_screen,
> xwl_screen->scrninfo = scrninfo;
> xwl_screen->driver = driver;
> xwl_screen->flags = flags;
> + xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
>
> if (xorgRootless)
> xwl_screen->flags |= XWL_FLAGS_ROOTLESS;
>
> /* Set up listener so we'll catch all events. */
> - xwl_screen->global_listener =
> - wl_display_add_global_listener(xwl_screen->display,
> - global_handler, xwl_screen);
> -
> - wl_display_roundtrip(xwl_screen->display);
> -
> - xwl_screen->wayland_fd =
> - wl_display_get_fd(xwl_screen->display, source_update, xwl_screen);
> + xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
> + wl_registry_add_listener(xwl_screen->registry, ®istry_listener,
> + xwl_screen);
> + ret = wl_display_roundtrip(xwl_screen->display);
> + if (ret == -1) {
> + xf86DrvMsg(scrninfo->scrnIndex, X_ERROR,
> + "failed to dispatch Wayland events: %s\n", strerror(errno));
> + return FALSE;
> + }
>
> #ifdef WITH_LIBDRM
> if (xwl_screen->driver->use_drm && !xwl_drm_initialised(xwl_screen))
> @@ -293,10 +288,9 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
> struct xwl_seat *xwl_seat, *itmp;
> struct xwl_window *xwl_window, *wtmp;
>
> - if (xwl_screen->input_listener)
> - wl_display_remove_global_listener(xwl_screen->display,
> - xwl_screen->input_listener);
> -
> + if (xwl_screen->registry)
> + wl_registry_destroy(xwl_screen->registry);
> + xwl_screen->registry = NULL;
>
> xorg_list_for_each_entry_safe(xwl_seat, itmp,
> &xwl_screen->seat_list, link) {
> @@ -310,7 +304,6 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
> free(xwl_window);
> }
>
> - xwl_screen->input_listener = NULL;
> xorg_list_init(&xwl_screen->seat_list);
> xorg_list_init(&xwl_screen->damage_window_list);
> xorg_list_init(&xwl_screen->window_list);
> @@ -349,6 +342,7 @@ void xwl_screen_post_damage(struct xwl_screen *xwl_screen)
> box->x2 - box->x1 + 1,
> box->y2 - box->y1 + 1);
> }
> + wl_surface_commit(xwl_window->surface);
> DamageEmpty(xwl_window->damage);
> }
>
> --
> 1.7.9.5
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list