summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLeon Henrik Plickat <leonhenrik.plickat@stud.uni-goettingen.de>2020-09-25 11:19:32 +0200
committerLeon Henrik Plickat <leonhenrik.plickat@stud.uni-goettingen.de>2020-09-25 11:19:32 +0200
commitf53c7341152bbc4b642935953e317a2a29abc99c (patch)
tree6e90223a7706da85ddfe85fbd440c6596a08a6cf /src
parent74a155389c20d4e546050c756b7fa94e445e1c1d (diff)
downloadwlclock-f53c7341152bbc4b642935953e317a2a29abc99c.tar.gz
wlclock-f53c7341152bbc4b642935953e317a2a29abc99c.tar.bz2
Change dimension model to ensure square center
Diffstat (limited to 'src')
-rw-r--r--src/render.c104
-rw-r--r--src/surface.c63
-rw-r--r--src/surface.h3
-rw-r--r--src/wlclock.c39
-rw-r--r--src/wlclock.h13
5 files changed, 121 insertions, 101 deletions
diff --git a/src/render.c b/src/render.c
index 2b3d626..6aa459f 100644
--- a/src/render.c
+++ b/src/render.c
@@ -27,91 +27,75 @@ static void rounded_rectangle (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t
cairo_close_path(cairo);
}
-static void draw_background (cairo_t *cairo,
- uint32_t x, uint32_t y, uint32_t w, uint32_t h,
- uint32_t border_top, uint32_t border_right,
- uint32_t border_bottom, uint32_t border_left,
- uint32_t top_left_radius, uint32_t top_right_radius,
- uint32_t bottom_left_radius, uint32_t bottom_right_radius,
- uint32_t scale,
- struct Wlclock_colour *background_colour,
- struct Wlclock_colour *border_colour)
+static void draw_background (cairo_t *cairo, struct Wlclock_dimensions *dimensions,
+ int32_t scale, struct Wlclock *clock)
{
- if ( colour_is_transparent(background_colour) && colour_is_transparent(border_colour) )
+ if ( colour_is_transparent(&clock->background_colour)
+ && colour_is_transparent(&clock->border_colour) )
return;
- /* Scale. */
- x *= scale, y *= scale, w *= scale, h *= scale;
- border_top *= scale, border_bottom *= scale;
- border_left *= scale, border_right *= scale;
- top_left_radius *= scale, top_right_radius *= scale;
- bottom_left_radius *= scale, bottom_right_radius *= scale;
+ int32_t w = scale * dimensions->w;
+ int32_t h = scale * dimensions->h;
+ int32_t center_x = scale * dimensions->center_x;
+ int32_t center_y = scale * dimensions->center_y;
+ int32_t center_size = scale * dimensions->center_size;
+ int32_t radius_top_left = scale * clock->radius_top_left;
+ int32_t radius_top_right = scale * clock->radius_top_right;
+ int32_t radius_bottom_left = scale * clock->radius_bottom_left;
+ int32_t radius_bottom_right = scale * clock->radius_bottom_right;
+
+ clocklog(clock, 2, "[render] Render dimensions: size=%d cx=%d cy=%d w=%d h=%d\n",
+ center_size, center_x, center_y, w, h);
cairo_save(cairo);
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
- if ( top_left_radius == 0 && top_right_radius == 0
- && bottom_left_radius == 0 && bottom_right_radius == 0 )
+ if ( radius_top_left == 0 && radius_top_right == 0
+ && radius_bottom_left == 0 && radius_bottom_right == 0 )
{
- if ( border_top == 0 && border_bottom == 0
- && border_left == 0 && border_right == 0 )
+ if ( center_x == 0 && center_y == 0 && center_size == w && center_size == h )
{
- cairo_rectangle(cairo, x, y, w, h);
- colour_set_cairo_source(cairo, background_colour);
+ cairo_rectangle(cairo, 0, 0, w, h);
+ colour_set_cairo_source(cairo, &clock->background_colour);
cairo_fill(cairo);
}
else
{
- /* Calculate dimensions of center. */
- uint32_t cx = x + border_left,
- cy = y + border_top,
- cw = w - (border_left + border_right),
- ch = h - (border_top + border_bottom);
-
- /* Borders. */
- cairo_rectangle(cairo, x, y, w, border_top);
- cairo_rectangle(cairo, x + w - border_right, y + border_top,
- border_right, h - border_top - border_bottom);
- cairo_rectangle(cairo, x, y + h - border_bottom, w, border_bottom);
- cairo_rectangle(cairo, x, y + border_top, border_left,
- h - border_top - border_bottom);
- colour_set_cairo_source(cairo, border_colour);
+ cairo_rectangle(cairo, 0, 0, w, h);
+ colour_set_cairo_source(cairo, &clock->border_colour);
cairo_fill(cairo);
- /* Center. */
- cairo_rectangle(cairo, cx, cy, cw, ch);
- colour_set_cairo_source(cairo, background_colour);
+ cairo_rectangle(cairo, center_x, center_y, center_size, center_size);
+ colour_set_cairo_source(cairo, &clock->background_colour);
cairo_fill(cairo);
}
}
else
{
- if ( border_top == 0 && border_bottom == 0
- && border_left == 0 && border_right == 0 )
+ if ( center_x == 0 && center_y == 0 && center_size == w && center_size == h )
{
- rounded_rectangle(cairo, x, y, w, h,
- top_left_radius, top_right_radius,
- bottom_left_radius, bottom_right_radius);
- colour_set_cairo_source(cairo, background_colour);
+ rounded_rectangle(cairo, 0, 0, w, h,
+ radius_top_left, radius_top_right,
+ radius_bottom_left, radius_bottom_right);
+ colour_set_cairo_source(cairo, &clock->background_colour);
cairo_fill(cairo);
}
else
{
- rounded_rectangle(cairo, x, y, w, h,
- top_left_radius, top_right_radius,
- bottom_left_radius, bottom_right_radius);
- colour_set_cairo_source(cairo, border_colour);
+ rounded_rectangle(cairo, 0, 0, w, h,
+ radius_top_left, radius_top_right,
+ radius_bottom_left, radius_bottom_right);
+ colour_set_cairo_source(cairo, &clock->border_colour);
cairo_fill(cairo);
- rounded_rectangle(cairo, x + border_left, y + border_top,
- w - (border_left + border_right),
- h - (border_bottom + border_top),
- top_left_radius, top_right_radius,
- bottom_left_radius, bottom_right_radius);
- colour_set_cairo_source(cairo, background_colour);
+ rounded_rectangle(cairo, center_x, center_y, center_size, center_size,
+ radius_top_left, radius_top_right,
+ radius_bottom_left, radius_bottom_right);
+ colour_set_cairo_source(cairo, &clock->background_colour);
cairo_fill(cairo);
}
}
+
cairo_restore(cairo);
}
@@ -132,18 +116,14 @@ void render_surface_frame (struct Wlclock_surface *surface)
/* Get new/next buffer. */
if (! next_buffer(&surface->current_buffer, clock->shm, surface->buffers,
- surface->size * scale, surface->size * scale))
+ surface->dimensions.w * scale,
+ surface->dimensions.h * scale))
return;
cairo_t *cairo = surface->current_buffer->cairo;
clear_buffer(cairo);
- draw_background(cairo, 0, 0, surface->size, surface->size,
- clock->border_top, clock->border_right,
- clock->border_bottom, clock->border_left,
- clock->radius_top_left, clock->radius_top_right,
- clock->radius_bottom_left, clock->radius_bottom_right,
- scale, &clock->background_colour, &clock->border_colour);
+ draw_background(cairo, &surface->dimensions, scale, clock);
// TODO draw clock face
// TODO draw clock hands to subsurface
diff --git a/src/surface.c b/src/surface.c
index 243a23d..19bd2d7 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -20,22 +20,28 @@
#include"buffer.h"
#include"render.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",
+ struct Wlclock *clock = surface->output->clock;
+ clocklog(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);
+ if ( (w != (uint32_t)surface->dimensions.w || h != (uint32_t)surface->dimensions.h)
+ && (w > 0 && h > 0) )
+ {
+ /* Try to fit into the space the compositor wants us to occupy
+ * while also keeping the center square and not changing the
+ * border sizes.
+ */
+ int32_t size_a = (int32_t)w - clock->border_left - clock->border_right;
+ int32_t size_b = (int32_t)h - clock->border_top - clock->border_bottom;
+ surface->dimensions.center_size = size_a < size_b ? size_a : size_b;
+ if ( surface->dimensions.center_size < 10 )
+ surface->dimensions.center_size = 10;
+ }
surface->configured = true;
update_surface(surface);
}
@@ -56,9 +62,38 @@ const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
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;
+ struct Wlclock *clock = surface->output->clock;
+ if ( clock->exclusive_zone == 1 ) switch (clock->anchor)
+ {
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
+ return surface->dimensions.h;
+
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
+ case ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM:
+ return surface->dimensions.w;
+
+ default:
+ return 0;
+ }
+ else
+ return surface->output->clock->exclusive_zone;
}
static void configure_layer_surface (struct Wlclock_surface *surface)
@@ -67,7 +102,7 @@ static void configure_layer_surface (struct Wlclock_surface *surface)
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);
+ surface->dimensions.w, surface->dimensions.h);
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,
@@ -95,7 +130,7 @@ bool create_surface (struct Wlclock_output *output)
}
output->surface = surface;
- surface->size = clock->size;
+ surface->dimensions = clock->dimensions;
surface->output = output;
surface->surface = NULL;
surface->layer_surface = NULL;
diff --git a/src/surface.h b/src/surface.h
index 57dd239..0f6ce48 100644
--- a/src/surface.h
+++ b/src/surface.h
@@ -4,6 +4,7 @@
#include<wayland-server.h>
#include"buffer.h"
+#include"wlclock.h"
#include<stdint.h>
#include<stdbool.h>
@@ -17,7 +18,7 @@ struct Wlclock_surface
struct wl_surface *surface;
struct zwlr_layer_surface_v1 *layer_surface;
- int32_t size;
+ struct Wlclock_dimensions dimensions;
struct Wlclock_buffer buffers[2];
struct Wlclock_buffer *current_buffer;
bool configured;
diff --git a/src/wlclock.c b/src/wlclock.c
index 9269e31..53dd7e3 100644
--- a/src/wlclock.c
+++ b/src/wlclock.c
@@ -393,11 +393,11 @@ static bool handle_command_flags (struct Wlclock *clock, int argc, char *argv[])
break;
case 1112: /* Size */
- clock->size = atoi(optarg);
- if ( clock->size <= 10 )
+ clock->dimensions.center_size = atoi(optarg);
+ if ( clock->dimensions.center_size <= 10 )
{
clocklog(NULL, 0, "ERROR: Unreasonably small size \"%d\".\n",
- clock->size);
+ clock->dimensions.center_size);
return false;
}
break;
@@ -530,7 +530,7 @@ int main (int argc, char *argv[])
clock.loop = true;
clock.verbosity = 0;
- clock.size = 165; /* About the size of xclock, at least on my machine. */
+ clock.dimensions.center_size = 165; /* About the size of xclock, at least on my machine. */
clock.exclusive_zone = -1;
clock.input = true;
clock.layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
@@ -549,26 +549,19 @@ int main (int argc, char *argv[])
if (! handle_command_flags(&clock, argc, argv))
goto exit;
- if ( clock.border_bottom > clock.size / 3
- || clock.border_top > clock.size / 3
- || clock.border_left > clock.size / 3
- || clock.border_right > clock.size / 3 )
- {
- clocklog(NULL, 0, "ERROR: Corner radii may not be larger than "
- "half the clock size.\n");
- goto exit;
- }
- if ( clock.radius_bottom_left > clock.size / 2
- || clock.radius_bottom_right > clock.size / 2
- || clock.radius_top_left > clock.size / 2
- || clock.radius_top_right > clock.size / 2 )
- {
- clocklog(NULL, 0, "ERROR: Corner radii may not be larger than "
- "half the clock size.\n");
- goto exit;
- }
+ clock.dimensions.w = clock.dimensions.center_size
+ + clock.border_left + clock.border_right;
+ clock.dimensions.h = clock.dimensions.center_size
+ + clock.border_top + clock.border_bottom;
+ clock.dimensions.center_x = clock.border_left;
+ clock.dimensions.center_y = clock.border_top;
+
- clocklog(&clock, 1, "[main] wlclock: version=%s\n", VERSION);
+ clocklog(&clock, 1, "[main] wlclock: version=%s\n"
+ "[main] Default dimensions: size=%d cx=%d cy=%d w=%d h=%d\n",
+ VERSION, clock.dimensions.center_size,
+ clock.dimensions.center_x, clock.dimensions.center_y,
+ clock.dimensions.w, clock.dimensions.h);
if (! init_wayland(&clock))
goto exit;
diff --git a/src/wlclock.h b/src/wlclock.h
index d051b7c..2799452 100644
--- a/src/wlclock.h
+++ b/src/wlclock.h
@@ -10,6 +10,17 @@
#include"colour.h"
+struct Wlclock_dimensions
+{
+ /* Width and height of entire surface (size + borders). */
+ int32_t w, h;
+
+ /* Dimensions of center area (where the actual clock is).
+ * Center is always square.
+ */
+ int32_t center_x, center_y, center_size;
+};
+
struct Wlclock
{
struct wl_display *display;
@@ -29,7 +40,7 @@ struct Wlclock
int ret;
enum zwlr_layer_shell_v1_layer layer;
- int32_t size;
+ struct Wlclock_dimensions dimensions;
char *namespace;
int32_t exclusive_zone;
int32_t border_top, border_right, border_bottom, border_left;