#include "minibuffer.h" #include "buffer.h" #include "display.h" #include #include #include static struct minibuffer { struct buffer *buffer; struct timespec expires; } g_minibuffer = {0}; struct margin update(struct buffer *buffer, struct command_list *commands, uint32_t width, uint32_t height, uint64_t frame_time, void *userdata) { struct timespec current; struct minibuffer *mb = (struct minibuffer *)userdata; clock_gettime(CLOCK_MONOTONIC, ¤t); if (current.tv_sec >= mb->expires.tv_sec) { buffer_clear(buffer); } return (struct margin){0}; } void minibuffer_init(struct buffer *buffer) { g_minibuffer.buffer = buffer; buffer_add_update_hook(g_minibuffer.buffer, update, &g_minibuffer); } void echo(uint32_t timeout, const char *fmt, va_list args) { char buff[2048]; size_t nbytes = vsnprintf(buff, 2048, fmt, args); // vsnprintf returns how many characters it would have wanted to write in case // of overflow buffer_clear(g_minibuffer.buffer); buffer_add_text(g_minibuffer.buffer, (uint8_t *)buff, nbytes > 2048 ? 2048 : nbytes); clock_gettime(CLOCK_MONOTONIC, &g_minibuffer.expires); g_minibuffer.expires.tv_sec += timeout; } void minibuffer_echo(const char *fmt, ...) { va_list args; va_start(args, fmt); echo(1000, fmt, args); va_end(args); } void minibuffer_echo_timeout(uint32_t timeout, const char *fmt, ...) { va_list args; va_start(args, fmt); echo(timeout, fmt, args); va_end(args); } bool minibuffer_displaying() { return !buffer_is_empty(g_minibuffer.buffer); } void minibuffer_clear() { g_minibuffer.expires.tv_nsec = 0; }