summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/render.c91
-rw-r--r--src/render.h3
-rw-r--r--src/surface.c86
-rw-r--r--src/surface.h11
-rw-r--r--src/wlclock.c8
-rw-r--r--src/wlclock.h1
6 files changed, 166 insertions, 34 deletions
diff --git a/src/render.c b/src/render.c
index eb23b7a..7d189ec 100644
--- a/src/render.c
+++ b/src/render.c
@@ -121,11 +121,10 @@ static void draw_clock_face (cairo_t *cairo, struct Wlclock_dimensions *dimensio
double cx = scale * (dimensions->center_x + (dimensions->center_size / 2));
double cy = scale * (dimensions->center_y + (dimensions->center_size / 2));
- double or = scale * 0.9 * dimensions->center_size / 2;
+ double or = scale * 0.9 * dimensions->center_size / 2; /* Radii mimick xclock. */
double ir = scale * 0.85 * dimensions->center_size / 2;
double bir = scale * 0.8 * dimensions->center_size / 2;
- double phi;
- double phi_step = 2 * PI / 60;
+ double phi, phi_step = 2 * PI / 60;
cairo_save(cairo);
for (int i = 0; i < 60; i++)
@@ -143,6 +142,51 @@ static void draw_clock_face (cairo_t *cairo, struct Wlclock_dimensions *dimensio
cairo_restore(cairo);
}
+static int hour_two_pseudo_min (int hour)
+{
+ if ( hour > 12 )
+ hour -= 12;
+ return hour * 5;
+}
+
+static void draw_clock_hands (cairo_t *cairo, int32_t size, int32_t scale, struct Wlclock *clock)
+{
+ double cxy = scale * size / 2;
+ double mr = scale * 0.6 * size / 2; /* Radii mimick xclock. */
+ double hr = scale * 0.4 * size / 2;
+ double ir = scale * 0.075 * size / 2;
+ double tip_phi, back_phi_1, back_phi_2, phi_step = 2 * PI / 60;
+ struct tm tm = *localtime(&clock->now);
+
+ cairo_save(cairo);
+
+ /* Minutes */
+ tip_phi = phi_step * (tm.tm_min + 45);
+ back_phi_1 = phi_step * (tm.tm_min + 45 + 20);
+ back_phi_2 = phi_step * (tm.tm_min + 45 + 40);
+ cairo_move_to(cairo, cxy + mr * cos(tip_phi), cxy + mr * sin(tip_phi));
+ cairo_line_to(cairo, cxy + ir * cos(back_phi_1), cxy + ir * sin(back_phi_1));
+ cairo_line_to(cairo, cxy + ir * cos(back_phi_2), cxy + ir * sin(back_phi_2));
+ cairo_line_to(cairo, cxy + mr * cos(tip_phi), cxy + mr * sin(tip_phi));
+
+ /* Hours */
+ // TODO optinally make hour hand progress between to hours intstead of instantly snapping
+ int pseudo_min = hour_two_pseudo_min(tm.tm_hour);
+ tip_phi = phi_step * (pseudo_min + 45);
+ back_phi_1 = phi_step * (pseudo_min + 45 + 20);
+ back_phi_2 = phi_step * (pseudo_min + 45 + 40);
+ cairo_move_to(cairo, cxy + hr * cos(tip_phi), cxy + hr * sin(tip_phi));
+ cairo_line_to(cairo, cxy + ir * cos(back_phi_1), cxy + ir * sin(back_phi_1));
+ cairo_line_to(cairo, cxy + ir * cos(back_phi_2), cxy + ir * sin(back_phi_2));
+ cairo_line_to(cairo, cxy + hr * cos(tip_phi), cxy + hr * sin(tip_phi));
+
+ cairo_close_path(cairo);
+ colour_set_cairo_source(cairo, &clock->clock_colour);
+ cairo_fill(cairo);
+
+ cairo_restore(cairo);
+}
+
static void clear_buffer (cairo_t *cairo)
{
cairo_save(cairo);
@@ -151,29 +195,54 @@ static void clear_buffer (cairo_t *cairo)
cairo_restore(cairo);
}
-void render_surface_frame (struct Wlclock_surface *surface)
+void render_background_frame (struct Wlclock_surface *surface)
{
struct Wlclock_output *output = surface->output;
struct Wlclock *clock = output->clock;
uint32_t scale = output->scale;
- clocklog(clock, 2, "[render] Render frame: global_name=%d\n", output->global_name);
+ clocklog(clock, 2, "[render] Render background frame: global_name=%d\n",
+ output->global_name);
/* Get new/next buffer. */
- if (! next_buffer(&surface->current_buffer, clock->shm, surface->buffers,
+ if (! next_buffer(&surface->current_background_buffer, clock->shm,
+ surface->background_buffers,
surface->dimensions.w * scale,
surface->dimensions.h * scale))
return;
- cairo_t *cairo = surface->current_buffer->cairo;
+ cairo_t *cairo = surface->current_background_buffer->cairo;
clear_buffer(cairo);
draw_background(cairo, &surface->dimensions, scale, clock);
draw_clock_face(cairo, &surface->dimensions, scale, clock);
- // TODO draw clock hands to subsurface
+ wl_surface_set_buffer_scale(surface->background_surface, scale);
+ wl_surface_attach(surface->background_surface, surface->current_background_buffer->buffer, 0, 0);
+ wl_surface_damage_buffer(surface->background_surface, 0, 0, INT32_MAX, INT32_MAX);
+}
+
+void render_hands_frame (struct Wlclock_surface *surface)
+{
+ struct Wlclock_output *output = surface->output;
+ struct Wlclock *clock = output->clock;
+ uint32_t scale = output->scale;
+ clocklog(clock, 2, "[render] Render hands frame: global_name=%d\n",
+ output->global_name);
+
+ /* Get new/next buffer. */
+ if (! next_buffer(&surface->current_hands_buffer, clock->shm,
+ surface->hands_buffers,
+ surface->dimensions.center_size * scale,
+ surface->dimensions.center_size * scale))
+ return;
+
+ cairo_t *cairo = surface->current_hands_buffer->cairo;
+ clear_buffer(cairo);
+
+ draw_clock_hands(cairo, surface->dimensions.center_size, scale, clock);
- wl_surface_set_buffer_scale(surface->surface, scale);
- wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0);
- wl_surface_damage_buffer(surface->surface, 0, 0, INT32_MAX, INT32_MAX);
+ wl_surface_set_buffer_scale(surface->hands_surface, scale);
+ wl_surface_attach(surface->hands_surface, surface->current_hands_buffer->buffer, 0, 0);
+ wl_surface_damage_buffer(surface->hands_surface, 0, 0, INT32_MAX, INT32_MAX);
}
diff --git a/src/render.h b/src/render.h
index ca4e54b..ed82de9 100644
--- a/src/render.h
+++ b/src/render.h
@@ -3,6 +3,7 @@
struct Wlclock_surface;
-void render_surface_frame (struct Wlclock_surface *surface);
+void render_background_frame (struct Wlclock_surface *surface);
+void render_hands_frame (struct Wlclock_surface *surface);
#endif
diff --git a/src/surface.c b/src/surface.c
index 19bd2d7..da3666d 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -96,10 +96,21 @@ static int32_t get_exclusive_zone (struct Wlclock_surface *surface)
return surface->output->clock->exclusive_zone;
}
+static void configure_subsurface (struct Wlclock_surface *surface)
+{
+ clocklog(surface->output->clock, 1, "[surface] Configuring sub surface: global_name=%d\n",
+ surface->output->global_name);
+ wl_subsurface_set_position(surface->subsurface,
+ surface->dimensions.center_x, surface->dimensions.center_y);
+ struct wl_region *region = wl_compositor_create_region(surface->output->clock->compositor);
+ wl_surface_set_input_region(surface->hands_surface, region);
+ wl_region_destroy(region);
+}
+
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",
+ clocklog(clock, 1, "[surface] Configuring layer surface: global_name=%d\n",
surface->output->global_name);
zwlr_layer_surface_v1_set_size(surface->layer_surface,
surface->dimensions.w, surface->dimensions.h);
@@ -112,7 +123,7 @@ static void configure_layer_surface (struct Wlclock_surface *surface)
if (! clock->input)
{
struct wl_region *region = wl_compositor_create_region(clock->compositor);
- wl_surface_set_input_region(surface->surface, region);
+ wl_surface_set_input_region(surface->background_surface, region);
wl_region_destroy(region);
}
}
@@ -129,20 +140,21 @@ bool create_surface (struct Wlclock_output *output)
return false;
}
- output->surface = surface;
- surface->dimensions = clock->dimensions;
- surface->output = output;
- surface->surface = NULL;
- surface->layer_surface = NULL;
- surface->configured = false;
+ output->surface = surface;
+ surface->dimensions = clock->dimensions;
+ surface->output = output;
+ surface->background_surface = NULL;
+ surface->hands_surface = NULL;
+ surface->layer_surface = NULL;
+ surface->configured = false;
- if ( NULL == (surface->surface = wl_compositor_create_surface(clock->compositor)) )
+ if ( NULL == (surface->background_surface = wl_compositor_create_surface(clock->compositor)) )
{
- clocklog(NULL, 0, "ERROR: Compositor did not create wl_surface.\n");
+ clocklog(NULL, 0, "ERROR: Compositor did not create wl_surface (background).\n");
return false;
}
if ( NULL == (surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
- clock->layer_shell, surface->surface,
+ clock->layer_shell, surface->background_surface,
output->wl_output, clock->layer,
clock->namespace)) )
{
@@ -150,10 +162,25 @@ bool create_surface (struct Wlclock_output *output)
return false;
}
+ if ( NULL == (surface->hands_surface = wl_compositor_create_surface(clock->compositor)) )
+ {
+ clocklog(NULL, 0, "ERROR: Compositor did not create wl_surface (hands).\n");
+ return false;
+ }
+ if ( NULL == (surface->subsurface = wl_subcompositor_get_subsurface(
+ clock->subcompositor, surface->hands_surface,
+ surface->background_surface)) )
+ {
+ clocklog(NULL, 0, "ERROR: Compositor did not create wl_subsurface.\n");
+ return false;
+ }
+
configure_layer_surface(surface);
+ configure_subsurface(surface);
zwlr_layer_surface_v1_add_listener(surface->layer_surface,
&layer_surface_listener, surface);
- wl_surface_commit(surface->surface);
+ wl_surface_commit(surface->background_surface);
+ wl_surface_commit(surface->hands_surface);
return true;
}
@@ -164,10 +191,16 @@ void destroy_surface (struct Wlclock_surface *surface)
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]);
+ if ( surface->subsurface != NULL )
+ wl_subsurface_destroy(surface->subsurface);
+ if ( surface->background_surface != NULL )
+ wl_surface_destroy(surface->background_surface);
+ if ( surface->hands_surface != NULL )
+ wl_surface_destroy(surface->hands_surface);
+ finish_buffer(&surface->background_buffers[0]);
+ finish_buffer(&surface->background_buffers[1]);
+ finish_buffer(&surface->hands_buffers[0]);
+ finish_buffer(&surface->hands_buffers[1]);
free(surface);
}
@@ -185,8 +218,11 @@ void update_surface (struct Wlclock_surface *surface)
if ( surface == NULL || ! surface->configured )
return;
configure_layer_surface(surface);
- render_surface_frame(surface);
- wl_surface_commit(surface->surface);
+ configure_subsurface(surface);
+ render_background_frame(surface);
+ render_hands_frame(surface);
+ wl_surface_commit(surface->background_surface);
+ wl_surface_commit(surface->hands_surface);
}
void update_all_surfaces (struct Wlclock *clock)
@@ -197,3 +233,17 @@ void update_all_surfaces (struct Wlclock *clock)
if ( op->surface != NULL )
update_surface(op->surface);
}
+
+void update_all_hands (struct Wlclock *clock)
+{
+ clocklog(clock, 1, "[surface] Updating all hands.\n");
+ struct Wlclock_output *op, *tmp;
+ wl_list_for_each_safe(op, tmp, &clock->outputs, link)
+ if ( op->surface != NULL )
+ {
+ render_hands_frame(op->surface);
+ wl_surface_commit(op->surface->hands_surface);
+ wl_surface_commit(op->surface->background_surface);
+ }
+}
+
diff --git a/src/surface.h b/src/surface.h
index 0f6ce48..d2dcb25 100644
--- a/src/surface.h
+++ b/src/surface.h
@@ -15,12 +15,16 @@ struct Wlclock_output;
struct Wlclock_surface
{
struct Wlclock_output *output;
- struct wl_surface *surface;
+ struct wl_surface *background_surface;
+ struct wl_surface *hands_surface;
+ struct wl_subsurface *subsurface;
struct zwlr_layer_surface_v1 *layer_surface;
struct Wlclock_dimensions dimensions;
- struct Wlclock_buffer buffers[2];
- struct Wlclock_buffer *current_buffer;
+ struct Wlclock_buffer background_buffers[2];
+ struct Wlclock_buffer *current_background_buffer;
+ struct Wlclock_buffer hands_buffers[2];
+ struct Wlclock_buffer *current_hands_buffer;
bool configured;
};
@@ -29,5 +33,6 @@ void destroy_surface (struct Wlclock_surface *surface);
void destroy_all_surfaces (struct Wlclock *clock);
void update_surface (struct Wlclock_surface *surface);
void update_all_surfaces (struct Wlclock *clock);
+void update_all_hands (struct Wlclock *clock);
#endif
diff --git a/src/wlclock.c b/src/wlclock.c
index 9397ca0..8d23cdb 100644
--- a/src/wlclock.c
+++ b/src/wlclock.c
@@ -33,6 +33,12 @@ static void registry_handle_global (void *data, struct wl_registry *registry,
clocklog(clock, 2, "[main] Get wl_compositor.\n");
clock->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 4);
}
+ if (! strcmp(interface, wl_subcompositor_interface.name))
+ {
+ clocklog(clock, 2, "[main] Get wl_subcompositor.\n");
+ clock->subcompositor = wl_registry_bind(registry, name,
+ &wl_subcompositor_interface, 1);
+ }
else if (! strcmp(interface, wl_shm_interface.name))
{
clocklog(clock, 2, "[main] Get wl_shm.\n");
@@ -500,7 +506,7 @@ static void clock_run (struct Wlclock *clock)
if ( ret == 0 )
{
clock->now = time(NULL);
- // TODO update clock hands
+ update_all_hands(clock);
continue;
}
else if ( ret < 0 )
diff --git a/src/wlclock.h b/src/wlclock.h
index ec8f981..d76bd86 100644
--- a/src/wlclock.h
+++ b/src/wlclock.h
@@ -26,6 +26,7 @@ struct Wlclock
struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor;
+ struct wl_subcompositor *subcompositor;
struct wl_shm *shm;
struct zwlr_layer_shell_v1 *layer_shell;
struct zxdg_output_manager_v1 *xdg_output_manager;