💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › edd983e38b1c65b43f0809c329129… captured on 2023-04-19 at 23:01:43. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-03-20)

➡️ Next capture (2023-09-08)

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

0 /* See LICENSE file for copyright and license details. */

1 #include <strings.h>

2 #include <termbox.h>

3 #include "gemini.h"

4 #include "display.h"

5 #include "wcwidth.h"

6 #include "url.h"

7

8 void tb_colorline(int x, int y, uintattr_t color) {

9 for (int i=x; i < tb_width(); i++)

10 tb_set_cell(i, y, ' ', color, color);

11 }

12

13 void hide_query(char* url, char* urlbuf) {

14 int hide = 0;

15 int posx = 0;

16 for (int i=0; url[i] && i < 1024; i++) {

17 if (hide && (url[i] == '/')) {

18 hide = 0;

19 }

20 if (!hide) {

21 urlbuf[posx] = url[i];

22 posx++;

23 }

24 if (!hide && url[i] == '?') {

25 hide = 1;

26 urlbuf[posx] = '<';

27 urlbuf[posx + 1] = '*';

28 urlbuf[posx + 2] = '>';

29 posx+=3;

30 }

31 }

32 urlbuf[posx] = '\0';

33 }

34

35 void display() {

36 int bg = GREY;

37 struct gmi_tab* tab = client.tab;

38 struct gmi_page* page = &tab->page;

39 if (tab->request.ask == 2) {

40 tab->request.ask = display_ask(tab->request.info,

41 tab->request.action);

42 }

43 tb_clear();

44

45 int input_offset = 0;

46 if (client.input.mode) {

47 int cpos = utf8_width_to(client.input.field,

48 sizeof(client.input.field),

49 client.input.cursor);

50 int w = tb_width();

51 w -= w&1; // make width even so double-width

52 // characters don't cause problem

53 if (page->code == 10 || page->code == 11)

54 w -= utf8_width(client.input.label,

55 sizeof(client.input.label)) + 2;

56 if (cpos >= w) {

57 input_offset = utf8_len_to(client.input.field,

58 sizeof(client.input.field),

59 cpos - cpos%w);

60 cpos = cpos%w;

61 }

62

63 if (page->code == 11 || page->code == 10)

64 tb_set_cursor(cpos + utf8_width(client.input.label,

65 sizeof(client.input.label))+2,

66 tb_height()-1);

67 else

68 tb_set_cursor(cpos, tb_height()-1);

69 }

70

71 if (page->code == 20 || page->code == 10 || page->code == 11) {

72 tb_clear();

73 if (client.tabs_count > 1) tab->scroll--;

74 page->lines = gmi_render(tab);

75 if (client.tabs_count > 1) tab->scroll++;

76 } else if (tab->error[0] != '\0') {

77 tb_printf(2, 1+(client.tabs_count>1), RED, TB_DEFAULT,

78 "# %s", tab->error);

79 }

80

81 // current tab

82 if (client.tabs_count > 1) {

83 tb_colorline(0, 0, bg);

84 gmi_gettitle(page, tab->url);

85 int index = 1;

86 struct gmi_tab* ptr = tab;

87 while (ptr->prev) {

88 index++;

89 ptr = ptr->prev;

90 }

91 tb_printf(0, 0, BLACK, bg,

92 " %s [%d/%d]", page->title,

93 index, client.tabs_count);

94 }

95

96 // current url

97 tb_colorline(0, tb_height()-2, bg);

98 char urlbuf[MAX_URL];

99 hide_query(tab->url, urlbuf);

100 tb_printf(0, tb_height()-2, BLACK, bg, "%s (%s)",

101 urlbuf, tab->page.meta);

102

103 // Show selected link url

104 if (tab->selected != 0) {

105 int x = tb_width() -

106 utf8_width(tab->selected_url, MAX_URL) - 5;

107 x = x < 10?10:x;

108 tb_printf(x, tb_height()-2, bg, BLUE,

109 " => %s ", tab->selected_url);

110 } else if (tab->request.state != STATE_DONE) {

111 hide_query(tab->request.url, urlbuf);

112 int llen = strnlen(tab->request.url, sizeof(tab->request.url));

113 tb_printf(tb_width()-llen-5, tb_height()-2, BLACK, bg,

114 " [%s] ", urlbuf);

115 }

116

117 int count = atoi(client.vim.counter);

118 if (count) {

119 tb_printf(tb_width() - 8, tb_height() - 1,

120 TB_DEFAULT, TB_DEFAULT, "%d", count);

121 }

122

123 // input

124 if (tab->show_error) {

125 tb_hide_cursor();

126 tb_colorline(0, tb_height()-1, RED);

127 tb_print(0, tb_height()-1, WHITE, RED, tab->error);

128 client.input.field[0] = '\0';

129 } else if (tab->show_info) {

130 tb_hide_cursor();

131 tb_colorline(0, tb_height()-1, GREEN);

132 tb_print(0, tb_height()-1, WHITE, GREEN, tab->info);

133 client.input.field[0] = '\0';

134 tab->show_info = 0;

135 } else if (page->code == 10) {

136 tb_printf(0, tb_height()-1, TB_DEFAULT, TB_DEFAULT,

137 "%s: %s", client.input.label,

138 client.input.field + input_offset);

139 } else if (page->code == 11) {

140 char input_buf[1024];

141 size_t i = 0;

142 for (; client.input.field[i] &&

143 i < sizeof(client.input.field); i++)

144 input_buf[i] = '*';

145 input_buf[i] = '\0';

146 tb_printf(0, tb_height()-1, TB_DEFAULT, TB_DEFAULT,

147 "%s: %s", client.input.label, input_buf);

148 } else {

149 tb_printf(0, tb_height()-1, TB_DEFAULT, TB_DEFAULT, "%s",

150 client.input.field + input_offset);

151 }

152

153 if (client.input.mode && tb_width() & 1)

154 tb_set_cell(tb_width() - 1, tb_height() -1, ' ',

155 TB_DEFAULT, TB_DEFAULT);

156 tb_present();

157 }

