2005-09-15 09:58:31 -04:00
|
|
|
/* Sessions status management */
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "elinks.h"
|
|
|
|
|
|
|
|
#include "bfu/dialog.h"
|
|
|
|
#include "cache/cache.h"
|
|
|
|
#include "config/options.h"
|
|
|
|
#include "dialogs/progress.h"
|
|
|
|
#include "dialogs/status.h"
|
|
|
|
#include "document/document.h"
|
|
|
|
#include "document/renderer.h"
|
|
|
|
#include "document/view.h"
|
2021-08-08 15:25:08 -04:00
|
|
|
#include "intl/libintl.h"
|
2005-09-15 09:58:31 -04:00
|
|
|
#include "network/connection.h"
|
|
|
|
#include "network/progress.h"
|
|
|
|
#include "network/state.h"
|
|
|
|
#include "protocol/bittorrent/dialogs.h"
|
|
|
|
#include "protocol/protocol.h"
|
|
|
|
#include "protocol/uri.h"
|
|
|
|
#include "session/download.h"
|
|
|
|
#include "session/session.h"
|
|
|
|
#include "terminal/draw.h"
|
|
|
|
#include "terminal/screen.h"
|
|
|
|
#include "terminal/tab.h"
|
|
|
|
#include "terminal/terminal.h"
|
|
|
|
#include "terminal/window.h"
|
|
|
|
#include "util/color.h"
|
|
|
|
#include "util/conv.h"
|
|
|
|
#include "util/error.h"
|
|
|
|
#include "util/memory.h"
|
|
|
|
#include "util/snprintf.h"
|
|
|
|
#include "util/string.h"
|
|
|
|
#include "viewer/text/form.h"
|
|
|
|
#include "viewer/text/link.h"
|
|
|
|
#include "viewer/text/view.h"
|
|
|
|
|
|
|
|
|
2021-01-02 10:20:27 -05:00
|
|
|
char *
|
2005-09-15 09:58:31 -04:00
|
|
|
get_download_msg(struct download *download, struct terminal *term,
|
2022-02-17 15:14:36 -05:00
|
|
|
int wide, int full, const char *separator)
|
2005-09-15 09:58:31 -04:00
|
|
|
{
|
|
|
|
if (!download_is_progressing(download)) {
|
|
|
|
/* DBG("%d -> %s", download->state, _(get_err_msg(download->state), term)); */
|
|
|
|
return stracpy(get_state_message(download->state, term));
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_BITTORRENT
|
|
|
|
if (download->conn
|
|
|
|
&& download->conn->uri->protocol == PROTOCOL_BITTORRENT)
|
|
|
|
return get_bittorrent_message(download, term, wide, full, separator);
|
|
|
|
#endif
|
2008-06-03 02:57:58 -04:00
|
|
|
if (download->conn && download->conn->http_upload_progress)
|
|
|
|
return get_upload_progress_msg(download->conn->http_upload_progress,
|
2008-05-02 18:13:40 -04:00
|
|
|
term, wide, full, separator);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
return get_progress_msg(download->progress, term, wide, full, separator);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define show_tabs(option, tabs) (((option) > 0) && !((option) == 1 && (tabs) < 2))
|
|
|
|
|
|
|
|
void
|
|
|
|
update_status(void)
|
|
|
|
{
|
2007-08-28 12:41:18 -04:00
|
|
|
int show_title_bar = get_opt_bool("ui.show_title_bar", NULL);
|
|
|
|
int show_status_bar = get_opt_bool("ui.show_status_bar", NULL);
|
|
|
|
int show_tabs_bar = get_opt_int("ui.tabs.show_bar", NULL);
|
|
|
|
int show_tabs_bar_at_top = get_opt_bool("ui.tabs.top", NULL);
|
2005-09-15 09:58:31 -04:00
|
|
|
#ifdef CONFIG_LEDS
|
2007-08-28 12:41:18 -04:00
|
|
|
int show_leds = get_opt_bool("ui.leds.enable", NULL);
|
2005-09-15 09:58:31 -04:00
|
|
|
#endif
|
2007-08-28 12:41:18 -04:00
|
|
|
int set_window_title = get_opt_bool("ui.window_title", NULL);
|
|
|
|
int insert_mode = get_opt_bool("document.browse.forms.insert_mode",
|
|
|
|
NULL);
|
2005-09-15 09:58:31 -04:00
|
|
|
struct session *ses;
|
2006-09-28 17:50:46 -04:00
|
|
|
int tabs_count = 1;
|
2005-09-15 09:58:31 -04:00
|
|
|
struct terminal *term = NULL;
|
|
|
|
|
|
|
|
foreach (ses, sessions) {
|
|
|
|
struct session_status *status = &ses->status;
|
|
|
|
int dirty = 0;
|
|
|
|
|
|
|
|
/* Try to descrease the number of tab calculation using that
|
|
|
|
* tab sessions share the same term. */
|
|
|
|
if (ses->tab->term != term) {
|
|
|
|
term = ses->tab->term;
|
2006-09-28 17:50:46 -04:00
|
|
|
tabs_count = number_of_tabs(term);
|
2005-09-15 09:58:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (status->force_show_title_bar >= 0)
|
|
|
|
show_title_bar = status->force_show_title_bar;
|
|
|
|
if (status->show_title_bar != show_title_bar) {
|
|
|
|
status->show_title_bar = show_title_bar;
|
|
|
|
dirty = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status->force_show_status_bar >= 0)
|
|
|
|
show_status_bar = status->force_show_status_bar;
|
|
|
|
if (status->show_status_bar != show_status_bar) {
|
|
|
|
status->show_status_bar = show_status_bar;
|
|
|
|
dirty = 1;
|
|
|
|
}
|
|
|
|
|
2006-09-28 17:50:46 -04:00
|
|
|
if (show_tabs(show_tabs_bar, tabs_count) != status->show_tabs_bar) {
|
|
|
|
status->show_tabs_bar = show_tabs(show_tabs_bar, tabs_count);
|
2005-09-15 09:58:31 -04:00
|
|
|
dirty = 1;
|
|
|
|
}
|
2006-03-04 04:24:37 -05:00
|
|
|
|
|
|
|
if (status->show_tabs_bar) {
|
|
|
|
if (status->show_tabs_bar_at_top != show_tabs_bar_at_top) {
|
|
|
|
status->show_tabs_bar_at_top = show_tabs_bar_at_top;
|
|
|
|
dirty = 1;
|
|
|
|
}
|
|
|
|
}
|
2005-09-15 09:58:31 -04:00
|
|
|
#ifdef CONFIG_LEDS
|
|
|
|
if (status->show_leds != show_leds) {
|
|
|
|
status->show_leds = show_leds;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
status->set_window_title = set_window_title;
|
|
|
|
|
|
|
|
/* This more belongs to the current browsing state but ... */
|
|
|
|
if (!insert_mode)
|
|
|
|
ses->insert_mode = INSERT_MODE_LESS;
|
|
|
|
else if (ses->insert_mode == INSERT_MODE_LESS)
|
|
|
|
ses->insert_mode = INSERT_MODE_OFF;
|
|
|
|
|
|
|
|
if (!dirty) continue;
|
|
|
|
|
|
|
|
/* Force the current document to be rerendered so the
|
|
|
|
* document view and document height is updated to fit
|
|
|
|
* into the new dimensions. Related to bug 87. */
|
|
|
|
render_document_frames(ses, 1);
|
|
|
|
|
|
|
|
set_screen_dirty(term->screen, 0, term->height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-02 10:20:27 -05:00
|
|
|
static char *
|
2005-09-15 09:58:31 -04:00
|
|
|
get_current_link_info_and_title(struct session *ses,
|
|
|
|
struct document_view *doc_view)
|
|
|
|
{
|
2021-01-02 10:20:27 -05:00
|
|
|
char *link_info, *link_title, *ret = NULL;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
link_info = get_current_link_info(ses, doc_view);
|
|
|
|
if (!link_info) return NULL;
|
|
|
|
|
|
|
|
link_title = get_current_link_title(doc_view);
|
|
|
|
if (link_title) {
|
|
|
|
assert(*link_title);
|
|
|
|
|
2007-03-11 06:59:11 -04:00
|
|
|
ret = straconcat(link_info, " - ", link_title,
|
2021-01-02 10:20:27 -05:00
|
|
|
(char *) NULL);
|
2005-09-15 09:58:31 -04:00
|
|
|
mem_free(link_info);
|
|
|
|
mem_free(link_title);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ret) ret = link_info;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
display_status_bar(struct session *ses, struct terminal *term, int tabs_count)
|
|
|
|
{
|
2021-01-02 10:20:27 -05:00
|
|
|
char *msg = NULL;
|
2005-09-15 09:58:31 -04:00
|
|
|
unsigned int tab_info_len = 0;
|
|
|
|
struct download *download = get_current_download(ses);
|
|
|
|
struct session_status *status = &ses->status;
|
2022-03-18 14:22:38 -04:00
|
|
|
unsigned int text_color_node = 0;
|
2005-09-15 09:58:31 -04:00
|
|
|
int msglen;
|
2018-09-09 13:14:56 -04:00
|
|
|
struct el_box box;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
#ifdef CONFIG_MARKS
|
|
|
|
if (ses->kbdprefix.mark != KP_MARK_NOTHING) {
|
|
|
|
switch (ses->kbdprefix.mark) {
|
|
|
|
case KP_MARK_NOTHING:
|
|
|
|
assert(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KP_MARK_SET:
|
|
|
|
msg = msg_text(term, N_("Enter a mark to set"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KP_MARK_GOTO:
|
|
|
|
msg = msg_text(term, N_("Enter a mark"
|
|
|
|
" to which to jump"));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
if (ses->kbdprefix.repeat_count) {
|
|
|
|
msg = msg_text(term, N_("Keyboard prefix: %d"),
|
|
|
|
ses->kbdprefix.repeat_count);
|
2006-10-24 14:41:25 -04:00
|
|
|
}
|
|
|
|
else if (ses->status.window_status) {
|
|
|
|
msg = stracpy(ses->status.window_status);
|
|
|
|
}
|
|
|
|
else if (download) {
|
2005-09-15 09:58:31 -04:00
|
|
|
struct document_view *doc_view = current_frame(ses);
|
|
|
|
|
|
|
|
/* Show S_INTERRUPTED message *once* but then show links
|
|
|
|
* again as usual. */
|
|
|
|
/* doc_view->vs may be NULL here in the short interval between
|
|
|
|
* ses_forward() with @loading_in_frame set, disconnecting the
|
|
|
|
* doc_view from vs, and render_document_frames(), detaching
|
|
|
|
* the doc_view. */
|
|
|
|
if (doc_view && doc_view->vs) {
|
|
|
|
static int last_current_link;
|
|
|
|
int ncl = doc_view->vs->current_link;
|
|
|
|
|
2008-08-03 08:24:26 -04:00
|
|
|
if (is_in_state(download->state, S_INTERRUPTED)
|
2005-09-15 09:58:31 -04:00
|
|
|
&& ncl != last_current_link)
|
2008-08-03 08:24:26 -04:00
|
|
|
download->state = connection_state(S_OK);
|
2005-09-15 09:58:31 -04:00
|
|
|
last_current_link = ncl;
|
|
|
|
|
2008-08-03 08:24:26 -04:00
|
|
|
if (is_in_state(download->state, S_OK)) {
|
2005-09-15 09:58:31 -04:00
|
|
|
if (get_current_link(doc_view)) {
|
|
|
|
msg = get_current_link_info_and_title(ses, doc_view);
|
|
|
|
} else if (ses->navigate_mode == NAVIGATE_CURSOR_ROUTING) {
|
|
|
|
msg = msg_text(term, N_("Cursor position: %dx%d"),
|
|
|
|
ses->tab->x + 1, ses->tab->y + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-02 18:13:40 -04:00
|
|
|
|
2005-09-15 09:58:31 -04:00
|
|
|
if (!msg) {
|
|
|
|
int full = term->width > 130;
|
|
|
|
int wide = term->width > 80;
|
|
|
|
|
|
|
|
msg = get_download_msg(download, term, wide, full, ", ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
set_box(&box, 0, term->height - 1, term->width, 1);
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_box_node(term, &box, ' ', 0, get_bfu_color_node(term, "status.status-bar"));
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
if (!status->show_tabs_bar && tabs_count > 1) {
|
2021-01-02 10:20:27 -05:00
|
|
|
char tab_info[8];
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
tab_info[tab_info_len++] = '[';
|
|
|
|
ulongcat(tab_info, &tab_info_len, term->current_tab + 1, 4, 0);
|
|
|
|
tab_info[tab_info_len++] = ']';
|
|
|
|
tab_info[tab_info_len++] = ' ';
|
|
|
|
tab_info[tab_info_len] = '\0';
|
|
|
|
|
2022-03-18 14:22:38 -04:00
|
|
|
text_color_node = get_bfu_color_node(term, "status.status-text");
|
|
|
|
draw_text_node(term, 0, term->height - 1, tab_info, tab_info_len,
|
|
|
|
0, text_color_node);
|
2005-09-15 09:58:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!msg) return;
|
|
|
|
|
2022-03-18 14:22:38 -04:00
|
|
|
if (!text_color_node)
|
|
|
|
text_color_node = get_bfu_color_node(term, "status.status-text");
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
msglen = strlen(msg);
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_text_node(term, 0 + tab_info_len, term->height - 1,
|
|
|
|
msg, msglen, 0, text_color_node);
|
2005-09-15 09:58:31 -04:00
|
|
|
mem_free(msg);
|
|
|
|
|
|
|
|
if (download_is_progressing(download) && download->progress->size > 0) {
|
|
|
|
int xend = term->width - 1;
|
|
|
|
int width;
|
|
|
|
|
|
|
|
#ifdef CONFIG_LEDS
|
|
|
|
if (ses->status.show_leds)
|
|
|
|
xend -= term->leds_length;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
width = int_max(0, xend - msglen - tab_info_len - 1);
|
|
|
|
if (width < 6) return;
|
|
|
|
int_upper_bound(&width, 20);
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_progress_bar_node(download->progress, term,
|
2005-09-15 09:58:31 -04:00
|
|
|
xend - width, term->height - 1, width,
|
2022-03-18 14:22:38 -04:00
|
|
|
NULL, 0);
|
2005-09-15 09:58:31 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
display_tab_bar(struct session *ses, struct terminal *term, int tabs_count)
|
|
|
|
{
|
2022-03-18 14:22:38 -04:00
|
|
|
unsigned int normal_color_node = get_bfu_color_node(term, "tabs.normal");
|
|
|
|
unsigned int selected_color_node = get_bfu_color_node(term, "tabs.selected");
|
|
|
|
unsigned int loading_color_node = get_bfu_color_node(term, "tabs.loading");
|
|
|
|
unsigned int fresh_color_node = get_bfu_color_node(term, "tabs.unvisited");
|
|
|
|
unsigned int tabsep_color_node = get_bfu_color_node(term, "tabs.separator");
|
2005-09-15 09:58:31 -04:00
|
|
|
struct session_status *status = &ses->status;
|
|
|
|
int tab_width = int_max(1, term->width / tabs_count);
|
|
|
|
int tab_total_width = tab_width * tabs_count;
|
|
|
|
int tab_remain_width = int_max(0, term->width - tab_total_width);
|
|
|
|
int tab_add = int_max(1, (tab_remain_width / tabs_count));
|
|
|
|
int tab_num;
|
2018-09-09 13:14:56 -04:00
|
|
|
struct el_box box;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2006-03-04 04:24:37 -05:00
|
|
|
if (status->show_tabs_bar_at_top) set_box(&box, 0, status->show_title_bar, term->width, 1);
|
|
|
|
else set_box(&box, 0, term->height - (status->show_status_bar ? 2 : 1), 0, 1);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
for (tab_num = 0; tab_num < tabs_count; tab_num++) {
|
|
|
|
struct download *download = NULL;
|
2022-03-18 14:22:38 -04:00
|
|
|
unsigned int color_node = normal_color_node;
|
2005-09-15 09:58:31 -04:00
|
|
|
struct window *tab = get_tab_by_number(term, tab_num);
|
|
|
|
struct document_view *doc_view;
|
2022-01-25 11:39:39 -05:00
|
|
|
struct session *tab_ses = (struct session *)tab->data;
|
2005-09-15 09:58:31 -04:00
|
|
|
int actual_tab_width = tab_width - 1;
|
2021-01-02 10:20:27 -05:00
|
|
|
char *msg;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
/* Adjust tab size to use full term width. */
|
|
|
|
if (tab_remain_width) {
|
|
|
|
actual_tab_width += tab_add;
|
|
|
|
tab_remain_width -= tab_add;
|
|
|
|
}
|
|
|
|
|
|
|
|
doc_view = tab_ses ? current_frame(tab_ses) : NULL;
|
|
|
|
|
|
|
|
if (doc_view) {
|
|
|
|
if (doc_view->document->title
|
|
|
|
&& *(doc_view->document->title))
|
|
|
|
msg = doc_view->document->title;
|
|
|
|
else
|
|
|
|
msg = _("Untitled", term);
|
|
|
|
} else {
|
|
|
|
msg = _("No document", term);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tab_num) {
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_char_node(term, box.x, box.y, BORDER_SVLINE,
|
|
|
|
SCREEN_ATTR_FRAME, tabsep_color_node);
|
2005-09-15 09:58:31 -04:00
|
|
|
box.x++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tab_num == term->current_tab) {
|
2022-03-18 14:22:38 -04:00
|
|
|
color_node = selected_color_node;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
} else {
|
|
|
|
download = get_current_download(tab_ses);
|
|
|
|
|
2008-08-03 08:24:26 -04:00
|
|
|
if (download && !is_in_state(download->state, S_OK)) {
|
2022-03-18 14:22:38 -04:00
|
|
|
color_node = loading_color_node;
|
2005-09-15 09:58:31 -04:00
|
|
|
} else if (!tab_ses || !tab_ses->status.visited) {
|
2022-03-18 14:22:38 -04:00
|
|
|
color_node = fresh_color_node;
|
2005-09-15 09:58:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!download_is_progressing(download)
|
|
|
|
|| download->progress->size <= 0)
|
|
|
|
download = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
box.width = actual_tab_width + 1;
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_box_node(term, &box, ' ', 0, color_node);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
if (download) {
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_progress_bar_node(download->progress, term,
|
2005-09-15 09:58:31 -04:00
|
|
|
box.x, box.y, actual_tab_width,
|
2022-03-18 14:22:38 -04:00
|
|
|
msg, 0);
|
2005-09-15 09:58:31 -04:00
|
|
|
} else {
|
2009-01-01 15:01:50 -05:00
|
|
|
int msglen;
|
|
|
|
#ifdef CONFIG_UTF8
|
|
|
|
if (term->utf8_cp) {
|
|
|
|
msglen = utf8_step_forward(msg, NULL,
|
|
|
|
actual_tab_width,
|
|
|
|
UTF8_STEP_CELLS_FEWER,
|
|
|
|
NULL) - msg;
|
|
|
|
} else
|
|
|
|
#endif /* CONFIG_UTF8 */
|
|
|
|
msglen = int_min(strlen(msg), actual_tab_width);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_text_node(term, box.x, box.y, msg, msglen, 0, color_node);
|
2005-09-15 09:58:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
tab->xpos = box.x;
|
|
|
|
tab->width = actual_tab_width;
|
|
|
|
if (tab_num == tabs_count - 1) {
|
|
|
|
/* This is the last tab, and is therefore followed
|
|
|
|
* by a space, not a separator; increment tab->width
|
|
|
|
* to count that space as part of the tab.
|
|
|
|
* -- Miciah */
|
|
|
|
tab->width++;
|
|
|
|
}
|
|
|
|
|
|
|
|
box.x += actual_tab_width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print page's title and numbering at window top. */
|
|
|
|
static inline void
|
|
|
|
display_title_bar(struct session *ses, struct terminal *term)
|
|
|
|
{
|
|
|
|
struct document_view *doc_view;
|
|
|
|
struct document *document;
|
2019-04-21 06:27:40 -04:00
|
|
|
struct string title;
|
2021-01-02 10:20:27 -05:00
|
|
|
char buf[40];
|
2005-09-15 09:58:31 -04:00
|
|
|
int buflen = 0;
|
|
|
|
int height;
|
|
|
|
|
|
|
|
/* Clear the old title */
|
2007-08-28 12:41:18 -04:00
|
|
|
if (!get_opt_bool("ui.show_menu_bar_always", NULL)) {
|
2018-09-09 13:14:56 -04:00
|
|
|
struct el_box box;
|
2006-03-03 13:01:15 -05:00
|
|
|
|
|
|
|
set_box(&box, 0, 0, term->width, 1);
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_box_node(term, &box, ' ', 0, get_bfu_color_node(term, "title.title-bar"));
|
2006-03-03 13:01:15 -05:00
|
|
|
}
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
doc_view = current_frame(ses);
|
|
|
|
if (!doc_view || !doc_view->document) return;
|
|
|
|
|
|
|
|
if (!init_string(&title)) return;
|
|
|
|
|
|
|
|
document = doc_view->document;
|
|
|
|
|
|
|
|
/* Set up the document page info string: '(' %page '/' %pages ')' */
|
|
|
|
height = doc_view->box.height;
|
|
|
|
if (height < document->height && doc_view->vs) {
|
|
|
|
int pos = doc_view->vs->y + height;
|
|
|
|
int page = 1;
|
|
|
|
int pages = height ? (document->height + height - 1) / height : 1;
|
|
|
|
|
|
|
|
/* Check if at the end else calculate the page. */
|
|
|
|
if (pos >= document->height) {
|
|
|
|
page = pages;
|
|
|
|
} else if (height) {
|
|
|
|
page = int_min((pos - height / 2) / height + 1, pages);
|
|
|
|
}
|
|
|
|
|
|
|
|
buflen = snprintf(buf, sizeof(buf), " (%d/%d)", page, pages);
|
|
|
|
if (buflen < 0) buflen = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (document->title) {
|
|
|
|
int maxlen = int_max(term->width - 4 - buflen, 0);
|
2006-03-04 19:54:17 -05:00
|
|
|
int titlelen, titlewidth;
|
|
|
|
|
2006-09-17 09:12:47 -04:00
|
|
|
#ifdef CONFIG_UTF8
|
2007-05-20 08:31:02 -04:00
|
|
|
if (term->utf8_cp) {
|
2006-03-04 19:54:17 -05:00
|
|
|
titlewidth = utf8_ptr2cells(document->title, NULL);
|
|
|
|
titlewidth = int_min(titlewidth, maxlen);
|
|
|
|
|
|
|
|
titlelen = utf8_cells2bytes(document->title,
|
|
|
|
titlewidth, NULL);
|
|
|
|
} else
|
2006-09-17 09:12:47 -04:00
|
|
|
#endif /* CONFIG_UTF8 */
|
2006-03-04 19:54:17 -05:00
|
|
|
{
|
|
|
|
titlewidth = int_min(strlen(document->title), maxlen);
|
|
|
|
titlelen = titlewidth;
|
|
|
|
}
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
add_bytes_to_string(&title, document->title, titlelen);
|
|
|
|
|
2006-03-04 19:54:17 -05:00
|
|
|
if (titlewidth == maxlen)
|
2005-09-15 09:58:31 -04:00
|
|
|
add_bytes_to_string(&title, "...", 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buflen > 0)
|
|
|
|
add_bytes_to_string(&title, buf, buflen);
|
|
|
|
|
|
|
|
if (title.length) {
|
2006-03-04 19:54:17 -05:00
|
|
|
int x;
|
2006-09-17 09:12:47 -04:00
|
|
|
#ifdef CONFIG_UTF8
|
2007-05-20 08:31:02 -04:00
|
|
|
if (term->utf8_cp) {
|
2006-07-27 03:51:10 -04:00
|
|
|
x = int_max(term->width - 1
|
|
|
|
- utf8_ptr2cells(title.source,
|
2006-03-04 19:54:17 -05:00
|
|
|
title.source
|
|
|
|
+ title.length), 0);
|
|
|
|
} else
|
2006-09-17 09:12:47 -04:00
|
|
|
#endif /* CONFIG_UTF8 */
|
2006-03-04 19:54:17 -05:00
|
|
|
x = int_max(term->width - 1 - title.length, 0);
|
2005-09-15 09:58:31 -04:00
|
|
|
|
2022-03-18 14:22:38 -04:00
|
|
|
draw_text_node(term, x, 0, title.source, title.length, 0,
|
|
|
|
get_bfu_color_node(term, "title.title-text"));
|
2005-09-15 09:58:31 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
done_string(&title);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
display_window_title(struct session *ses, struct terminal *term)
|
|
|
|
{
|
|
|
|
static struct session *last_ses;
|
|
|
|
struct session_status *status = &ses->status;
|
2021-01-02 10:20:27 -05:00
|
|
|
char *doc_title = NULL;
|
|
|
|
char *title;
|
2005-09-15 09:58:31 -04:00
|
|
|
int titlelen;
|
|
|
|
|
|
|
|
if (ses->doc_view
|
|
|
|
&& ses->doc_view->document
|
|
|
|
&& ses->doc_view->document->title
|
|
|
|
&& ses->doc_view->document->title[0])
|
|
|
|
doc_title = ses->doc_view->document->title;
|
|
|
|
|
2007-03-11 06:59:11 -04:00
|
|
|
title = doc_title ? straconcat(doc_title, " - ELinks",
|
2021-01-02 10:20:27 -05:00
|
|
|
(char *) NULL)
|
2005-09-15 09:58:31 -04:00
|
|
|
: stracpy("ELinks");
|
|
|
|
if (!title) return;
|
|
|
|
|
|
|
|
titlelen = strlen(title);
|
Bug 885: Proper charset support in xterm window title
When ELinks runs in an X11 terminal emulator (e.g. xterm), or in GNU
Screen, it tries to update the title of the window to match the title
of the current document. To do this, ELinks sends an "OSC 1 ; Pt BEL"
sequence to the terminal. Unfortunately, xterm expects the Pt string
to be in the ISO-8859-1 charset, making it impossible to display e.g.
Cyrillic characters. In xterm patch #210 (2006-03-12) however, there
is a menu item and a resource that can make xterm take the Pt string
in UTF-8 instead, allowing characters from all around the world.
The downside is that ELinks apparently cannot ask xterm whether the
setting is on or off; so add a terminal._template_.latin1_title option
to ELinks and let the user edit that instead.
Complete list of changes:
- Add the terminal._template_.latin1_title option. But do not add
that to the terminal options window because it's already rather
crowded there.
- In set_window_title(), take a new codepage argument. Use it to
decode the title into Unicode characters, and remove only actual
control characters. For example, CP437 has graphical characters in
the 0x80...0x9F range, so don't remove those, even though ISO-8859-1
has control characters in the same range. Likewise, don't
misinterpret single bytes of UTF-8 characters as control characters.
- In set_window_title(), do not truncate the title to the width of the
window. The font is likely to be different and proportional anyway.
But do truncate before 1024 bytes, an xterm limit.
- In struct itrm, add a title_codepage member to remember which
charset the master said it was going to use in the terminal window
title. Initialize title_codepage in handle_trm(), update it in
dispatch_special() if the master sends the new request
TERM_FN_TITLE_CODEPAGE, and use it in most set_window_title() calls;
but not in the one that sets $TERM as the title, because that string
was not received from the master and should consist of ASCII
characters only.
- In set_terminal_title(), convert the caller-provided title to
ISO-8859-1 or UTF-8 if appropriate, and report the codepage to the
slave with the new TERM_FN_TITLE_CODEPAGE request. The conversion
can run out of memory, so return a success/error flag, rather than
void. In display_window_title(), check this result and don't update
caches on error.
- Add a NEWS entry for all of this.
2008-12-28 20:09:53 -05:00
|
|
|
if ((last_ses != ses
|
|
|
|
|| !status->last_title
|
|
|
|
|| strlen(status->last_title) != titlelen
|
|
|
|
|| memcmp(status->last_title, title, titlelen))
|
|
|
|
&& set_terminal_title(term, title) >= 0) {
|
2005-09-15 09:58:31 -04:00
|
|
|
mem_free_set(&status->last_title, title);
|
|
|
|
last_ses = ses;
|
|
|
|
} else {
|
|
|
|
mem_free(title);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_LEDS
|
|
|
|
static inline void
|
|
|
|
display_leds(struct session *ses, struct session_status *status)
|
|
|
|
{
|
2006-12-09 22:11:04 -05:00
|
|
|
if (ses->doc_view && ses->doc_view->document) {
|
|
|
|
struct cache_entry *cached = ses->doc_view->document->cached;
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
if (cached) {
|
|
|
|
if (cached->ssl_info)
|
|
|
|
set_led_value(status->ssl_led, 'S');
|
|
|
|
else
|
|
|
|
unset_led_value(status->ssl_led);
|
|
|
|
} else {
|
|
|
|
/* FIXME: We should do this thing better. */
|
|
|
|
set_led_value(status->ssl_led, '?');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ses->insert_mode == INSERT_MODE_LESS) {
|
|
|
|
set_led_value(status->insert_mode_led, 'i');
|
|
|
|
} else {
|
|
|
|
if (ses->insert_mode == INSERT_MODE_ON)
|
|
|
|
set_led_value(status->insert_mode_led, 'I');
|
|
|
|
else
|
|
|
|
unset_led_value(status->insert_mode_led);
|
|
|
|
}
|
|
|
|
|
|
|
|
draw_leds(ses);
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_LEDS */
|
|
|
|
|
|
|
|
/* Print statusbar and titlebar, set terminal title. */
|
|
|
|
void
|
|
|
|
print_screen_status(struct session *ses)
|
|
|
|
{
|
|
|
|
struct terminal *term = ses->tab->term;
|
|
|
|
struct session_status *status = &ses->status;
|
|
|
|
int tabs_count = number_of_tabs(term);
|
|
|
|
int ses_tab_is_current = (ses->tab == get_current_tab(term));
|
|
|
|
|
|
|
|
if (ses_tab_is_current) {
|
|
|
|
if (status->set_window_title)
|
|
|
|
display_window_title(ses, term);
|
|
|
|
|
|
|
|
if (status->show_title_bar)
|
|
|
|
display_title_bar(ses, term);
|
|
|
|
|
|
|
|
if (status->show_status_bar)
|
|
|
|
display_status_bar(ses, term, tabs_count);
|
|
|
|
#ifdef CONFIG_LEDS
|
|
|
|
if (status->show_leds)
|
|
|
|
display_leds(ses, status);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!ses->status.visited)
|
|
|
|
ses->status.visited = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status->show_tabs_bar) {
|
|
|
|
display_tab_bar(ses, term, tabs_count);
|
|
|
|
}
|
|
|
|
|
2008-10-12 07:01:05 -04:00
|
|
|
redraw_windows(REDRAW_IN_FRONT_OF_WINDOW, ses->tab);
|
2005-09-15 09:58:31 -04:00
|
|
|
}
|