[PATCH 04/16] xdg-shell: Implement part of the interface.

Rafael Antognolli antognolli at gmail.com
Tue Dec 3 09:45:24 PST 2013


On Fri, Nov 29, 2013 at 9:29 PM, Kristian Høgsberg <hoegsberg at gmail.com> wrote:
> On Wed, Nov 27, 2013 at 03:50:20PM -0200, Rafael Antognolli wrote:
>> Basic requests are implemented, enough to get a surface displayed.
>> ---
>>  src/.gitignore  |   2 +
>>  src/Makefile.am |   6 +-
>>  src/shell.c     | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
>>  3 files changed, 223 insertions(+), 13 deletions(-)
>>
>> diff --git a/src/.gitignore b/src/.gitignore
>> index 723967d..8e59be6 100644
>> --- a/src/.gitignore
>> +++ b/src/.gitignore
>> @@ -19,3 +19,5 @@ workspaces-protocol.c
>>  workspaces-server-protocol.h
>>  input-method-protocol.c
>>  input-method-server-protocol.h
>> +xdg-shell-protocol.c
>> +xdg-shell-server-protocol.h
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index 551dff9..f6f277d 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -294,7 +294,9 @@ desktop_shell_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS)
>>  desktop_shell_la_SOURCES =                   \
>>       shell.c                                 \
>>       desktop-shell-protocol.c                \
>> -     desktop-shell-server-protocol.h
>> +     desktop-shell-server-protocol.h         \
>> +     xdg-shell-protocol.c                    \
>> +     xdg-shell-server-protocol.h
>>  endif
>>
>>  if ENABLE_TABLET_SHELL
>> @@ -355,6 +357,8 @@ BUILT_SOURCES =                                   \
>>       input-method-server-protocol.h          \
>>       workspaces-server-protocol.h            \
>>       workspaces-protocol.c                   \
>> +     xdg-shell-protocol.c                    \
>> +     xdg-shell-server-protocol.h             \
>>       git-version.h
>>
>>  CLEANFILES = $(BUILT_SOURCES)
>> diff --git a/src/shell.c b/src/shell.c
>> index 507d46f..f775899 100644
>> --- a/src/shell.c
>> +++ b/src/shell.c
>> @@ -40,6 +40,7 @@
>>  #include "input-method-server-protocol.h"
>>  #include "workspaces-server-protocol.h"
>>  #include "../shared/config-parser.h"
>> +#include "xdg-shell-server-protocol.h"
>>
>>  #define DEFAULT_NUM_WORKSPACES 1
>>  #define DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH 200
>> @@ -1564,8 +1565,8 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *seat)
>>  }
>>
>>  static void
>> -shell_surface_move(struct wl_client *client, struct wl_resource *resource,
>> -                struct wl_resource *seat_resource, uint32_t serial)
>> +common_surface_move(struct wl_resource *resource,
>> +                 struct wl_resource *seat_resource, uint32_t serial)
>>  {
>>       struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
>>       struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>> @@ -1587,6 +1588,13 @@ shell_surface_move(struct wl_client *client, struct wl_resource *resource,
>>       }
>>  }
>>
>> +static void
>> +shell_surface_move(struct wl_client *client, struct wl_resource *resource,
>> +                struct wl_resource *seat_resource, uint32_t serial)
>> +{
>> +     common_surface_move(resource, seat_resource, serial);
>> +}
>> +
>>  struct weston_resize_grab {
>>       struct shell_grab base;
>>       uint32_t edges;
>> @@ -1741,9 +1749,9 @@ surface_resize(struct shell_surface *shsurf,
>>  }
>>
>>  static void
>> -shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
>> -                  struct wl_resource *seat_resource, uint32_t serial,
>> -                  uint32_t edges)
>> +common_surface_resize(struct wl_resource *resource,
>> +                   struct wl_resource *seat_resource, uint32_t serial,
>> +                   uint32_t edges)
>>  {
>>       struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
>>       struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>> @@ -1763,6 +1771,14 @@ shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
>>  }
>>
>>  static void
>> +shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
>> +                  struct wl_resource *seat_resource, uint32_t serial,
>> +                  uint32_t edges)
>> +{
>> +     common_surface_resize(resource, seat_resource, serial, edges);
>> +}
>> +
>> +static void
>>  end_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer);
>>
>>  static void
>> @@ -1943,12 +1959,10 @@ create_pointer_focus_listener(struct weston_seat *seat)
>>  }
>>
>>  static void
>> -shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
>> -                                                     uint32_t serial)
>> +surface_pong(struct shell_surface *shsurf, uint32_t serial)
>>  {
>> -     struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>> -     struct weston_seat *seat;
>>       struct weston_compositor *ec = shsurf->surface->compositor;
>> +     struct weston_seat *seat;
>>
>>       if (shsurf->ping_timer == NULL)
>>               /* Just ignore unsolicited pong. */
>> @@ -1965,6 +1979,16 @@ shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
>>  }
>>
>>  static void
>> +shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
>> +                                                     uint32_t serial)
>> +{
>> +     struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>> +
>> +     surface_pong(shsurf, serial);
>> +
>> +}
>> +
>> +static void
>>  set_title(struct shell_surface *shsurf, const char *title)
>>  {
>>       free(shsurf->title);
>> @@ -2802,9 +2826,9 @@ get_shell_surface(struct weston_surface *surface)
>>               return NULL;
>>  }
>>
>> -static       struct shell_surface *
>> -create_shell_surface(void *shell, struct weston_surface *surface,
>> -                  const struct weston_shell_client *client)
>> +static struct shell_surface *
>> +create_common_surface(void *shell, struct weston_surface *surface,
>> +                   const struct weston_shell_client *client)
>>  {
>>       struct shell_surface *shsurf;
>>
>> @@ -2863,6 +2887,19 @@ create_shell_surface(void *shell, struct weston_surface *surface,
>>       return shsurf;
>>  }
>>
>> +static struct shell_surface *
>> +create_shell_surface(void *shell, struct weston_surface *surface,
>> +                  const struct weston_shell_client *client)
>> +{
>> +     struct shell_surface *shsurf;
>> +     shsurf = create_common_surface(shell, surface, client);
>> +
>> +     shsurf->type = SHELL_SURFACE_NONE;
>> +     shsurf->next_type = SHELL_SURFACE_NONE;
>> +
>> +     return shsurf;
>> +}
>> +
>>  static struct weston_view *
>>  get_primary_view(void *shell, struct shell_surface *shsurf)
>>  {
>> @@ -2907,6 +2944,157 @@ static const struct wl_shell_interface shell_implementation = {
>>       shell_get_shell_surface
>>  };
>>
>> +/****************************
>> + * xdg-shell implementation */
>> +
>> +static void
>> +xdg_surface_destroy(struct wl_client *client,
>> +                 struct wl_resource *resource)
>> +{
>> +     wl_resource_destroy(resource);
>> +}
>> +
>> +static void
>> +xdg_surface_pong(struct wl_client *client,
>> +              struct wl_resource *resource,
>> +              uint32_t serial)
>> +{
>> +     struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>> +
>> +     surface_pong(shsurf, serial);
>> +}
>> +
>> +static void
>> +xdg_surface_set_app_id(struct wl_client *client,
>> +                    struct wl_resource *resource,
>> +                    const char *app_id)
>> +{
>> +     struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>> +
>> +     free(shsurf->class);
>> +     shsurf->class = strdup(app_id);
>> +}
>> +
>> +static void
>> +xdg_surface_set_title(struct wl_client *client,
>> +                     struct wl_resource *resource, const char *title)
>> +{
>> +     struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>> +
>> +     set_title(shsurf, title);
>> +}
>> +
>> +static void
>> +xdg_surface_move(struct wl_client *client, struct wl_resource *resource,
>> +              struct wl_resource *seat_resource, uint32_t serial)
>> +{
>> +     common_surface_move(resource, seat_resource, serial);
>> +}
>> +
>> +static void
>> +xdg_surface_resize(struct wl_client *client, struct wl_resource *resource,
>> +                struct wl_resource *seat_resource, uint32_t serial,
>> +                uint32_t edges)
>> +{
>> +     common_surface_resize(resource, seat_resource, serial, edges);
>> +}
>> +
>> +static const struct xdg_surface_interface xdg_surface_implementation = {
>> +     xdg_surface_destroy,
>> +     NULL, // set_transient_for
>> +     xdg_surface_set_title,
>> +     xdg_surface_set_app_id,
>> +     xdg_surface_pong,
>> +     xdg_surface_move,
>> +     xdg_surface_resize,
>> +     NULL, // set_output
>> +     NULL, // set_fullscreen
>> +     NULL, // unset_fullscreen
>> +     NULL, // set_maximized
>> +     NULL, // unset_maximized
>> +     NULL // set_minimized
>
> We try to avoid // style comments even for a one-line thing like this.
> But I think you should just squash patches 4-7 into one big patch.
> The point of small commits is mainly bisectability - fix one issues or
> add one feature at a time.  In this case the entire xdg_shell
> interface is one feature.  If you're landing a big chunk of work,
> there's really no point in committing it one or three functions at a
> time.

Done.

>> +};
>> +
>> +static void
>> +xdg_send_configure(struct weston_surface *surface,
>> +            uint32_t edges, int32_t width, int32_t height)
>> +{
>> +     struct shell_surface *shsurf = get_shell_surface(surface);
>> +
>> +     xdg_surface_send_configure(shsurf->resource, edges, width, height);
>> +}
>> +
>> +static const struct weston_shell_client xdg_client = {
>> +     xdg_send_configure
>> +};
>> +
>> +static void
>> +xdg_use_unstable_version(struct wl_client *client,
>> +                      struct wl_resource *resource,
>> +                      int32_t version)
>> +{
>> +     if (version > 1) {
>> +             wl_resource_post_error(resource,
>> +                                    1,
>> +                                    "xdg-shell:: version not implemented yet.");
>> +             return;
>> +     }
>> +}
>> +
>> +static struct shell_surface *
>> +create_xdg_surface(void *shell, struct weston_surface *surface,
>> +                const struct weston_shell_client *client)
>> +{
>> +     struct shell_surface *shsurf;
>> +     shsurf = create_common_surface(shell, surface, client);
>> +
>> +     shsurf->type = SHELL_SURFACE_NONE;
>> +     shsurf->next_type = SHELL_SURFACE_TOPLEVEL;
>> +
>> +     return shsurf;
>> +}
>> +
>> +static void
>> +xdg_get_xdg_surface(struct wl_client *client,
>> +                 struct wl_resource *resource,
>> +                 uint32_t id,
>> +                 struct wl_resource *surface_resource)
>> +{
>> +     struct weston_surface *surface =
>> +             wl_resource_get_user_data(surface_resource);
>> +     struct desktop_shell *shell = wl_resource_get_user_data(resource);
>> +     struct shell_surface *shsurf;
>> +
>> +     if (get_shell_surface(surface)) {
>> +             wl_resource_post_error(surface_resource,
>> +                                    WL_DISPLAY_ERROR_INVALID_OBJECT,
>> +                                    "desktop_shell::get_shell_surface already requested");
>> +             return;
>> +     }
>> +
>> +     shsurf = create_xdg_surface(shell, surface, &xdg_client);
>> +     if (!shsurf) {
>> +             wl_resource_post_error(surface_resource,
>> +                                    WL_DISPLAY_ERROR_INVALID_OBJECT,
>> +                                    "surface->configure already set");
>> +             return;
>> +     }
>> +
>> +     shsurf->resource =
>> +             wl_resource_create(client,
>> +                                &xdg_surface_interface, 1, id);
>> +     wl_resource_set_implementation(shsurf->resource,
>> +                                    &xdg_surface_implementation,
>> +                                    shsurf, shell_destroy_shell_surface);
>> +}
>> +
>> +static const struct xdg_shell_interface xdg_implementation = {
>> +     xdg_use_unstable_version,
>> +     xdg_get_xdg_surface,
>> +     NULL // get_xdg_popup
>> +};
>> +
>> +
>>  static void
>>  shell_fade(struct desktop_shell *shell, enum fade_type type);
>>
>> @@ -4507,6 +4695,18 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
>>  }
>>
>>  static void
>> +bind_xdg_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
>> +{
>> +     struct desktop_shell *shell = data;
>> +     struct wl_resource *resource;
>> +
>> +     resource = wl_resource_create(client, &xdg_shell_interface, 1, id);
>> +     if (resource)
>> +             wl_resource_set_implementation(resource, &xdg_implementation,
>> +                                            shell, NULL);
>
> I'd like to make sure we can't call any requests in the object until
> use_unstable_version() has been called with a matching version.  We can do something like
>
> static int
> xdg_shell_unversioned_dispatch(const void *implementation,
>                                void *_target, uint32_t opcode,
>                                const struct wl_message *message,
>                                union wl_argument *args)
> {
>         struct wl_resource *resource = target;
>         struct desktop_shell *shell = wl_resource_get_user_data(resource);
>
>         if (opcode != 0) {
>                 wl_resource_post_error(resource,
>                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
>                                        "must call set_unstable_version first");
>                 return 0;
>         }
>
> #define XDG_SERVER_VERSION 1
>
>         if (args[0].i != XDG_SERVER_VERSION) {
>                 wl_resource_post_error(resource,
>                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
>                                        "incompatible version, server is %d "
>                                        "client wants %d",
>                                        XDG_SERVER_VERSION, args[0].i);
>                 return 0;
>         }
>
>         wl_resource_set_implementation(resource, &xdg_implementation,
>                                        shell, NULL);
> }
>
> and then use
>
>    wl_resource_set_dispatcher(resource, xdg_shell_unversioned_dispatch,
>                               NULL, shell, NULL);
>
> in bind_xdg_shell().

I don't fully understand this sorcery yet (didn't spend too much
trying), but it apparently works, thanks!

I didn't add it before because I wasn't sure about how to add it.

>> +}
>> +
>> +static void
>>  unbind_desktop_shell(struct wl_resource *resource)
>>  {
>>       struct desktop_shell *shell = wl_resource_get_user_data(resource);
>> @@ -6045,6 +6245,10 @@ module_init(struct weston_compositor *ec,
>>                                 shell, bind_shell) == NULL)
>>               return -1;
>>
>> +     if (wl_global_create(ec->wl_display, &xdg_shell_interface, 1,
>> +                               shell, bind_xdg_shell) == NULL)
>> +             return -1;
>> +
>>       if (wl_global_create(ec->wl_display,
>>                            &desktop_shell_interface, 2,
>>                            shell, bind_desktop_shell) == NULL)
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel



-- 
Rafael Antognolli


More information about the wayland-devel mailing list