💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › b52f0c4cdf5eec514bc42517797ef… captured on 2024-02-05 at 09:59:50. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
0 /*
1 * ISC License
2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <poll.h>
10 #include "client.h"
11 #define PAGE_INTERNAL
12 #include "page.h"
13 #include "termbox.h"
14 #include "error.h"
15 #include "macro.h"
16 #include "memory.h"
17
18 int page_display(struct page text, int from, struct rect rect, int selected) {
19 int y;
20 int to = rect.h - rect.y;
21 from--;
22 for (y = from; y < (ssize_t)text.length && y < from + to; y++) {
23 size_t i;
24 int x;
25 x = rect.x + OFFSETX;
26 if (y < 0) continue;
27 for (i = 0; i < text.lines[y].length; i++) {
28 struct page_cell cell = text.lines[y].cells[i];
29 int fg = cell.color, bg = TB_DEFAULT;
30 if (selected && cell.link == (uint32_t)selected) {
31 fg = TB_RED;
32 }
33 if (cell.selected) {
34 if (cell.selected == text.selected) {
35 bg = TB_WHITE;
36 if (!fg || fg == TB_WHITE ||
37 fg == TB_DEFAULT)
38 fg = TB_YELLOW;
39 } else bg = TB_YELLOW;
40 }
41 tb_set_cell(x, rect.y + y - from, cell.codepoint,
42 fg, bg);
43 x += cell.width;
44 }
45 }
46 return 0;
47 }
48
49 int page_update(int in, int out, const char *data, size_t length,
50 struct page *page) {
51
52 int ret;
53 size_t i, bytes_sent;
54 struct page_line line = {0};
55 struct pollfd pfd;
56
57 /* clean up previous */
58 for (i = 0; i < page->length; i++) {
59 free(page->lines[i].cells);
60 }
61 free(page->lines);
62
63 page->length = 0;
64 page->lines = NULL;
65
66 line.cells =
67 malloc((page->width + 1) * sizeof(struct page_cell));
68 if (!line.cells) return ERROR_MEMORY_FAILURE;
69
70 bytes_sent = ret = 0;
71 pfd.fd = in;
72 pfd.events = POLLIN;
73
74 while (!ret) {
75
76 struct page_cell cell;
77 void *tmp;
78 int len;
79
80 if (!poll(&pfd, 1, 0)) {
81 int bytes = PARSER_CHUNK;
82 if (bytes_sent + bytes > length)
83 bytes = length - bytes_sent;
84 write(out, &data[bytes_sent], bytes);
85 bytes_sent += bytes;
86 continue;
87 }
88
89 len = read(in, P(cell));
90 if (len != sizeof(cell)) {
91 ret = -1;
92 break;
93 }
94
95 switch (cell.special) {
96 case PAGE_EOF: break;
97 case PAGE_BLANK: break;
98 case PAGE_RESET: break;
99 case PAGE_NEWLINE:
100 {
101 struct page_line *ptr;
102 size_t length;
103
104 tmp = realloc(page->lines,
105 (page->length + 1) * sizeof(line));
106 if (!tmp) {
107 free(page->lines);
108 ret = ERROR_MEMORY_FAILURE;
109 break;
110 }
111 page->lines = tmp;
112
113 length = sizeof(struct page_cell) * line.length;
114 ptr = &page->lines[page->length];
115 ptr->cells = malloc(length);
116 if (!ptr->cells) {
117 free(page->lines);
118 ret = ERROR_MEMORY_FAILURE;
119 break;
120 }
121 memcpy(ptr->cells, line.cells, length);
122 ptr->length = line.length;
123
124 line.length = 0;
125 page->length++;
126 }
127 break;
128 default:
129 if (line.length >= (size_t)page->width) break;
130 line.cells[line.length] = cell;
131 line.length++;
132 break;
133 }
134 if (cell.special == PAGE_EOF) break;
135 }
136 free(line.cells);
137 return ret;
138 }
139
140 int page_free(struct page page) {
141 size_t i;
142 for (i = 0; i < page.length; i++) {
143 free(page.lines[i].cells);
144 }
145 free(page.lines);
146 for (i = 0; i < page.links_count; i++) {
147 free_readonly(page.links[i], strnlen(page.links[i], MAX_URL));
148 }
149 free(page.links);
150 free(page.img);
151 return 0;
152 }
153