158

159 void display_history() {

160 char urlbuf[1024];

161 int ret = 0;

162 struct tb_event ev;

163 bzero(&ev, sizeof(ev));

164 do {

165 struct gmi_tab* tab = client.tab;

166

167 tb_clear();

168 tb_print(2, 1, RED, TB_DEFAULT, "# History");

169

170 if (!tab->history) {

171 tb_present();

172 continue;

173 }

174 int y = 3;

175 for (struct gmi_link* link = tab->history->next; link;

176 link = link->next) {

177 hide_query(link->url, urlbuf);

178 tb_printf(4, y, TB_DEFAULT, TB_DEFAULT, "%s", urlbuf);

179 y++;

180 }

181

182 hide_query(tab->history->url, urlbuf);

183 tb_printf(4, y, TB_DEFAULT, BLUE, "-> %s", urlbuf);

184 y++;

185

186 for (struct gmi_link* link = tab->history->prev; link;

187 link = link->prev) {

188 hide_query(link->url, urlbuf);

189 tb_printf(4, y, TB_DEFAULT, TB_DEFAULT, "%s", urlbuf);

190 y++;

191 }

192

193 tb_present();

194

195 } while(((ret = tb_poll_event(&ev)) == TB_OK &&

196 ev.type == TB_EVENT_RESIZE)

197 || ret == -14);

198 }

199

200 int display_ask(char* info, char* action) {

201 int ret = 0;

202 struct tb_event ev;

203 bzero(&ev, sizeof(ev));

204 do {

205

206 tb_clear();

207 tb_printf(2, 1, RED, TB_DEFAULT, "%s", info);

208 int w = tb_width();

209 int h = tb_height();

210 const char* line1 = "Press 'y' to %s";

211 const char* line2 = "Press any other key to cancel";

212 int x1 = w/2-(strlen(line1)+strnlen(action, w/2))/2;

213 int x2 = w/2-strlen(line2)/2;

214 tb_printf(x1, h/2-1, TB_DEFAULT, TB_DEFAULT, line1, action);

215 tb_printf(x1+7, h/2-1, GREEN, TB_DEFAULT, "y");

216 tb_printf(x2, h/2, TB_DEFAULT, TB_DEFAULT, line2);

217

218 tb_present();

219

220 } while(((ret = tb_poll_event(&ev)) == TB_OK &&

221 ev.type == TB_EVENT_RESIZE) || ret == -14);

222 return ev.ch == 'y' || ev.ch == 'Y';

223 }

224