💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › 2c2c43e903fd910a5e08bee41742e… captured on 2023-12-28 at 15:43:56. 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_read, bytes_sent, cells_read;
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 cells_read = bytes_sent = bytes_read = 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 bytes_sent - bytes_read < PARSER_CHUNK * 2) {
82 int bytes = PARSER_CHUNK;
83 if (bytes_sent + bytes > length)
84 bytes = length - bytes_sent;
85 write(out, &data[bytes_sent], bytes);
86 bytes_sent += bytes;
87 }
88
89 len = read(in, P(cell));
90 if (len != sizeof(cell)) {
91 ret = -1;
92 break;
93 }
94 cells_read++;
95
96 switch (cell.special) {
97 case PAGE_EOF: break;
98 case PAGE_BLANK: break;
99 case PAGE_RESET:
100 bytes_read = cell.codepoint;
101 break;
102 case PAGE_NEWLINE:
103 {
104 struct page_line *ptr;
105 size_t length;
106
107 tmp = realloc(page->lines,
108 (page->length + 1) * sizeof(line));
109 if (!tmp) {
110 free(page->lines);
111 ret = ERROR_MEMORY_FAILURE;
112 break;
113 }
114 page->lines = tmp;
115
116 length = sizeof(struct page_cell) * line.length;
117 ptr = &page->lines[page->length];
118 ptr->cells = malloc(length);
119 if (!ptr->cells) {
120 free(page->lines);
121 ret = ERROR_MEMORY_FAILURE;
122 break;
123 }
124 memcpy(ptr->cells, line.cells, length);
125 ptr->length = line.length;
126
127 line.length = 0;
128 page->length++;
129 }
130 break;
131 default:
132 if (line.length >= (size_t)page->width) break;
133 line.cells[line.length] = cell;
134 line.length++;
135 break;
136 }
137 if (cell.special == PAGE_EOF) break;
138 }
139 free(line.cells);
140 return ret;
141 }
142
143 int page_free(struct page page) {
144 size_t i;
145 for (i = 0; i < page.length; i++) {
146 free(page.lines[i].cells);
147 }
148 free(page.lines);
149 for (i = 0; i < page.links_count; i++) {
150 free_readonly(page.links[i], strnlen(page.links[i], MAX_URL));
151 }
152 free(page.links);
153 free(page.img);
154 return 0;
155 }
156