diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/render.c | 104 | ||||
-rw-r--r-- | src/surface.c | 63 | ||||
-rw-r--r-- | src/surface.h | 3 | ||||
-rw-r--r-- | src/wlclock.c | 39 | ||||
-rw-r--r-- | src/wlclock.h | 13 |
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; |