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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
#include <popups/popup.h>
#include <libfont/fonts.h>
#include <knob/format.h>
#include <knob/heap.h>
#include <stdint.h>
#include <stdarg.h>
#define PADDING 6
#define FONT "fixed-10"
static const struct font_info *info_font = 0;
static const struct key_packet info_quits[] = {
{ .key_id = KEY_ESCAPE, .modifiers = NO_MODS },
{ .key_id = 0 }
};
void info_popup(struct popup *into, const char *msg, uint8_t fg, uint8_t bg) {
if (!info_font)
info_font = get_font(FONT);
uint32_t w = 0, h = 1, lw = 0;
for (const char *i = msg; *i; ++i)
if (*i == '\n') {
++h;
if (lw > w)
w = lw;
lw = 0;
}
else
++lw;
if (lw > w)
w = lw;
into->has_quit = false;
into->quit_binds = (struct key_packet *)info_quits;
const uint32_t pitch = info_font->space_width * w + 2 * PADDING;
const uint32_t height = info_font->space_height * h + 2 * PADDING;
uint8_t *const pixbuf = get_block(pitch * height);
for (uint32_t y = 0; y < height; ++y)
for (uint32_t x = 0; x < pitch; ++x)
pixbuf[y * pitch + x] = bg;
uint32_t my = 0;
uint32_t mx = 0;
--msg;
while (*++msg) {
if (*msg == '\n') {
++my;
mx = 0;
}
else
put_char(info_font, *msg, pixbuf + (my * info_font->space_height + PADDING) * pitch + mx++ * info_font->space_width + PADDING, pitch, bg, fg);
}
into->pixbuf = pixbuf;
into->handle = _new_window(pitch, height, pixbuf);
}
void info_popupf_v(struct popup *into, const char *text, uint8_t fg, uint8_t bg, va_list args) {
char *const msg = format_v(text, args);
info_popup(into, msg, fg, bg);
free_block(msg);
}
void info_popupf(struct popup *into, const char *text, uint8_t fg, uint8_t bg, ...) {
va_list args;
va_start(args, bg);
info_popupf_v(into, text, fg, bg, args);
va_end(args);
}
|