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