commit 1fce2e758fce1ba5d600301bb2b5fae29578adbc from: Omar Polo date: Sat Aug 14 20:52:22 2021 UTC move more stuff outta telescope.c commit - 14071a5adaa0065fdf58a2662f4a905113bbf7bd commit + 1fce2e758fce1ba5d600301bb2b5fae29578adbc blob - f9700485e6e51e0685df1b85448c1dacebc0f557 blob + b87d975b158b12520b075074fe6260776d2db0d8 --- Makefile.am +++ Makefile.am @@ -31,6 +31,8 @@ telescope_SOURCES = cmd.c \ parser_textpatch.c \ parser_textplain.c \ sandbox.c \ + session.c \ + session.h \ telescope.c \ telescope.h \ tofu.c \ blob - a9e7f413497fdf626deef837e1d7742ff240d69f blob + 0c1616c92912ba90abe1c57a6cc4b027ddc46e44 --- cmd.c +++ cmd.c @@ -23,6 +23,7 @@ #include "compl.h" #include "defaults.h" #include "minibuffer.h" +#include "session.h" #include "telescope.h" #include "ui.h" #include "utf8.h" blob - e9d7d6511c8937cf42d4049494201e702d9e2c62 blob + ec8779a1d316069a5d20451ba8150655023d4aff --- minibuffer.c +++ minibuffer.c @@ -21,6 +21,7 @@ #include #include "minibuffer.h" +#include "session.h" #include "ui.h" #include "utf8.h" blob - 5e81c69e04676a27822b4ad6e9d48670eb4646e8 blob + acfc0ecc4abaf7a75f65981ed7a488ac8f50c617 --- parser.c +++ parser.c @@ -16,10 +16,28 @@ #include "parser.h" #include "telescope.h" +#include "ui.h" #include #include +/* + * Load a text/gemini page given the string page. Always returns 0. + */ +int +load_page_from_str(struct tab *tab, const char *page) +{ + erase_buffer(&tab->buffer); + parser_init(tab, gemtext_initparser); + if (!tab->buffer.page.parse(&tab->buffer.page, page, strlen(page))) + abort(); + if (!tab->buffer.page.free(&tab->buffer.page)) + abort(); + ui_on_tab_refresh(tab); + ui_on_tab_loaded(tab); + return 0; +} + void parser_init(struct tab *tab, parserfn fn) { blob - d1ef5e24490de37385e3d9fdc808aa2a598d8925 blob + 63be7ce5d280b6dd51d837b3fc21ca0132203642 --- parser.h +++ parser.h @@ -22,6 +22,8 @@ typedef void (*parserfn)(struct parser *); /* parser.c */ +int load_page_from_str(struct tab *, const char *); + void parser_init(struct tab *, parserfn); int parser_parse(struct tab *, const char *, size_t); int parser_free(struct tab *); blob - /dev/null blob + 08d58942f01ce15982085bfa616d7f140af5a211 (mode 644) --- /dev/null +++ session.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2021 Omar Polo + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "compat.h" + +#include +#include +#include +#include +#include + +#include "defaults.h" +#include "minibuffer.h" +#include "parser.h" +#include "session.h" +#include "ui.h" + +static struct event autosaveev; + +void +switch_to_tab(struct tab *tab) +{ + current_tab = tab; + tab->flags &= ~TAB_URGENT; + + if (operating && tab->flags & TAB_LAZY) + load_url_in_tab(tab, tab->hist_cur->h, NULL, 0); +} + +unsigned int +tab_new_id(void) +{ + static uint32_t tab_counter; + + return tab_counter++; +} + +struct tab * +new_tab(const char *url, const char *base, struct tab *after) +{ + struct tab *tab; + + autosave_hook(); + + if ((tab = calloc(1, sizeof(*tab))) == NULL) { + event_loopbreak(); + return NULL; + } + tab->fd = -1; + + TAILQ_INIT(&tab->hist.head); + + TAILQ_INIT(&tab->buffer.head); + TAILQ_INIT(&tab->buffer.page.head); + + tab->id = tab_new_id(); + if (!operating) + tab->flags |= TAB_LAZY; + switch_to_tab(tab); + + if (after != NULL) + TAILQ_INSERT_AFTER(&tabshead, after, tab, tabs); + else + TAILQ_INSERT_TAIL(&tabshead, tab, tabs); + + load_url_in_tab(tab, url, base, 0); + return tab; +} + +/* + * Free every resource linked to the tab, including the tab itself. + * Removes the tab from the tablist, but doesn't update the + * current_tab though. + */ +void +free_tab(struct tab *tab) +{ + stop_tab(tab); + + autosave_hook(); + + if (evtimer_pending(&tab->loadingev, NULL)) + evtimer_del(&tab->loadingev); + + TAILQ_REMOVE(&tabshead, tab, tabs); + free(tab); +} + +void +stop_tab(struct tab *tab) +{ + ui_send_net(IMSG_STOP, tab->id, NULL, 0); + + if (tab->fd != -1) { + close(tab->fd); + tab->fd = -1; + free(tab->path); + tab->path = NULL; + load_page_from_str(tab, "Stopped.\n"); + } +} + + +void +save_session(void) +{ + struct tab *tab; + char *t; + int flags; + + ui_send_fs(IMSG_SESSION_START, 0, NULL, 0); + + TAILQ_FOREACH(tab, &tabshead, tabs) { + flags = tab->flags; + if (tab == current_tab) + flags |= TAB_CURRENT; + + t = tab->hist_cur->h; + ui_send_fs(IMSG_SESSION_TAB, flags, t, strlen(t)+1); + + t = tab->buffer.page.title; + ui_send_fs(IMSG_SESSION_TAB_TITLE, 0, t, strlen(t)+1); + } + + ui_send_fs(IMSG_SESSION_END, 0, NULL, 0); +} + +/* + * Parse a line of the session file. The format is: + * + * URL [flags,...] [title]\n + */ +static void +parse_session_line(char *line, const char **title, uint32_t *flags) +{ + char *s, *t, *ap; + + *title = ""; + *flags = 0; + if ((s = strchr(line, ' ')) == NULL) + return; + + *s++ = '\0'; + + if ((t = strchr(s, ' ')) != NULL) { + *t++ = '\0'; + *title = t; + } + + while ((ap = strsep(&s, ",")) != NULL) { + if (*ap == '\0') + ; + else if (!strcmp(ap, "current")) + *flags |= TAB_CURRENT; + else + message("unknown tab flag: %s", ap); + } +} + +void +load_last_session(void) +{ + const char *title; + char *nl, *line = NULL; + uint32_t flags; + size_t linesize = 0; + ssize_t linelen; + FILE *session; + struct tab *tab, *curr = NULL; + + if ((session = fopen(session_file, "r")) == NULL) { + /* first time? */ + new_tab("about:new", NULL, NULL); + switch_to_tab(new_tab("about:help", NULL, NULL)); + return; + } + + while ((linelen = getline(&line, &linesize, session)) != -1) { + if ((nl = strchr(line, '\n')) != NULL) + *nl = '\0'; + parse_session_line(line, &title, &flags); + if ((tab = new_tab(line, NULL, NULL)) == NULL) + err(1, "new_tab"); + strlcpy(tab->buffer.page.title, title, + sizeof(tab->buffer.page.title)); + if (flags & TAB_CURRENT) + curr = tab; + } + + if (ferror(session)) + message("error reading %s: %s", + session_file, strerror(errno)); + fclose(session); + free(line); + + if (curr != NULL) + switch_to_tab(curr); + + if (last_time_crashed()) + switch_to_tab(new_tab("about:crash", NULL, NULL)); + + return; +} + +void +autosave_init(void) +{ + evtimer_set(&autosaveev, autosave_timer, NULL); +} + +void +autosave_timer(int fd, short event, void *data) +{ + save_session(); +} + +/* + * Function to be called in "interesting" places where we may want to + * schedule an autosave (like on new tab or before loading an url.) + */ +void +autosave_hook(void) +{ + struct timeval tv; + + if (autosave <= 0) + return; + + if (!evtimer_pending(&autosaveev, NULL)) { + tv.tv_sec = autosave; + tv.tv_usec = 0; + + evtimer_add(&autosaveev, &tv); + } +} blob - a3369803052b9b1054d382f1d6e4c8c5f05f72bc blob + 70f1484960a8f53f3329a21fa25dbdf04545b672 --- telescope.c +++ telescope.c @@ -30,6 +30,7 @@ #include "defaults.h" #include "minibuffer.h" #include "parser.h" +#include "session.h" #include "telescope.h" #include "ui.h" @@ -45,12 +46,10 @@ static const char *opts = "Cc:hnT:v"; /* * Used to know when we're finished loading. */ -static int operating; +int operating; static struct imsgev *iev_fs, *iev_net; -static struct event autosaveev; - struct tabshead tabshead = TAILQ_HEAD_INITIALIZER(tabshead); struct proxylist proxies = TAILQ_HEAD_INITIALIZER(proxies); @@ -108,7 +107,6 @@ static void handle_imsg_bookmark_ok(struct imsg*, si static void handle_imsg_save_cert_ok(struct imsg*, size_t); static void handle_imsg_update_cert_ok(struct imsg *, size_t); static void handle_dispatch_imsg(int, short, void*); -static int load_page_from_str(struct tab*, const char*); static int load_about_url(struct tab*, const char*); static int load_file_url(struct tab *, const char *); static int load_finger_url(struct tab *, const char *); @@ -120,12 +118,7 @@ static int make_request(struct tab *, struct get_req const char *); static int make_fs_request(struct tab *, int, const char *); static int do_load_url(struct tab*, const char *, const char *); -static void autosave_timer(int, short, void *); -static void parse_session_line(char *, const char **, uint32_t *); -static void load_last_session(void); static pid_t start_child(enum telescope_process, const char *, int); -static int ui_send_net(int, uint32_t, const void *, uint16_t); -static int ui_send_fs(int, uint32_t, const void *, uint16_t); static struct proto { const char *schema; @@ -569,20 +562,6 @@ handle_dispatch_imsg(int fd, short ev, void *d) if (dispatch_imsg(iev, ev, handlers, sizeof(handlers)) == -1) err(1, "connection closed"); -} - -static int -load_page_from_str(struct tab *tab, const char *page) -{ - erase_buffer(&tab->buffer); - parser_init(tab, gemtext_initparser); - if (!tab->buffer.page.parse(&tab->buffer.page, page, strlen(page))) - die(); - if (!tab->buffer.page.free(&tab->buffer.page)) - die(); - ui_on_tab_refresh(tab); - ui_on_tab_loaded(tab); - return 0; } static int @@ -939,225 +918,15 @@ load_next_page(struct tab *tab) tab->hist_cur = h; do_load_url(tab, h->h, NULL); return 1; -} - -void -switch_to_tab(struct tab *tab) -{ - current_tab = tab; - tab->flags &= ~TAB_URGENT; - - if (operating && tab->flags & TAB_LAZY) - load_url_in_tab(tab, tab->hist_cur->h, NULL, 0); -} - -unsigned int -tab_new_id(void) -{ - static uint32_t tab_counter; - - return tab_counter++; -} - -struct tab * -new_tab(const char *url, const char *base, struct tab *after) -{ - struct tab *tab; - - autosave_hook(); - - if ((tab = calloc(1, sizeof(*tab))) == NULL) { - event_loopbreak(); - return NULL; - } - tab->fd = -1; - - TAILQ_INIT(&tab->hist.head); - - TAILQ_INIT(&tab->buffer.head); - TAILQ_INIT(&tab->buffer.page.head); - - tab->id = tab_new_id(); - if (!operating) - tab->flags |= TAB_LAZY; - switch_to_tab(tab); - - if (after != NULL) - TAILQ_INSERT_AFTER(&tabshead, after, tab, tabs); - else - TAILQ_INSERT_TAIL(&tabshead, tab, tabs); - - load_url_in_tab(tab, url, base, 0); - return tab; } -/* - * Free every resource linked to the tab, including the tab itself. - * Removes the tab from the tablist, but doesn't update the - * current_tab though. - */ void -free_tab(struct tab *tab) -{ - stop_tab(tab); - - autosave_hook(); - - if (evtimer_pending(&tab->loadingev, NULL)) - evtimer_del(&tab->loadingev); - - TAILQ_REMOVE(&tabshead, tab, tabs); - free(tab); -} - -void -stop_tab(struct tab *tab) -{ - ui_send_net(IMSG_STOP, tab->id, NULL, 0); - - if (tab->fd != -1) { - close(tab->fd); - tab->fd = -1; - free(tab->path); - tab->path = NULL; - load_page_from_str(tab, "Stopped.\n"); - } -} - -void add_to_bookmarks(const char *str) { ui_send_fs(IMSG_BOOKMARK_PAGE, 0, str, strlen(str)+1); } -void -save_session(void) -{ - struct tab *tab; - char *t; - int flags; - - ui_send_fs(IMSG_SESSION_START, 0, NULL, 0); - - TAILQ_FOREACH(tab, &tabshead, tabs) { - flags = tab->flags; - if (tab == current_tab) - flags |= TAB_CURRENT; - - t = tab->hist_cur->h; - ui_send_fs(IMSG_SESSION_TAB, flags, t, strlen(t)+1); - - t = tab->buffer.page.title; - ui_send_fs(IMSG_SESSION_TAB_TITLE, 0, t, strlen(t)+1); - } - - ui_send_fs(IMSG_SESSION_END, 0, NULL, 0); -} - -static void -autosave_timer(int fd, short event, void *data) -{ - save_session(); -} - -/* - * Function to be called in "interesting" places where we may want to - * schedule an autosave (like on new tab or before loading an url.) - */ -void -autosave_hook(void) -{ - struct timeval tv; - - if (autosave <= 0) - return; - - if (!evtimer_pending(&autosaveev, NULL)) { - tv.tv_sec = autosave; - tv.tv_usec = 0; - - evtimer_add(&autosaveev, &tv); - } -} - -/* - * Parse a line of the session file. The format is: - * - * URL [flags,...] [title]\n - */ -static void -parse_session_line(char *line, const char **title, uint32_t *flags) -{ - char *s, *t, *ap; - - *title = ""; - *flags = 0; - if ((s = strchr(line, ' ')) == NULL) - return; - - *s++ = '\0'; - - if ((t = strchr(s, ' ')) != NULL) { - *t++ = '\0'; - *title = t; - } - - while ((ap = strsep(&s, ",")) != NULL) { - if (*ap == '\0') - ; - else if (!strcmp(ap, "current")) - *flags |= TAB_CURRENT; - else - message("unknown tab flag: %s", ap); - } -} - -static void -load_last_session(void) -{ - const char *title; - char *nl, *line = NULL; - uint32_t flags; - size_t linesize = 0; - ssize_t linelen; - FILE *session; - struct tab *tab, *curr = NULL; - - if ((session = fopen(session_file, "r")) == NULL) { - /* first time? */ - new_tab("about:new", NULL, NULL); - switch_to_tab(new_tab("about:help", NULL, NULL)); - return; - } - - while ((linelen = getline(&line, &linesize, session)) != -1) { - if ((nl = strchr(line, '\n')) != NULL) - *nl = '\0'; - parse_session_line(line, &title, &flags); - if ((tab = new_tab(line, NULL, NULL)) == NULL) - err(1, "new_tab"); - strlcpy(tab->buffer.page.title, title, - sizeof(tab->buffer.page.title)); - if (flags & TAB_CURRENT) - curr = tab; - } - - if (ferror(session)) - message("error reading %s: %s", - session_file, strerror(errno)); - fclose(session); - free(line); - - if (curr != NULL) - switch_to_tab(curr); - - if (last_time_crashed()) - switch_to_tab(new_tab("about:crash", NULL, NULL)); - - return; -} - static pid_t start_child(enum telescope_process p, const char *argv0, int fd) { @@ -1195,7 +964,7 @@ start_child(enum telescope_process p, const char *argv err(1, "execvp(%s)", argv0); } -static int +int ui_send_net(int type, uint32_t peerid, const void *data, uint16_t datalen) { @@ -1203,7 +972,7 @@ ui_send_net(int type, uint32_t peerid, const void *dat datalen); } -static int +int ui_send_fs(int type, uint32_t peerid, const void *data, uint16_t datalen) { return imsg_compose_event(iev_fs, type, peerid, 0, -1, data, @@ -1338,7 +1107,7 @@ main(int argc, char * const *argv) event_init(); /* Setup event handler for the autosave */ - evtimer_set(&autosaveev, autosave_timer, NULL); + autosave_init(); /* Setup event handlers for pipes to fs/net */ iev_fs->events = EV_READ; blob - /dev/null blob + 6a43fea1188a6278ccb9176a6d5229214b5aef23 (mode 644) --- /dev/null +++ session.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Omar Polo + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef SESSION_H +#define SESSION_H + +#include "telescope.h" + +void switch_to_tab(struct tab *); +unsigned int tab_new_id(void); +struct tab *new_tab(const char *, const char *base, struct tab *); +void free_tab(struct tab *); +void stop_tab(struct tab*); + +void save_session(void); +void load_last_session(void); + +void autosave_init(void); +void autosave_timer(int, short, void *); +void autosave_hook(void); + +#endif blob - 0d27078306404e67cb153ed72bd19478b4d061c0 blob + a11df120af6df0245b79aa4a40723dd9a031bbaa --- telescope.h +++ telescope.h @@ -320,19 +320,16 @@ void sandbox_ui_process(void); void sandbox_fs_process(void); /* telescope.c */ +extern int operating; + void gopher_send_search_req(struct tab *, const char *); void load_url(struct tab *, const char *, const char *, int); void load_url_in_tab(struct tab *, const char *, const char *, int); int load_previous_page(struct tab*); int load_next_page(struct tab*); -void switch_to_tab(struct tab *); -unsigned int tab_new_id(void); -struct tab *new_tab(const char *, const char *base, struct tab *); -void free_tab(struct tab *); -void stop_tab(struct tab*); void add_to_bookmarks(const char*); -void save_session(void); -void autosave_hook(void); +int ui_send_net(int, uint32_t, const void *, uint16_t); +int ui_send_fs(int, uint32_t, const void *, uint16_t); /* tofu.c */ void tofu_init(struct ohash*, unsigned int, ptrdiff_t); blob - 74418030e8c0876058277924bc327014757d0d5d blob + bed65fdfaaa525e0fc3697c0fed86952b81a3de3 --- ui.c +++ ui.c @@ -43,6 +43,7 @@ #include "defaults.h" #include "minibuffer.h" +#include "session.h" #include "telescope.h" #include "ui.h" #include "utf8.h"