💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › a6ed8e421da9e785845c643449afa… captured on 2024-02-05 at 10:03:57. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-12-28)
-=-=-=-=-=-=-
0 /*
1 * ISC License
2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
3 */
4 #include <stddef.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdint.h>
9 #include <pthread.h>
10 #include "termbox.h"
11 #include "macro.h"
12 #include "config.h"
13 #include "client.h"
14 #include "gemini.h"
15 #include "page.h"
16 #include "request.h"
17 #include "tab.h"
18 #include "strnstr.h"
19 #include "error.h"
20 #include "parser.h"
21 #include "known_hosts.h"
22 #include "image.h"
23
24 void tab_clean_requests(struct tab *tab);
25
26 void tab_display_loading(struct tab *tab, struct rect rect) {
27 int off[][2] = {
28 {0, 0}, {1, 0}, {2, 0}, {2, 1}, {2, 2}, {1, 2}, {0, 2}, {0, 1}
29 };
30 int x = rect.x + rect.w - 4, y = rect.y + rect.h - 5, i;
31 struct timespec now;
32 tab->loading = (tab->loading + 1) % (sizeof(off) / sizeof(*off));
33
34 clock_gettime(CLOCK_MONOTONIC, &now);
35 tab->loading = (now.tv_sec * 10 + now.tv_nsec / 100000000) %
36 (sizeof(off) / sizeof(*off));
37
38 for (i = 0; i < (int)(sizeof(off) / sizeof(*off)); i++) {
39 tb_set_cell(x + off[i][0], y + off[i][1], ' ', TB_WHITE,
40 i != tab->loading ? TB_WHITE : TB_BLUE);
41 }
42 }
43
44 void tab_display_update(struct request *req, struct rect rect) {
45 int error = parse_page(NULL, req, rect.w - rect.x);
46 if (error) {
47 req->error = error;
48 return;
49 }
50 request_scroll(req, 0, rect); /* fix scroll */
51 return;
52 }
53
54 void tab_display_gemtext(struct request *req, struct rect rect) {
55
56 if (!req) return;
57
58 if (req->length > config.maximumDisplayLength) {
59 tb_printf(rect.x + 2, rect.y + 1, TB_RED, TB_DEFAULT,
60 "The response is too large to be displayed : "
61 "%d bytes", req->length);
62 return;
63 }
64
65 #ifdef ENABLE_IMAGE
66 if (image_process && config.enableImage &&
67 req->page.mime == MIME_IMAGE) {
68 if (!req->page.img && !req->page.img_tried) {
69 int offset = req->page.offset;
70 req->page.img = image_parse(
71 &req->data[offset], req->length - offset,
72 &req->page.img_w, &req->page.img_h);
73 req->page.img_tried = 1;
74 }
75 if (req->page.img) {
76 image_display(req->page.img,
77 req->page.img_w, req->page.img_h, rect.y);
78 } else {
79 tb_printf(2, rect.y + 1, TB_RED, TB_DEFAULT,
80 "Failed to load the image");
81 }
82 return;
83 }
84 #endif
85 if (!config.enableHexViewer && req->page.mime != MIME_GEMTEXT &&
86 req->page.mime != MIME_GEMTEXT) {
87 tb_printf(2, rect.y + 1, TB_RED, TB_DEFAULT,
88 "Unable to display binary data.");
89 return;
90 }
91 if (req->page.width != rect.w - rect.x) {
92 /* TODO: should be done in the background */
93 tab_display_update(req, rect);
94 }
95 page_display(req->page, req->scroll, rect, req->selected);
96 }
97
98 void tab_display_error(struct tab *tab) {
99 if (!tab) return;
100 tab->request->state = STATE_ENDED;
101 tb_refresh();
102 tab_clean_requests(tab);
103 }
104
105 void tab_display_request(struct request *req, struct rect rect) {
106 if (!req) return;
107 switch (req->status) {
108 case GMI_SUCCESS:
109 tab_display_gemtext(req, rect);
110 break;
111 case GMI_INPUT:
112 case GMI_SECRET:
113 break;
114 default:
115 break;
116 }
117 }
118
119 void tab_display(struct tab *tab, struct client *client) {
120
121 struct rect rect;
122 struct request *req;
123
124 if (!tab || !tab->request) return;
125
126 rect = client_display_rect(client);
127
128 req = tab_completed(tab);
129 if (req) tab_display_request(req, rect);
130
131 if (client->mode != MODE_CMDLINE && tab->failure) {
132 tab->failure = 0;
133 client->error = 1;
134 snprintf(V(client->cmd), "%s", tab->error);
135 }
136
137 switch (tab->request->state) {
138 case STATE_COMPLETED:
139 tab_display_request(tab->view ?
140 tab->view : tab->request, rect);
141 break;
142 case STATE_FAILED:
143 tab_display_error(tab);
144 break;
145 case STATE_ONGOING:
146 tab_display_loading(tab, rect);
147 break;
148 }
149
150 }
151