diff options
author | Leon Henrik Plickat <leonhenrik.plickat@stud.uni-goettingen.de> | 2020-09-24 18:01:28 +0200 |
---|---|---|
committer | Leon Henrik Plickat <leonhenrik.plickat@stud.uni-goettingen.de> | 2020-09-24 18:01:28 +0200 |
commit | 9ff4f4959b8d78104fa4defb3c4cea9606e3c484 (patch) | |
tree | ac80aef7e1caff0d0af491ea4816ca63706a8116 /src/surface.c | |
download | wlclock-9ff4f4959b8d78104fa4defb3c4cea9606e3c484.tar.gz wlclock-9ff4f4959b8d78104fa4defb3c4cea9606e3c484.tar.bz2 |
Init
Diffstat (limited to 'src/surface.c')
-rw-r--r-- | src/surface.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/surface.c b/src/surface.c new file mode 100644 index 0000000..9e6c8e2 --- /dev/null +++ b/src/surface.c @@ -0,0 +1,163 @@ +#include<stdio.h> +#include<stdlib.h> +#include<stdbool.h> +#include<unistd.h> +#include<string.h> + +#include<cairo/cairo.h> +#include<wayland-server.h> +#include<wayland-client.h> +#include<wayland-client-protocol.h> + +#include"wlr-layer-shell-unstable-v1-protocol.h" +#include"xdg-output-unstable-v1-protocol.h" +#include"xdg-shell-protocol.h" + +#include"wlclock.h" +#include"output.h" +#include"misc.h" +#include"surface.h" +#include"buffer.h" + +static uint32_t min (uint32_t a, uint32_t b) +{ + return a > b ? b : a; +} + +static void layer_surface_handle_configure (void *data, + struct zwlr_layer_surface_v1 *layer_surface, uint32_t serial, + uint32_t w, uint32_t h) +{ + struct Wlclock_surface *surface = (struct Wlclock_surface *)data; + clocklog(surface->output->clock, 1, + "[surface] Layer surface configure request: global_name=%d w=%d h=%d serial=%d\n", + surface->output->global_name, w, h, serial); + zwlr_layer_surface_v1_ack_configure(layer_surface, serial); + if ( w > 0 && h > 0 ) /* Try to fit as best as possible. */ + surface->size = min(w, h); + surface->configured = true; + update_surface(surface); +} + +static void layer_surface_handle_closed (void *data, struct zwlr_layer_surface_v1 *layer_surface) +{ + struct Wlclock_surface *surface = (struct Wlclock_surface *)data; + clocklog(surface->output->clock, 1, + "[surface] Layer surface has been closed: global_name=%d\n", + surface->output->global_name); + destroy_surface(surface); +} + +const struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .configure = layer_surface_handle_configure, + .closed = layer_surface_handle_closed +}; + +static int32_t get_exclusive_zone (struct Wlclock_surface *surface) +{ + if ( surface->output->clock->exclusive_zone == 1 ) + return surface->size; + return surface->output->clock->exclusive_zone; +} + +static void configure_layer_surface (struct Wlclock_surface *surface) +{ + struct Wlclock *clock = surface->output->clock; + clocklog(clock, 1, "[surface] Configuring surface: global_name=%d\n", + surface->output->global_name); + zwlr_layer_surface_v1_set_size(surface->layer_surface, + surface->size, surface->size); + zwlr_layer_surface_v1_set_anchor(surface->layer_surface, clock->anchor); + zwlr_layer_surface_v1_set_margin(surface->layer_surface, + clock->margin_top, clock->margin_right, + clock->margin_bottom, clock->margin_left); + zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, + get_exclusive_zone(surface)); + if (! clock->input) + { + struct wl_region *region = wl_compositor_create_region(clock->compositor); + wl_surface_set_input_region(surface->surface, region); + wl_region_destroy(region); + } +} + +bool create_surface (struct Wlclock_output *output) +{ + struct Wlclock *clock = output->clock; + clocklog(clock, 1, "[surface] Creating surface: global_name=%d\n", output->global_name); + + struct Wlclock_surface *surface = calloc(1, sizeof(struct Wlclock_surface)); + if ( surface == NULL ) + { + clocklog(NULL, 0, "ERROR: Could not allocate.\n"); + return false; + } + + output->surface = surface; + surface->size = clock->size; + surface->output = output; + surface->surface = NULL; + surface->layer_surface = NULL; + surface->configured = false; + + if ( NULL == (surface->surface = wl_compositor_create_surface(clock->compositor)) ) + { + clocklog(NULL, 0, "ERROR: Compositor did not create wl_surface.\n"); + return false; + } + if ( NULL == (surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( + clock->layer_shell, surface->surface, + output->wl_output, clock->layer, + clock->namespace)) ) + { + clocklog(NULL, 0, "ERROR: Compositor did not create layer_surface.\n"); + return false; + } + + configure_layer_surface(surface); + zwlr_layer_surface_v1_add_listener(surface->layer_surface, + &layer_surface_listener, surface); + wl_surface_commit(surface->surface); + + return true; +} + +void destroy_surface (struct Wlclock_surface *surface) +{ + if ( surface == NULL ) + return; + if ( surface->layer_surface != NULL ) + zwlr_layer_surface_v1_destroy(surface->layer_surface); + if ( surface->surface != NULL ) + wl_surface_destroy(surface->surface); + finish_buffer(&surface->buffers[0]); + finish_buffer(&surface->buffers[1]); + free(surface); +} + +void destroy_all_surfaces (struct Wlclock *clock) +{ + clocklog(clock, 1, "[surface] Destroying all surfaces.\n"); + struct Wlclock_output *op, *tmp; + wl_list_for_each_safe(op, tmp, &clock->outputs, link) + if ( op->surface != NULL ) + destroy_surface(op->surface); +} + +void update_surface (struct Wlclock_surface *surface) +{ + if ( surface == NULL || ! surface->configured ) + return; + configure_layer_surface(surface); + // render_surface_frame(surface); // TODO + wl_surface_commit(surface->surface); +} + +void update_all_surfaces (struct Wlclock *clock) +{ + clocklog(clock, 1, "[surface] Updating all surfaces.\n"); + struct Wlclock_output *op, *tmp; + wl_list_for_each_safe(op, tmp, &clock->outputs, link) + if ( op->surface != NULL ) + update_surface(op->surface); +} |