1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#include "minibuffer.h"
#include "buffer.h"
#include "display.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
static struct minibuffer {
struct buffer *buffer;
struct timespec expires;
} g_minibuffer = {0};
struct update_hook_result 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 update_hook_result){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; }
|