From eba48b7cec388325b237fd1b5a3c6d2e04deba12 Mon Sep 17 00:00:00 2001
From: Simeon Simeonov
Date: Thu, 19 Mar 2020 16:51:23 +0100
Subject: Initial merge i3lock-extended -> i3lock
---
extras.c | 448 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 448 insertions(+)
create mode 100644 extras.c
(limited to 'extras.c')
diff --git a/extras.c b/extras.c
new file mode 100644
index 0000000..37819f5
--- /dev/null
+++ b/extras.c
@@ -0,0 +1,448 @@
+/*
+ * This file is part of i3lock-extended
+ * Copyright (C) 2020 Simeon Simeonov
+
+ * i3lock-extended is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * i3lock-extended is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+#include "randr.h"
+#include "extras.h"
+
+
+extern int failed_attempts;
+
+
+static void i3lock_color_to_array(double *rgb16, const char *color) {
+
+ char strgroups[3][3] = {{color[0], color[1], '\0'},
+ {color[2], color[3], '\0'},
+ {color[4], color[5], '\0'}};
+ *rgb16 = strtol(strgroups[0], NULL, 16) / 255.0;
+ *(rgb16 + 1) = strtol(strgroups[1], NULL, 16) / 255.0;
+ *(rgb16 + 2) = strtol(strgroups[2], NULL, 16) / 255.0;
+
+}
+
+
+static void i3clock_fetch_digital_clock_xy(int *x,
+ int *y,
+ const i3lock_digital_clock_t *dc,
+ const uint32_t *resolution,
+ int text_length) {
+
+ /* x */
+ if (dc->horizontal_alignment == I3LOCK_ALIGN_CENTER) {
+ *x = resolution[0] / 2 - text_length * dc->text_size / 2;
+ } else if (dc->horizontal_alignment == I3LOCK_ALIGN_RIGHT) {
+ *x = resolution[0] - resolution[0] / 10 - text_length * dc->text_size;
+ } else {
+ /* left */
+ *x = resolution[0] / 10; /* 10% */
+ }
+
+ /* y */
+ if (dc->vertical_alignment == I3LOCK_ALIGN_MIDDLE) {
+ *y = resolution[1] / 2 - dc->text_size / 2;
+ } else if (dc->vertical_alignment == I3LOCK_ALIGN_BOTTOM) {
+ *y = resolution[1] - resolution[1] / 10 - dc->text_size;
+ } else {
+ /* top */
+ *y = resolution[1] / 10; /* 10% */
+ }
+
+}
+
+
+static void i3clock_fetch_led_clock_xy(int *x,
+ int *y,
+ const i3lock_led_clock_t *lc,
+ const uint32_t *resolution) {
+ int clock_length, clock_height;
+
+ /* x */
+ clock_length = 6 * resolution[1] / I3LOCK_SCALE_LED_SPACING + \
+ 5 * resolution[1] / I3LOCK_SCALE_LED_LENGTH;
+ if (lc->horizontal_alignment == I3LOCK_ALIGN_CENTER) {
+ *x = resolution[0] / 2 - clock_length / 2;
+ } else if (lc->horizontal_alignment == I3LOCK_ALIGN_RIGHT) {
+ *x = resolution[0] - resolution[0] / 10 - clock_length;
+ } else {
+ /* left */
+ *x = resolution[0] / 10; /* 10% */
+ }
+
+ /* y */
+ clock_height = 3 * resolution[1] / I3LOCK_SCALE_LED_SPACING + \
+ 2 * resolution[1] / I3LOCK_SCALE_LED_LENGTH;
+ if (lc->vertical_alignment == I3LOCK_ALIGN_MIDDLE) {
+ *y = resolution[1] / 2 - clock_height / 2;
+ } else if (lc->vertical_alignment == I3LOCK_ALIGN_BOTTOM) {
+ *y = resolution[1] - resolution[1] / 10 - clock_height;
+ } else {
+ /* top */
+ *y = resolution[1] / 10; /* 10% */
+ }
+
+}
+
+
+static void i3lock_draw_led(cairo_t *cr,
+ double x,
+ double y,
+ double length,
+ int type,
+ const i3lock_led_clock_t *lc) {
+ double border_color[3], face_color[3];
+ i3lock_color_to_array(border_color, lc->led_border_color);
+ if (type) {
+ /* LED on */
+ i3lock_color_to_array(face_color, lc->led_on_color);
+ } else {
+ i3lock_color_to_array(face_color, lc->led_off_color);
+ }
+ cairo_set_line_width(cr, 2);
+ cairo_rectangle(cr, x, y, length, length);
+ cairo_set_source_rgb(cr, face_color[0], face_color[1], face_color[2]);
+ cairo_fill(cr);
+ cairo_rectangle(cr, x, y, length, length);
+ cairo_set_source_rgb(cr, border_color[0], border_color[1], border_color[2]);
+ cairo_stroke(cr);
+}
+
+
+void i3lock_draw_digital_clock(cairo_t *cr,
+ const i3lock_digital_clock_t *dc,
+ const uint32_t *resolution,
+ const struct tm *brokentime) {
+ double rgb16[3];
+ char current_time_str[128];
+ int x, y;
+ strftime(current_time_str,
+ 128,
+ dc->template,
+ brokentime);
+ i3lock_color_to_array(rgb16, dc->color);
+ cairo_set_source_rgb(cr,
+ rgb16[0],
+ rgb16[1],
+ rgb16[2]);
+ cairo_set_font_size(cr, dc->text_size);
+ if (xr_screens > 0) {
+ /* xinerama */
+ int screen;
+ uint32_t screen_resolution[2];
+ for (screen = 0; screen < xr_screens; ++screen) {
+ screen_resolution[0] = xr_resolutions[screen].width;
+ screen_resolution[1] = xr_resolutions[screen].height;
+ i3clock_fetch_digital_clock_xy(&x,
+ &y,
+ dc,
+ screen_resolution,
+ strlen(current_time_str));
+ cairo_move_to(cr,
+ x + xr_resolutions[screen].x,
+ y + xr_resolutions[screen].y);
+ cairo_show_text(cr, current_time_str);
+ }
+ return;
+ }
+
+ i3clock_fetch_digital_clock_xy(&x,
+ &y,
+ dc,
+ resolution,
+ strlen(current_time_str));
+ /* printf("%dx%d\n", *resolution, *(resolution + 1)); */
+ cairo_move_to(cr, x, y);
+ cairo_show_text(cr, current_time_str);
+
+}
+
+
+void i3lock_draw_string(cairo_t *cr,
+ const char *formatted_string,
+ const i3lock_elapsed_time_t *et,
+ const uint32_t *resolution) {
+ double rgb16[3];
+ int x, y;
+
+ /* create a dummy i3lock_digital_clock_t structure in order to reuse
+ i3clock_fetch_digital_clock_xy */
+ i3lock_digital_clock_t dc = {et->text_size,
+ "",
+ "",
+ et->horizontal_alignment,
+ et->vertical_alignment};
+ i3lock_color_to_array(rgb16, et->color);
+ cairo_set_source_rgb(cr,
+ rgb16[0],
+ rgb16[1],
+ rgb16[2]);
+ cairo_set_font_size(cr, et->text_size);
+ if (xr_screens > 0) {
+ /* xinerama */
+ int screen;
+ uint32_t screen_resolution[2];
+ for (screen = 0; screen < xr_screens; ++screen) {
+ screen_resolution[0] = xr_resolutions[screen].width;
+ screen_resolution[1] = xr_resolutions[screen].height;
+ i3clock_fetch_digital_clock_xy(&x,
+ &y,
+ &dc,
+ screen_resolution,
+ strlen(formatted_string));
+ cairo_move_to(cr,
+ x + xr_resolutions[screen].x,
+ y + xr_resolutions[screen].y);
+ cairo_show_text(cr, formatted_string);
+ }
+ return;
+ }
+
+ i3clock_fetch_digital_clock_xy(&x,
+ &y,
+ &dc,
+ resolution,
+ strlen(formatted_string));
+ /* printf("%dx%d\n", *resolution, *(resolution + 1)); */
+ cairo_move_to(cr, x, y);
+ cairo_show_text(cr, formatted_string);
+
+}
+
+
+void i3lock_draw_elapsed_time(cairo_t *cr,
+ const i3lock_elapsed_time_t *et,
+ const uint32_t *resolution,
+ const time_t *now) {
+ double rgb16[3];
+ char elapsed_time_str[128];
+ int x, y, seconds, minutes, hours, diff_seconds;
+
+ /* create a dummy i3lock_digital_clock_t structure in ordet to reuse
+ i3clock_fetch_digital_clock_xy */
+ i3lock_digital_clock_t dc = {et->text_size,
+ "",
+ "",
+ et->horizontal_alignment,
+ et->vertical_alignment};
+
+ diff_seconds = (int) difftime(*now, et->start_time);
+ hours = diff_seconds / 3600;
+ minutes = (diff_seconds - hours * 3600) / 60;
+ seconds = diff_seconds - hours * 3600 - minutes * 60;
+ if (hours) {
+ snprintf(elapsed_time_str,
+ 128,
+ "%d:%02d:%02d",
+ hours,
+ minutes,
+ seconds);
+ } else {
+ snprintf(elapsed_time_str, 128, "%02d:%02d", minutes, seconds);
+ }
+ if (failed_attempts) {
+ char failed_attempts_str[16]; /* ... that many attempts */
+ snprintf(failed_attempts_str,
+ 16,
+ " (%d)",
+ failed_attempts);
+ strncat(elapsed_time_str, failed_attempts_str, 16);
+ }
+ i3lock_color_to_array(rgb16, et->color);
+ cairo_set_source_rgb(cr,
+ rgb16[0],
+ rgb16[1],
+ rgb16[2]);
+ cairo_set_font_size(cr, et->text_size);
+ if (xr_screens > 0) {
+ /* xinerama */
+ int screen;
+ uint32_t screen_resolution[2];
+ for (screen = 0; screen < xr_screens; ++screen) {
+ screen_resolution[0] = xr_resolutions[screen].width;
+ screen_resolution[1] = xr_resolutions[screen].height;
+ i3clock_fetch_digital_clock_xy(&x,
+ &y,
+ &dc,
+ screen_resolution,
+ strlen(elapsed_time_str));
+ cairo_move_to(cr,
+ x + xr_resolutions[screen].x,
+ y + xr_resolutions[screen].y);
+ cairo_show_text(cr, elapsed_time_str);
+ }
+ return;
+ }
+
+ i3clock_fetch_digital_clock_xy(&x,
+ &y,
+ &dc,
+ resolution,
+ strlen(elapsed_time_str));
+ /* printf("%dx%d\n", *resolution, *(resolution + 1)); */
+ cairo_move_to(cr, x, y);
+ cairo_show_text(cr, elapsed_time_str);
+
+}
+
+
+void i3lock_draw_led_clock(cairo_t *cr,
+ const i3lock_led_clock_t *lc,
+ const uint32_t *resolution,
+ const struct tm *brokentime) {
+ int side_length, space_length, base_x, base_y;
+ int base_x_h; /* used to make the code more readable */
+ if (xr_screens > 0) {
+ /* xinerama */
+ int screen;
+ uint32_t screen_resolution[2];
+ for (screen = 0; screen < xr_screens; ++screen) {
+ screen_resolution[0] = xr_resolutions[screen].width;
+ screen_resolution[1] = xr_resolutions[screen].height;
+ side_length = xr_resolutions[screen].height / I3LOCK_SCALE_LED_SPACING;
+ space_length = xr_resolutions[screen].height / I3LOCK_SCALE_LED_LENGTH;
+ i3clock_fetch_led_clock_xy(&base_x,
+ &base_y,
+ lc,
+ screen_resolution);
+ base_x += xr_resolutions[screen].x;
+ base_y += xr_resolutions[screen].y;
+ base_x_h = base_x + space_length / 2 + side_length / 2;
+
+ /* hours */
+ i3lock_draw_led(cr,
+ base_x_h,
+ base_y,
+ side_length,
+ brokentime->tm_hour & 16,
+ lc);
+ i3lock_draw_led(cr,
+ base_x_h + space_length + side_length,
+ base_y,
+ side_length,
+ brokentime->tm_hour & 8,
+ lc);
+ i3lock_draw_led(cr,
+ base_x_h + 2 * (space_length + side_length),
+ base_y,
+ side_length,
+ brokentime->tm_hour & 4,
+ lc);
+ i3lock_draw_led(cr,
+ base_x_h + 3 * (space_length + side_length),
+ base_y,
+ side_length,
+ brokentime->tm_hour & 2,
+ lc);
+ i3lock_draw_led(cr,
+ base_x_h + 4 * (space_length + side_length),
+ base_y,
+ side_length,
+ brokentime->tm_hour & 1,
+ lc);
+
+ /* minutes */
+ i3lock_draw_led(cr,
+ base_x,
+ base_y + side_length + space_length,
+ side_length,
+ brokentime->tm_min & 32,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + side_length + space_length,
+ base_y + side_length + space_length,
+ side_length,
+ brokentime->tm_min & 16,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 2 * (side_length + space_length),
+ base_y + side_length + space_length,
+ side_length,
+ brokentime->tm_min & 8,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 3 * (side_length + space_length),
+ base_y + side_length + space_length,
+ side_length,
+ brokentime->tm_min & 4,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 4 * (side_length + space_length),
+ base_y + side_length + space_length,
+ side_length,
+ brokentime->tm_min & 2,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 5 * (side_length + space_length),
+ base_y + side_length + space_length,
+ side_length,
+ brokentime->tm_min & 1,
+ lc);
+
+ /* seconds */
+ i3lock_draw_led(cr,
+ base_x,
+ base_y + 2 * (side_length + space_length),
+ side_length,
+ brokentime->tm_sec & 32,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + side_length + space_length,
+ base_y + 2 * (side_length + space_length),
+ side_length,
+ brokentime->tm_sec & 16,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 2 * (side_length + space_length),
+ base_y + 2 * (side_length + space_length),
+ side_length,
+ brokentime->tm_sec & 8,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 3 * (side_length + space_length),
+ base_y + 2 * (side_length + space_length),
+ side_length,
+ brokentime->tm_sec & 4,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 4 * (side_length + space_length),
+ base_y + 2 * (side_length + space_length),
+ side_length,
+ brokentime->tm_sec & 2,
+ lc);
+ i3lock_draw_led(cr,
+ base_x + 5 * (side_length + space_length),
+ base_y + 2 * (side_length + space_length),
+ side_length,
+ brokentime->tm_sec & 1,
+ lc);
+ }
+ return;
+ }
+
+}
+
+
--
cgit v1.3