💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › c3cf7a181df35cd21349b63dca3c3… captured on 2023-12-28 at 15:43:27. 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 <string.h>
6 #include <stdint.h>
7 #include "macro.h"
8 #include "strlcpy.h"
9 #include "utf8.h"
10 #include "termbox.h"
11 #include "page.h"
12 #include "request.h"
13 #include "client.h"
14 #include "tab.h"
15 #include "input.h"
16 #include "error.h"
17
18 void client_reset(struct client *client) {
19 if (!client) return;
20 client->g = client->count = 0;
21 }
22
23 int client_input_normal(struct client *client, struct tb_event ev) {
24 switch (ev.key) {
25 case TB_KEY_ESC:
26 client->count = 0;
27 break;
28 case TB_KEY_ARROW_DOWN:
29 goto down;
30 case TB_KEY_ARROW_UP:
31 goto up;
32 case TB_KEY_PGUP:
33 client->count = AZ(client->count);
34 tab_scroll(client->tab, -client->count * client->height,
35 client_display_rect(client));
36 client_reset(client);
37 break;
38 case TB_KEY_PGDN:
39 client->count = AZ(client->count);
40 tab_scroll(client->tab, client->count * client->height,
41 client_display_rect(client));
42 client_reset(client);
43 break;
44 case TB_KEY_BACK_TAB:
45 case TB_KEY_TAB:
46 {
47 char url[MAX_URL];
48 struct request *req;
49 size_t i;
50 int ret;
51
52 req = tab_completed(client->tab);
53 i = client->count;
54 client->count = 0;
55 if (!req) break;
56 if (!i && !req->selected) break;
57 if (i) {
58 if (req->page.links_count < i) {
59 /* error */
60 client->error = 1;
61 STRLCPY(client->cmd,
62 "Invalid link number");
63 break;
64 }
65 req->selected = i;
66 break;
67 }
68 i = req->selected;
69 req->selected = 0;
70 if (req->page.links_count < i) break;
71 ret = request_follow(req,
72 req->page.links[i - 1], V(url));
73 if (ret) {
74 client->error = 1;
75 error_string(ret, V(client->cmd));
76 break;
77 }
78 if (ev.key == TB_KEY_BACK_TAB) {
79 client_newtab(client, url);
80 break;
81 }
82 ret = tab_request(client->tab, url);
83 if (ret) {
84 client->error = 1;
85 error_string(ret, V(client->cmd));
86 break;
87 }
88 break;
89 }
90 }
91 if (ev.ch >= '0' && ev.ch <= '9') {
92 client->count = client->count * 10 + ev.ch - '0';
93 if (client->count > MAX_COUNT) client->count = MAX_COUNT;
94 return 0;
95 }
96 switch (ev.ch) {
97 case ':':
98 client_enter_mode_cmdline(client);
99 break;
100 case '/':
101 {
102 struct request *req = tab_completed(client->tab);
103 if (!req) break;
104 client_enter_mode_cmdline(client);
105 client->cmd[0] = '/';
106 client->search[0] = '\0';
107 req->page.selected = 1;
108 }
109 break;
110 case 'n':
111 case 'N':
112 {
113 struct request *req = tab_completed(client->tab);
114 if (!req) break;
115 if (ev.ch == 'n') {
116 if (req->page.selected < req->page.occurrences)
117 req->page.selected++;
118 } else {
119 if (req->page.selected > 1)
120 req->page.selected--;
121 }
122 req->scroll = page_selection_line(req->page);
123 req->scroll -= client_display_rect(client).h / 2;
124 }
125 tab_scroll(client->tab, 0, client_display_rect(client));
126 break;
127 case 'u':
128 {
129 struct request *req = tab_completed(client->tab);
130 client_enter_mode_cmdline(client);
131 client->cursor = snprintf(V(client->cmd),
132 ":o %s", req ? req->url : "");
133 }
134 break;
135 case 'j':
136 down:
137 client->count = AZ(client->count);
138 tab_scroll(client->tab, client->count,
139 client_display_rect(client));
140 client_reset(client);
141 break;
142 case 'k':
143 up:
144 client->count = AZ(client->count);
145 tab_scroll(client->tab, -client->count,
146 client_display_rect(client));
147 client_reset(client);
148 break;
149 case 't':
150 if (!client->g) break;
151 if (client->tab->next)
152 client->tab = client->tab->next;
153 else while (client->tab->prev)
154 client->tab = client->tab->prev;
155 client_reset(client);
156 break;
157 case 'T':
158 if (!client->g) break;
159 if (client->tab->prev)
160 client->tab = client->tab->prev;
161 else while (client->tab->next)
162 client->tab = client->tab->next;
163 client_reset(client);
164 break;
165 case 'g':
166 if (!client->g) {
167 client->g = 1;
168 break;
169 }
170 tab_scroll(client->tab, -0x0FFFFFFF,
171 client_display_rect(client));
172 client_reset(client);
173 break;
174 case 'G':
175 client->count = 0;
176 tab_scroll(client->tab, 0x0FFFFFFF,
177 client_display_rect(client));
178 client_reset(client);
179 break;
180 case 'h':
181 if (!client || !client->tab || !client->tab->request) break;
182 {
183 struct request *req = client->tab->view ?
184 client->tab->view->next :
185 client->tab->request->next;
186 while (req && req->state != STATE_COMPLETED) {
187 req = req->next;
188 }
189 if (req) client->tab->view = req;
190 }
191 break;
192 case 'l':
193 if (!client || !client->tab || !client->tab->request) break;
194 if (!client->tab->view) break;
195 {
196 struct request *req, *prev;
197 prev = NULL;
198 req = client->tab->request->next;
199 while (req && req != client->tab->view) {
200 if (req->state == STATE_COMPLETED)
201 prev = req;
202 req = req->next;
203 }
204 client->tab->view = prev;
205 }
206 break;
207 case 'r':
208 {
209 struct request *req = tab_completed(client->tab);
210 if (!req) break;
211 tab_request(client->tab, req->url);
212 }
213 break;
214 case 'b':
215 client_newtab(client, "about:bookmarks");
216 break;
217 case 'f':
218 client_newtab(client, "about:history");
219 break;
220 }
221 return 0;
222 }
223