💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › 06b4ffa2e60613db1e4c7b871e437… captured on 2024-02-05 at 09:55:44. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

Go Back

0 /*

1 * ISC License

2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>

3 */

4 #include <stdio.h>

5 #include <stddef.h>

6 #include <stdint.h>

7 #include <string.h>

8 #include <time.h>

9 #include "termbox.h"

10 #include "macro.h"

11 #include "strlcpy.h"

12 #include "page.h"

13 #include "request.h"

14 #include "client.h"

15 #include "tab.h"

16 #include "utf8.h"

17 #include "url.h"

18 #include "known_hosts.h"

19

20 #define MULTIPLE_TABS(X) (X->tab->next || X->tab->prev)

21

22 struct rect client_display_rect(struct client *client) {

23 struct rect rect = {0};

24 rect.w = client->width - 2;

25 rect.y = MULTIPLE_TABS(client);

26 rect.h = client->height - 1 - rect.y;

27 return rect;

28 }

29

30 void client_display(struct client* client) {

31 if (!client) return;

32 tb_clear();

33 tab_display(client->tab, client);

34 client_draw(client);

35 tb_present();

36 }

37

38 #define TAB_WIDTH 32

39 #define TB_REV (TB_REVERSE | TB_DEFAULT), TB_DEFAULT

40

41 void client_draw_scrollbar(struct client* client, struct request *request) {

42 int y, h, i;

43 struct rect rect;

44 if (!client || !request) return;

45 rect = client_display_rect(client);

46 rect.h -= 2;

47 if ((signed)request->page.length - rect.h <= 0) return;

48 y = rect.h * request->scroll / (request->page.length - rect.h);

49 h = (rect.h - 1) / (request->page.length - rect.h);

50 h = h ? h : 1;

51 if (y + h > rect.h) y = rect.h - h + 1;

52 for (i = 0; i <= rect.h; i++) {

53 tb_set_cell(client->width - 1, rect.y + i, ' ', TB_DEFAULT,

54 (i >= y && i < y + h) ? TB_WHITE : TB_BLACK);

55 }

56 }

57

58 void client_draw(struct client* client) {

59

60 int i;

61 struct request *req, *req_input;

62

63 if (!client) return;

64

65 req = tab_completed(client->tab);

66 /* reset counter and error when a new page is loaded */

67 if (req != client->last_request) {

68 client->count = 0;

69 client->error = 0;

70 }

71 client->last_request = req;

72

73 client->width = tb_width();

74 client->height = tb_height();

75

76 if (MULTIPLE_TABS(client)) {

77 struct tab *tab, *start;

78 int x, width;

79 int count, current;

80 for (i = 0; i < client->width; i++) {

81 tb_set_cell(i, 0, ' ', TB_REV);

82 }

83 for (tab = client->tab; tab->prev; tab = tab->prev) ;

84 current = count = 0;

85 for (start = tab; start; start = start->next) {

86 if (client->tab == start) current = count;

87 count++;

88 }

89 x = 0;

90 width = (client->width - count * 2) / count;

91 if (width > TAB_WIDTH) width = TAB_WIDTH;

92 if (width < 1) width = 1;

93 for (; tab; tab = tab->next) {

94 char buf[TAB_WIDTH] = {0};

95 int fg = TB_REVERSE | TB_DEFAULT, bg = TB_DEFAULT;

96 size_t length;

97 struct request *req = tab_completed(tab);

98 if (width == 1) {

99 current--;

100 if (client->width < current * 4) continue;

101 }

102 utf8_cpy(buf, req ? req->page.title : "about:blank",

103 width);

104 length = utf8_width(V(buf));

105 if (tab == client->tab) {

106 fg = TB_DEFAULT;

107 bg = TB_DEFAULT;

108 for (i = x; i < x + width + 2; i++)

109 tb_set_cell(i, 0, ' ', fg, bg);

110 }

111 tb_set_cell(x, 0, '[', fg, bg);

112 tb_set_cell(x + width + 1, 0, ']', fg, bg);

113 tb_printf(x + (width + 2 - length) / 2, 0,

114 fg, bg, "%s", buf);

115 x += width + 2;

116 }

117 }

118

119 for (i = 0; i < client->width; i++)

120 tb_set_cell(i, client->height - 2, ' ', TB_REV);

121

122 if (client->error) {

123 int color = client->error == ERROR_INFO ? TB_GREEN : TB_RED;

124 tb_print(0, client->height - 1, TB_WHITE, color, client->cmd);

125 }

126

127 if (client->mode == MODE_CMDLINE) {

128 tb_print(0, client->height - 1, TB_DEFAULT, TB_DEFAULT,

129 client->cmd);

130 tb_set_cursor(utf8_width(client->cmd, sizeof(client->cmd)),

131 client->height - 1);

132 }

133

134 if (client->count) {

135 tb_printf(client->width - 10, client->height - 1,

136 TB_DEFAULT, TB_DEFAULT, "%d", client->count);

137 }

138

139 req_input = tab_input(client->tab);

140 if (req_input) {

141 tb_printf(0, client->height - 2, TB_REV, "%s", req_input->url);

142 } else {

143 int expired = 0, fg = TB_REVERSE | TB_DEFAULT, bg = TB_DEFAULT;

144 char url[1024];

145 if (req && known_hosts_expired(req->name) > 0) {

146 int i;

147 expired = 1;

148 fg = TB_WHITE;

149 bg = TB_RED;

150 for (i = 0; i < client->width; i++) {

151 tb_set_cell(

152 i, client->height - 2, ' ', fg, bg);

153 }

154 }

155 if (req) url_hide_query(req->url, V(url));

156 else STRLCPY(url, "about:blank");

157 tb_printf(0, client->height - 2, fg, bg, "%s%s (%s)",

158 expired ? "[Certificate expired] " : "",

159 url, req ? req->meta : "");

160 }

161

162 if (req && req->selected &&

163 (size_t)req->selected <= req->page.links_count) {

164 const char *link = req->page.links[req->selected - 1];

165 const char format[] = " => %s ";

166 int len = utf8_width(link, MAX_URL) + sizeof(format) - 3;

167 int x = client->width - len;

168 if (x < 10) x = 10;

169 tb_printf(x, client->height - 2, TB_WHITE, TB_BLUE,

170 format, link);

171 }

172 client_draw_scrollbar(client, req);

173 }

174