[PATCH v2 xserver] xwayland: Port to Wayland 1.0 API

Kristian Høgsberg hoegsberg at gmail.com
Wed Nov 21 13:33:43 PST 2012


On Tue, Nov 20, 2012 at 05:45:10PM -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 v1:
> - delayed xserver interface bind, via callback. Thus a new request for
>   initializing weston WM is not needed anymore.
> 
>  hw/xfree86/xwayland/xwayland-cursor.c  |   40 ++++++++-----
>  hw/xfree86/xwayland/xwayland-drm.c     |   37 +++++++-----
>  hw/xfree86/xwayland/xwayland-input.c   |   32 +++++++----
>  hw/xfree86/xwayland/xwayland-output.c  |   54 +++++++++---------
>  hw/xfree86/xwayland/xwayland-private.h |   12 +++-
>  hw/xfree86/xwayland/xwayland.c         |   96 ++++++++++++++++----------------
>  6 files changed, 152 insertions(+), 119 deletions(-)
> 
> diff --git a/hw/xfree86/xwayland/xwayland-cursor.c b/hw/xfree86/xwayland/xwayland-cursor.c
> index f69601a..c98b67c 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);
> +}
> +

Splitting this out (so we can call it from seat_handle_capabilities())
is an unrelated change and should be in a separate patch.  Of course,
we'll be squashing all the xwayland history into just a few patches,
so not a big deal in this case.

>  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..e0abeac 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, version);

The version to pass to wl_registry_bind is the version we (the client)
supports.  The version the compositor sends in the global event is the
version of the interface the server supports and may be different from
what we support.  A client must verify that the server interface is as
least the minimum version number the client supports and if that's ok,
then send the version number the client supports in the bind request.
This ensures that the server knows which version the client
understands and can avoid sending events that may have been introduced
in later versions.

In this case (and all other cases of wl_registry_bind in this patch)
the version to pass is 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,22 @@ 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_flush(xwl_screen->display);
> +    if (ret == -1)
> +        return BadAlloc;
> +    ret = wl_display_dispatch(xwl_screen->display);
> +    if (ret == -1)
> +        return BadAlloc;
> +
> +    if (!xwl_screen->authenticated)
> +        wl_display_roundtrip(xwl_screen->display);

This whole thing should just be

  ret = wl_display_roundtrip(xwl_screen->display);
  if (ret == -1)
    return BadAlloc;
  if (!xwl_screen->authenticated)
    return BadAlloc; 

wl_display_roundtrip will send the wl_display.sync request and then
call wl_display_iterate() (which flushes) until it has received the
reply event, which will be after a potential auth event comes in.  So
after the roundtrip we either have the auth event or we aren't going
to get it.

>      return Success;
>  }
> diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
> index d9f352f..85d7c37 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) {
> @@ -503,7 +508,8 @@ 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,
> +                         version);
>      xwl_seat->id = id;
>  
>      xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor);
> @@ -512,23 +518,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, version);
> +    } else if (strcmp(interface, "xserver") == 0) {
> +        xwl_screen->xorg_server =
> +            wl_registry_bind(registry, id, &xserver_interface, version);
> +        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..f7e5964 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,44 @@ 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;
> +    int ret;
>  
>      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, version);
>  	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;

I think eventually (that is, in a later patch) we want to keep a list
of globals in the server and a list of interested listeners.  We'll be
able to avoid a bit of boilerplate that way too, since we can just
pass in the interface name, minimum version, listener struct and
listener data.  That way we can skip all the registry listener struct
and global handler functions and just create the proxies centrally and
we avoid creating four registry proxies.  Anyway, something for later.

>      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.c b/hw/xfree86/xwayland/xwayland.c
> index 67ac7d4..0044449 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
>  };
> @@ -83,14 +83,6 @@ xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t time)
>  
>      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);
> -    }
>  }

And this is where we used to bind to the xserver interface, right
after the delayed init of the input devices.  Before, xwl_input_init
would get callbacks immediately after registering the global handler
(they used to be cached in wl_display), but now it just sends the
get_registry request to the display.  Making the xserver_listener
interface global and binding from input_handler isn't very nice
though.  I'm thinking that maybe we should just bite the bullet and
implement that client side caching of globals.

>  static const struct wl_callback_listener delayed_init_listner = {
> @@ -98,53 +90,56 @@ 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, version);
> +    } else if (strcmp(interface, "wl_shm") == 0) {
> +        xwl_screen->shm =
> +            wl_registry_bind(registry, id, &wl_shm_interface, version);
>      }
>  }
>  
> -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)
> +        return;
>  
> -    if (err >= 0 && FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
> -	wl_display_iterate(xwl_screen->display, WL_DISPLAY_READABLE);
> +    /* First dispatch any pending events we might've picked up along the
> +     * way, then do a blocking read if there's been any activity on our fd. */
> +    ret = wl_display_dispatch_pending(xwl_screen->display);
> +    if (ret == -1)
> +        FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));

wl_display_dispatch_pending() is only for dispatching events that are
stuck in the event queue and should be used just before going to sleep
to make sure we don't go to sleep with pending events.  We never sleep
with pending events, and thus we never wake up with pending events, so
no need to call it here.

> +
> +    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. */
> -
> -    while (xwl_screen->mask & WL_DISPLAY_WRITABLE)
> -	wl_display_iterate(xwl_screen->display, WL_DISPLAY_WRITABLE);

This is where we need wl_display_dispatch_pending() - just before and
just before the call to wl_display_flush(), so that in case any
handlers of pending events ends up queuing requests, they get flushed
too.

> +    ret = wl_display_flush(xwl_screen->display);
> +    if (ret == -1)
> +        FatalError("failed to write to XWayland fd: %s\n", strerror(errno));
>  }
>  
>  int
> @@ -228,10 +223,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 +239,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, &registry_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 +291,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 +307,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);
> @@ -348,9 +344,11 @@ void xwl_screen_post_damage(struct xwl_screen *xwl_screen)
>  			      box->x1, box->y1,
>  			      box->x2 - box->x1 + 1,
>  			      box->y2 - box->y1 + 1);
> +	    wl_surface_commit(xwl_window->surface);

We don't need to call wl_surface_commit() for each damage rect, just
once after the loop is fine.  We should also call wl_surface_commit()
from xwl_window_attach() and xwl_set_cursor() where we attach new
buffers and also post damage.

>  	}
>  	DamageEmpty(xwl_window->damage);
>      }
> +    wl_display_flush(xwl_screen->display);

We don't need the flush here.

>      xorg_list_init(&xwl_screen->damage_window_list);
>  }

Kristian


More information about the wayland-devel mailing list