mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
blink: implement 'blink'
This commit is contained in:
parent
07aad4a534
commit
e21ab8cf33
3 changed files with 79 additions and 1 deletions
24
main.c
24
main.c
|
|
@ -328,6 +328,7 @@ main(int argc, char *const *argv)
|
|||
.auto_margin = true,
|
||||
.window_title_stack = tll_init(),
|
||||
.flash_timer_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC),
|
||||
.blink_timer_fd = timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC),
|
||||
.vt = {
|
||||
.state = 1, /* STATE_GROUND */
|
||||
.attrs = {
|
||||
|
|
@ -685,6 +686,7 @@ main(int argc, char *const *argv)
|
|||
{.fd = term.ptmx, .events = POLLIN},
|
||||
{.fd = term.kbd.repeat.pipe_read_fd, .events = POLLIN},
|
||||
{.fd = term.flash_timer_fd, .events = POLLIN},
|
||||
{.fd = term.blink_timer_fd, .events = POLLIN},
|
||||
};
|
||||
|
||||
wl_display_flush(term.wl.display);
|
||||
|
|
@ -796,6 +798,26 @@ main(int argc, char *const *argv)
|
|||
if (term.frame_callback == NULL)
|
||||
grid_render(&term);
|
||||
}
|
||||
|
||||
if (fds[4].revents & POLLIN) {
|
||||
uint64_t expiration_count;
|
||||
ssize_t ret = read(
|
||||
term.blink_timer_fd, &expiration_count, sizeof(expiration_count));
|
||||
|
||||
if (ret < 0)
|
||||
LOG_ERRNO("failed to read blink timer");
|
||||
else
|
||||
LOG_DBG("blink timer expired %llu times",
|
||||
(unsigned long long)expiration_count);
|
||||
|
||||
term.blink_mode = term.blink_mode == BLINK_ON
|
||||
? BLINK_OFF : BLINK_ON;
|
||||
term_damage_view(&term);
|
||||
|
||||
if (term.frame_callback == NULL)
|
||||
grid_render(&term);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -885,6 +907,8 @@ out:
|
|||
|
||||
if (term.flash_timer_fd != -1)
|
||||
close(term.flash_timer_fd);
|
||||
if (term.blink_timer_fd != -1)
|
||||
close(term.blink_timer_fd);
|
||||
|
||||
if (term.ptmx != -1)
|
||||
close(term.ptmx);
|
||||
|
|
|
|||
52
render.c
52
render.c
|
|
@ -3,6 +3,7 @@
|
|||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <wayland-cursor.h>
|
||||
#include <xdg-shell.h>
|
||||
|
|
@ -117,6 +118,9 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
_bg = swap;
|
||||
}
|
||||
|
||||
if (cell->attrs.blink && term->blink_mode == BLINK_OFF)
|
||||
_fg = _bg;
|
||||
|
||||
struct rgb fg = color_hex_to_rgb(_fg);
|
||||
struct rgb bg = color_hex_to_rgb(_bg);
|
||||
|
||||
|
|
@ -128,6 +132,20 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
cairo_rectangle(buf->cairo, x, y, width, height);
|
||||
cairo_fill(buf->cairo);
|
||||
|
||||
if (cell->attrs.blink && !term->is_blinking) {
|
||||
/* First cell we see that has blink set - arm blink timer */
|
||||
LOG_DBG("arming blink timer");
|
||||
struct itimerspec alarm = {
|
||||
.it_value = {.tv_sec = 0, .tv_nsec = 500 * 1000000},
|
||||
.it_interval = {.tv_sec = 0, .tv_nsec = 500 * 1000000},
|
||||
};
|
||||
|
||||
if (timerfd_settime(term->blink_timer_fd, 0, &alarm, NULL) < 0)
|
||||
LOG_ERRNO("failed to arm blink timer");
|
||||
else
|
||||
term->is_blinking = true;
|
||||
}
|
||||
|
||||
if (cell->c[0] == '\0' || cell->attrs.conceal)
|
||||
return;
|
||||
|
||||
|
|
@ -365,7 +383,39 @@ grid_render(struct terminal *term)
|
|||
row->dirty = false;
|
||||
all_clean = false;
|
||||
|
||||
wl_surface_damage_buffer(term->wl.surface, 0, r * term->cell_height, term->width, term->cell_height);
|
||||
wl_surface_damage_buffer(
|
||||
term->wl.surface,
|
||||
0, r * term->cell_height,
|
||||
term->width, term->cell_height);
|
||||
}
|
||||
|
||||
if (term->is_blinking) {
|
||||
/* Check if there are still any visible blinking cells */
|
||||
bool none_is_blinking = true;
|
||||
for (int r = 0; r < term->rows; r++) {
|
||||
struct row *row = grid_row_in_view(term->grid, r);
|
||||
for (int col = 0; col < term->cols; col++) {
|
||||
if (row->cells[col].attrs.blink) {
|
||||
none_is_blinking = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No, disarm the blink timer */
|
||||
if (none_is_blinking) {
|
||||
LOG_DBG("disarming blink timer");
|
||||
|
||||
term->is_blinking = false;
|
||||
term->blink_mode = BLINK_ON;
|
||||
|
||||
if (timerfd_settime(
|
||||
term->blink_timer_fd, 0,
|
||||
&(struct itimerspec){0}, NULL) < 0)
|
||||
{
|
||||
LOG_ERRNO("failed to disarm blink timer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: break out to function */
|
||||
|
|
|
|||
|
|
@ -246,6 +246,10 @@ struct terminal {
|
|||
bool flash_active;
|
||||
int flash_timer_fd;
|
||||
|
||||
bool is_blinking;
|
||||
enum { BLINK_ON, BLINK_OFF } blink_mode;
|
||||
int blink_timer_fd;
|
||||
|
||||
struct vt vt;
|
||||
struct kbd kbd;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue