kiss-nihal

personal KISS Linux package repo
git clone git://git.nihaljere.xyz/kiss-nihal
Log | Files | Refs | Submodules

subsurface.patch (8500B)


      1 From f7a97664194da119e2171656bd9eb79379fa5436 Mon Sep 17 00:00:00 2001
      2 From: ian <42294085+ianbeyst@users.noreply.github.com>
      3 Date: Sat, 18 Apr 2020 20:11:28 +0200
      4 Subject: [PATCH] Implement basic subsurface support
      5 
      6 Functionality is for now limited to creation, initial rendering and
      7 destruction.
      8 ---
      9  libswc/subcompositor.c |  7 ++--
     10  libswc/subsurface.c    | 94 +++++++++++++++++++++++++++++++++++++-----
     11  libswc/subsurface.h    | 20 ++++++++-
     12  libswc/surface.c       |  6 ++-
     13  libswc/surface.h       |  3 ++
     14  5 files changed, 115 insertions(+), 15 deletions(-)
     15 
     16 diff --git a/libswc/subcompositor.c b/libswc/subcompositor.c
     17 index 5d1da45..10d50c3 100644
     18 --- a/libswc/subcompositor.c
     19 +++ b/libswc/subcompositor.c
     20 @@ -31,10 +31,11 @@ static void
     21  get_subsurface(struct wl_client *client, struct wl_resource *resource,
     22                 uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource)
     23  {
     24 -	struct subsurface *subsurface;
     25 -
     26 -	subsurface = subsurface_new(client, wl_resource_get_version(resource), id);
     27 +    struct surface *surface = wl_resource_get_user_data(surface_resource);
     28 +    struct surface *parent = wl_resource_get_user_data(parent_resource);
     29 +    struct subsurface *subsurface;
     30  
     31 +	subsurface = subsurface_new(client, wl_resource_get_version(resource), id, surface, parent);
     32  	if (!subsurface) {
     33  		wl_resource_post_no_memory(resource);
     34  		return;
     35 diff --git a/libswc/subsurface.c b/libswc/subsurface.c
     36 index 6f68b2c..c8aaca0 100644
     37 --- a/libswc/subsurface.c
     38 +++ b/libswc/subsurface.c
     39 @@ -21,40 +21,53 @@
     40   * SOFTWARE.
     41   */
     42  
     43 +#include "compositor.h"
     44  #include "subsurface.h"
     45  #include "util.h"
     46  
     47  #include <stdlib.h>
     48 +#include <stdbool.h>
     49  #include <wayland-server.h>
     50  
     51  static void
     52  set_position(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y)
     53  {
     54 -	/* TODO: Implement. */
     55 +	struct subsurface *subsurface = wl_resource_get_user_data(resource);
     56 +
     57 +    subsurface->position.x = x;
     58 +    subsurface->position.y = y;
     59 +    subsurface->position.set = true;
     60 +
     61 +    view_move(subsurface->surface->view, subsurface->parent->view->geometry.x + x, subsurface->parent->view->geometry.y + y);
     62 +    view_update(subsurface->surface->view);
     63 +
     64 +	struct compositor_view *comp_view = compositor_view(subsurface->surface->view);
     65 +	if (comp_view)
     66 +		compositor_view_show(comp_view);
     67  }
     68  
     69  static void
     70  place_above(struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource)
     71  {
     72 -	/* TODO: Implement. */
     73 +    DEBUG("subsurface::place_above\n");
     74  }
     75  
     76  static void
     77  place_below(struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling_resource)
     78  {
     79 -	/* TODO: Implement. */
     80 +    DEBUG("subsurface::place_below\n");
     81  }
     82  
     83  static void
     84  set_sync(struct wl_client *client, struct wl_resource *resource)
     85  {
     86 -	/* TODO: Implement. */
     87 +    DEBUG("subsurface::set_sync\n");
     88  }
     89  
     90  static void
     91  set_desync(struct wl_client *client, struct wl_resource *resource)
     92  {
     93 -	/* TODO: Implement. */
     94 +    DEBUG("subsurface::set_desync\n");
     95  }
     96  
     97  static const struct wl_subsurface_interface subsurface_impl = {
     98 @@ -67,14 +80,63 @@ static const struct wl_subsurface_interface subsurface_impl = {
     99  };
    100  
    101  static void
    102 -subsurface_destroy(struct wl_resource *resource)
    103 +unlink_from_parent(struct subsurface* subsurface)
    104  {
    105 -	struct subsurface *subsurface = wl_resource_get_user_data(resource);
    106 +	wl_list_remove(&subsurface->parent_link);
    107 +	wl_list_remove(&subsurface->parent_destroy_listener.link);
    108 +	subsurface->parent = NULL;
    109 +}
    110 +
    111 +static void
    112 +subsurface_destroy(struct subsurface *subsurface)
    113 +{
    114 +	if (subsurface->parent)
    115 +	    unlink_from_parent(subsurface);
    116 +
    117 +	struct compositor_view *comp_view = compositor_view(subsurface->surface->view);
    118 +	if (comp_view)
    119 +	    compositor_view_destroy(comp_view);
    120 +
    121 +    wl_list_remove(&subsurface->surface_destroy_listener.link);
    122 +
    123  	free(subsurface);
    124  }
    125  
    126 +static void
    127 +subsurface_destroy_handler(struct wl_resource *resource)
    128 +{
    129 +	struct subsurface *subsurface = wl_resource_get_user_data(resource);
    130 +    if (subsurface)
    131 +        subsurface_destroy(subsurface);
    132 +}
    133 +
    134 +static void
    135 +subsurface_handle_surface_destroy(struct wl_listener *listener, void *data)
    136 +{
    137 +	struct subsurface *subsurface;
    138 +	subsurface = wl_container_of(listener, subsurface, surface_destroy_listener);
    139 +
    140 +    if (subsurface->resource)
    141 +		wl_resource_set_user_data(subsurface->resource, NULL);
    142 +
    143 +	subsurface_destroy(subsurface);
    144 +}
    145 +
    146 +static void
    147 +subsurface_handle_parent_destroy(struct wl_listener *listener, void *data)
    148 +{
    149 +	struct subsurface *subsurface;
    150 +	subsurface = wl_container_of(listener, subsurface, parent_destroy_listener);
    151 +
    152 +	struct compositor_view *comp_view = compositor_view(subsurface->surface->view);
    153 +	if (comp_view)
    154 +	    compositor_view_hide(comp_view);
    155 +
    156 +	unlink_from_parent(subsurface);
    157 +}
    158 +
    159  struct subsurface *
    160 -subsurface_new(struct wl_client *client, uint32_t version, uint32_t id)
    161 +subsurface_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface, struct surface *parent)
    162  {
    163  	struct subsurface *subsurface;
    164  
    165 @@ -82,11 +144,23 @@ subsurface_new(struct wl_client *client, uint32_t version, uint32_t id)
    166  		goto error0;
    167  
    168  	subsurface->resource = wl_resource_create(client, &wl_subsurface_interface, version, id);
    169 -
    170  	if (!subsurface->resource)
    171  		goto error1;
    172 +	wl_resource_set_implementation(subsurface->resource, &subsurface_impl, subsurface, &subsurface_destroy_handler);
    173 +
    174 +    subsurface->surface = surface;
    175 +    subsurface->parent = parent;
    176 +
    177 +	subsurface->surface_destroy_listener.notify = subsurface_handle_surface_destroy;
    178 +	subsurface->parent_destroy_listener.notify = subsurface_handle_parent_destroy;
    179 +	wl_signal_add(&surface->destroy_signal, &subsurface->surface_destroy_listener);
    180 +	wl_signal_add(&parent->destroy_signal, &subsurface->parent_destroy_listener);
    181 +
    182 +	wl_list_insert(&parent->subsurface_list, &subsurface->parent_link);
    183 +
    184 +    subsurface->synchronized = true;
    185  
    186 -	wl_resource_set_implementation(subsurface->resource, &subsurface_impl, subsurface, &subsurface_destroy);
    187 +    compositor_create_view(subsurface->surface);
    188  
    189  	return subsurface;
    190  
    191 diff --git a/libswc/subsurface.h b/libswc/subsurface.h
    192 index a78ed69..2bfd578 100644
    193 --- a/libswc/subsurface.h
    194 +++ b/libswc/subsurface.h
    195 @@ -24,14 +24,32 @@
    196  #ifndef SWC_SUBSURFACE_H
    197  #define SWC_SUBSURFACE_H
    198  
    199 +#include "surface.h"
    200 +
    201 +#include <stdbool.h>
    202  #include <stdint.h>
    203  
    204  struct wl_client;
    205  
    206  struct subsurface {
    207  	struct wl_resource *resource;
    208 +
    209 +    struct surface *surface;
    210 +    struct wl_listener surface_destroy_listener;
    211 +
    212 +    struct surface *parent;
    213 +    struct wl_listener parent_destroy_listener;
    214 +    struct wl_list parent_link;
    215 +
    216 +	struct {
    217 +		int32_t x;
    218 +		int32_t y;
    219 +		bool set;
    220 +	} position;
    221 +
    222 +	bool synchronized;
    223  };
    224  
    225 -struct subsurface *subsurface_new(struct wl_client *client, uint32_t version, uint32_t id);
    226 +struct subsurface *subsurface_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface, struct surface *parent);
    227  
    228  #endif
    229 diff --git a/libswc/surface.c b/libswc/surface.c
    230 index 19a36ec..f6809d8 100644
    231 --- a/libswc/surface.c
    232 +++ b/libswc/surface.c
    233 @@ -305,6 +305,8 @@ surface_destroy(struct wl_resource *resource)
    234  {
    235  	struct surface *surface = wl_resource_get_user_data(resource);
    236  
    237 +    wl_signal_emit(&surface->destroy_signal, surface);
    238 +
    239  	state_finalize(&surface->state);
    240  	state_finalize(&surface->pending.state);
    241  
    242 @@ -339,10 +341,13 @@ surface_new(struct wl_client *client, uint32_t version, uint32_t id)
    243  	surface->pending.commit = 0;
    244  	surface->view = NULL;
    245  	surface->view_handler.impl = &view_handler_impl;
    246 +	wl_list_init(&surface->subsurface_list);
    247  
    248  	state_initialize(&surface->state);
    249  	state_initialize(&surface->pending.state);
    250  
    251 +    wl_signal_init(&surface->destroy_signal);
    252 +
    253  	return surface;
    254  
    255  error1:
    256 @@ -361,7 +366,6 @@ surface_set_view(struct surface *surface, struct view *view)
    257  		wl_list_remove(&surface->view_handler.link);
    258  
    259  	surface->view = view;
    260 -
    261  	if (view) {
    262  		wl_list_insert(&view->handlers, &surface->view_handler.link);
    263  		view_attach(view, surface->state.buffer);
    264 diff --git a/libswc/surface.h b/libswc/surface.h
    265 index 039ed4c..28d810b 100644
    266 --- a/libswc/surface.h
    267 +++ b/libswc/surface.h
    268 @@ -67,6 +67,9 @@ struct surface {
    269  
    270  	struct view *view;
    271  	struct view_handler view_handler;
    272 +
    273 +    struct wl_signal destroy_signal;
    274 +    struct wl_list subsurface_list;
    275  };
    276  
    277  struct surface *surface_new(struct wl_client *client, uint32_t version, uint32_t id);