From 315df0075ea3d8793e6b57142e7298818b6c84a0 Mon Sep 17 00:00:00 2001 From: Richard Russon Date: Sun, 1 Apr 2018 05:12:17 +0100 Subject: [PATCH] split out window functions --- Makefile.autosetup | 2 +- addrbook.c | 1 + browser.c | 1 + buffy.c | 1 + commands.c | 1 + compose.c | 1 + copy.c | 1 + curs_lib.c | 205 +--------------------------- curs_main.c | 3 +- edit.c | 1 + enter.c | 1 + filter.c | 1 + flags.c | 1 + handler.c | 1 + hdrline.c | 1 + help.c | 1 + history.c | 1 + init.c | 5 +- keymap.c | 1 + main.c | 9 +- menu.c | 3 +- mutt_curses.h | 42 ------ mutt_logging.c | 1 + mutt_window.c | 309 +++++++++++++++++++++++++++++++++++++++++++ mutt_window.h | 62 +++++++++ muttlib.c | 1 + ncrypt/crypt_gpgme.c | 1 + ncrypt/pgpinvoke.c | 1 + ncrypt/pgpkey.c | 1 + ncrypt/smime.c | 1 + newsrc.c | 1 + pager.c | 7 +- query.c | 1 + recvattach.c | 1 + recvcmd.c | 1 + remailer.c | 1 + resize.c | 3 +- rfc3676.c | 1 + sendlib.c | 1 + sidebar.c | 1 + status.c | 1 + 41 files changed, 426 insertions(+), 254 deletions(-) create mode 100644 mutt_window.c create mode 100644 mutt_window.h diff --git a/Makefile.autosetup b/Makefile.autosetup index a49de85af..847d29455 100644 --- a/Makefile.autosetup +++ b/Makefile.autosetup @@ -65,7 +65,7 @@ NEOMUTTOBJS= addrbook.o alias.o attach.o bcache.o body.o browser.o buffy.o \ enter.o envelope.o filter.o flags.o from.o group.o handler.o \ hdrline.o header.o help.o history.o hook.o init.o keymap.o \ main.o mbox.o menu.o mh.o muttlib.o mutt_account.o \ - mutt_logging.o mutt_signal.o mutt_socket.o mx.o newsrc.o \ + mutt_logging.o mutt_signal.o mutt_socket.o mutt_window.o mx.o newsrc.o \ nntp.o pager.o parse.o pattern.o pop.o pop_auth.o pop_lib.o \ postpone.o query.o recvattach.o recvcmd.o resize.o rfc1524.o \ rfc2047.o rfc2231.o rfc3676.o safe_asprintf.o score.o send.o \ diff --git a/addrbook.c b/addrbook.c index 643aaff3e..7fd999869 100644 --- a/addrbook.c +++ b/addrbook.c @@ -32,6 +32,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "opcodes.h" #include "options.h" #include "protos.h" diff --git a/browser.c b/browser.c index 7d64c501d..e09dfd0c2 100644 --- a/browser.c +++ b/browser.c @@ -50,6 +50,7 @@ #include "mutt_account.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "opcodes.h" #include "options.h" diff --git a/buffy.c b/buffy.c index 652f4ebd5..afbd34035 100644 --- a/buffy.c +++ b/buffy.c @@ -39,6 +39,7 @@ #include "mailbox.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "options.h" #include "protos.h" diff --git a/commands.c b/commands.c index 334a4d1dc..41f0ab49c 100644 --- a/commands.c +++ b/commands.c @@ -46,6 +46,7 @@ #include "mailbox.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "options.h" diff --git a/compose.c b/compose.c index 689f4ff2b..ef5a81a3f 100644 --- a/compose.c +++ b/compose.c @@ -45,6 +45,7 @@ #include "mailbox.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "opcodes.h" diff --git a/copy.c b/copy.c index 2d0b6c3f3..ab5487c51 100644 --- a/copy.c +++ b/copy.c @@ -35,6 +35,7 @@ #include "header.h" #include "mailbox.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "options.h" diff --git a/curs_lib.c b/curs_lib.c index 5773acf66..6d801dcdb 100644 --- a/curs_lib.c +++ b/curs_lib.c @@ -46,6 +46,7 @@ #include "header.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "opcodes.h" #include "options.h" #include "pager.h" @@ -76,16 +77,6 @@ static size_t UngetCount = 0; static size_t UngetLen = 0; static struct Event *UngetKeyEvents; -struct MuttWindow *MuttHelpWindow = NULL; -struct MuttWindow *MuttIndexWindow = NULL; -struct MuttWindow *MuttStatusWindow = NULL; -struct MuttWindow *MuttMessageWindow = NULL; -#ifdef USE_SIDEBAR -struct MuttWindow *MuttSidebarWindow = NULL; -#endif - -static void reflow_message_window_rows(int mw_rows); - void mutt_refresh(void) { /* don't refresh when we are waiting for a child. */ @@ -191,7 +182,7 @@ int mutt_get_field_full(const char *field, char *buf, size_t buflen, addstr((char *) field); /* cast to get around bad prototypes */ NORMAL_COLOR; mutt_refresh(); - mutt_window_getyx(MuttMessageWindow, NULL, &x); + mutt_window_getxy(MuttMessageWindow, &x, NULL); ret = mutt_enter_string_full(buf, buflen, x, complete, multiple, files, numfiles, es); } while (ret == 1); mutt_window_clearline(MuttMessageWindow, 0); @@ -283,7 +274,7 @@ int mutt_yesorno(const char *msg, int def) } if (prompt_lines != MuttMessageWindow->rows) { - reflow_message_window_rows(prompt_lines); + mutt_window_reflow_message_rows(prompt_lines); mutt_menu_current_redraw(); } @@ -341,7 +332,7 @@ int mutt_yesorno(const char *msg, int def) if (MuttMessageWindow->rows != 1) { - reflow_message_window_rows(1); + mutt_window_reflow_message_rows(1); mutt_menu_current_redraw(); } else @@ -551,190 +542,6 @@ out: mutt_clear_error(); } -void mutt_init_windows(void) -{ - MuttHelpWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); - MuttIndexWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); - MuttStatusWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); - MuttMessageWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); -#ifdef USE_SIDEBAR - MuttSidebarWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); -#endif -} - -void mutt_free_windows(void) -{ - FREE(&MuttHelpWindow); - FREE(&MuttIndexWindow); - FREE(&MuttStatusWindow); - FREE(&MuttMessageWindow); -#ifdef USE_SIDEBAR - FREE(&MuttSidebarWindow); -#endif -} - -void mutt_reflow_windows(void) -{ - if (OPT_NO_CURSES) - return; - - mutt_debug(2, "entering\n"); - - MuttStatusWindow->rows = 1; - MuttStatusWindow->cols = COLS; - MuttStatusWindow->row_offset = StatusOnTop ? 0 : LINES - 2; - MuttStatusWindow->col_offset = 0; - - memcpy(MuttHelpWindow, MuttStatusWindow, sizeof(struct MuttWindow)); - if (!Help) - MuttHelpWindow->rows = 0; - else - MuttHelpWindow->row_offset = StatusOnTop ? LINES - 2 : 0; - - memcpy(MuttMessageWindow, MuttStatusWindow, sizeof(struct MuttWindow)); - MuttMessageWindow->row_offset = LINES - 1; - - memcpy(MuttIndexWindow, MuttStatusWindow, sizeof(struct MuttWindow)); - MuttIndexWindow->rows = MAX( - LINES - MuttStatusWindow->rows - MuttHelpWindow->rows - MuttMessageWindow->rows, 0); - MuttIndexWindow->row_offset = - StatusOnTop ? MuttStatusWindow->rows : MuttHelpWindow->rows; - -#ifdef USE_SIDEBAR - if (SidebarVisible) - { - memcpy(MuttSidebarWindow, MuttIndexWindow, sizeof(struct MuttWindow)); - MuttSidebarWindow->cols = SidebarWidth; - MuttIndexWindow->cols -= SidebarWidth; - - if (SidebarOnRight) - { - MuttSidebarWindow->col_offset = COLS - SidebarWidth; - } - else - { - MuttIndexWindow->col_offset += SidebarWidth; - } - } -#endif - - mutt_menu_set_current_redraw_full(); - /* the pager menu needs this flag set to recalc line_info */ - mutt_menu_set_current_redraw(REDRAW_FLOW); -} - -static void reflow_message_window_rows(int mw_rows) -{ - MuttMessageWindow->rows = mw_rows; - MuttMessageWindow->row_offset = LINES - mw_rows; - - MuttStatusWindow->row_offset = StatusOnTop ? 0 : LINES - mw_rows - 1; - - if (Help) - MuttHelpWindow->row_offset = StatusOnTop ? LINES - mw_rows - 1 : 0; - - MuttIndexWindow->rows = MAX( - LINES - MuttStatusWindow->rows - MuttHelpWindow->rows - MuttMessageWindow->rows, 0); - -#ifdef USE_SIDEBAR - if (SidebarVisible) - MuttSidebarWindow->rows = MuttIndexWindow->rows; -#endif - - /* We don't also set REDRAW_FLOW because this function only - * changes rows and is a temporary adjustment. */ - mutt_menu_set_current_redraw_full(); -} - -int mutt_window_move(struct MuttWindow *win, int row, int col) -{ - return move(win->row_offset + row, win->col_offset + col); -} - -int mutt_window_mvaddch(struct MuttWindow *win, int row, int col, const chtype ch) -{ - return mvaddch(win->row_offset + row, win->col_offset + col, ch); -} - -int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str) -{ - return mvaddstr(win->row_offset + row, win->col_offset + col, str); -} - -#ifdef USE_SLANG_CURSES -static int vw_printw(SLcurses_Window_Type *win, const char *fmt, va_list ap) -{ - char buf[LONG_STRING]; - - (void) SLvsnprintf(buf, sizeof(buf), (char *) fmt, ap); - SLcurses_waddnstr(win, buf, -1); - return 0; -} -#endif - -int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt, ...) -{ - int rc = mutt_window_move(win, row, col); - if (rc != ERR) - { - va_list ap; - va_start(ap, fmt); - rc = vw_printw(stdscr, fmt, ap); - va_end(ap); - } - - return rc; -} - -/** - * mutt_window_clrtoeol - Clear to the end of the line - * - * Assumes the cursor has already been positioned within the window. - */ -void mutt_window_clrtoeol(struct MuttWindow *win) -{ - if (!win || !stdscr) - return; - - if (win->col_offset + win->cols == COLS) - clrtoeol(); - else - { - int row, col; - getyx(stdscr, row, col); - int curcol = col; - while (curcol < win->col_offset + win->cols) - { - addch(' '); - curcol++; - } - move(row, col); - } -} - -void mutt_window_clearline(struct MuttWindow *win, int row) -{ - mutt_window_move(win, row, 0); - mutt_window_clrtoeol(win); -} - -/** - * mutt_window_getyx - Get the cursor position in the window - * - * Assumes the current position is inside the window. Otherwise it will - * happily return negative or values outside the window boundaries - */ -void mutt_window_getyx(struct MuttWindow *win, int *y, int *x) -{ - int row, col; - - getyx(stdscr, row, col); - if (y) - *y = row - win->row_offset; - if (x) - *x = col - win->col_offset; -} - void mutt_show_error(void) { if (OPT_KEEP_QUIET || !ErrorBufMessage) @@ -1006,7 +813,7 @@ int mutt_multi_choice(char *prompt, char *letters) } if (prompt_lines != MuttMessageWindow->rows) { - reflow_message_window_rows(prompt_lines); + mutt_window_reflow_message_rows(prompt_lines); mutt_menu_current_redraw(); } @@ -1048,7 +855,7 @@ int mutt_multi_choice(char *prompt, char *letters) } if (MuttMessageWindow->rows != 1) { - reflow_message_window_rows(1); + mutt_window_reflow_message_rows(1); mutt_menu_current_redraw(); } else diff --git a/curs_main.c b/curs_main.c index 77f115c1a..f967f15ce 100644 --- a/curs_main.c +++ b/curs_main.c @@ -43,6 +43,7 @@ #include "mailbox.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "opcodes.h" @@ -3276,7 +3277,7 @@ int mutt_index_menu(void) case OP_SIDEBAR_TOGGLE_VISIBLE: SidebarVisible = !SidebarVisible; - mutt_reflow_windows(); + mutt_window_reflow(); break; case OP_SIDEBAR_TOGGLE_VIRTUAL: diff --git a/edit.c b/edit.c index 6dfce77b0..b6a878c5f 100644 --- a/edit.c +++ b/edit.c @@ -38,6 +38,7 @@ #include "globals.h" #include "header.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "options.h" #include "protos.h" diff --git a/enter.c b/enter.c index 86cd2f146..a3eb41a3f 100644 --- a/enter.c +++ b/enter.c @@ -34,6 +34,7 @@ #include "history.h" #include "keymap.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "opcodes.h" #include "protos.h" diff --git a/filter.c b/filter.c index 9d172c1f0..83fac2dc5 100644 --- a/filter.c +++ b/filter.c @@ -28,6 +28,7 @@ #include "mutt.h" #include "filter.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "protos.h" /** diff --git a/flags.c b/flags.c index 549c5aae6..28c75cd31 100644 --- a/flags.c +++ b/flags.c @@ -30,6 +30,7 @@ #include "header.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "options.h" #include "protos.h" diff --git a/handler.c b/handler.c index 9609925e5..3282f4afe 100644 --- a/handler.c +++ b/handler.c @@ -42,6 +42,7 @@ #include "globals.h" #include "keymap.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "ncrypt/ncrypt.h" #include "opcodes.h" #include "options.h" diff --git a/hdrline.c b/hdrline.c index 11c5f4b87..b15fe75ab 100644 --- a/hdrline.c +++ b/hdrline.c @@ -39,6 +39,7 @@ #include "header.h" #include "mbtable.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "ncrypt/ncrypt.h" #include "options.h" #include "protos.h" diff --git a/help.c b/help.c index 3ab125878..e7d47173e 100644 --- a/help.c +++ b/help.c @@ -31,6 +31,7 @@ #include "globals.h" #include "keymap.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "opcodes.h" #include "options.h" #include "pager.h" diff --git a/history.c b/history.c index 088f53184..b64d423ab 100644 --- a/history.c +++ b/history.c @@ -80,6 +80,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "opcodes.h" #include "options.h" #include "protos.h" diff --git a/init.c b/init.c index 1db6f7796..d83f16373 100644 --- a/init.c +++ b/init.c @@ -50,6 +50,7 @@ #include "mbtable.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "myvar.h" #include "ncrypt/ncrypt.h" @@ -1967,7 +1968,7 @@ static void restore_default(struct Option *p) if (p->flags & R_TREE) OPT_REDRAW_TREE = true; if (p->flags & R_REFLOW) - mutt_reflow_windows(); + mutt_window_reflow(); #ifdef USE_SIDEBAR if (p->flags & R_SIDEBAR) mutt_menu_set_current_redraw(REDRAW_SIDEBAR); @@ -2715,7 +2716,7 @@ static int parse_set(struct Buffer *tmp, struct Buffer *s, unsigned long data, if (MuttVars[idx].flags & R_TREE) OPT_REDRAW_TREE = true; if (MuttVars[idx].flags & R_REFLOW) - mutt_reflow_windows(); + mutt_window_reflow(); #ifdef USE_SIDEBAR if (MuttVars[idx].flags & R_SIDEBAR) mutt_menu_set_current_redraw(REDRAW_SIDEBAR); diff --git a/keymap.c b/keymap.c index fef10d21e..02fde9215 100644 --- a/keymap.c +++ b/keymap.c @@ -34,6 +34,7 @@ #include "functions.h" #include "globals.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "ncrypt/ncrypt.h" #include "opcodes.h" #include "options.h" diff --git a/main.c b/main.c index 83b0cab0a..34e1efa09 100644 --- a/main.c +++ b/main.c @@ -49,6 +49,7 @@ #include "mutt_curses.h" #include "mutt_logging.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "myvar.h" #include "ncrypt/ncrypt.h" #include "options.h" @@ -160,7 +161,7 @@ static int start_curses(void) meta(stdscr, true); #endif init_extended_keys(); - mutt_reflow_windows(); + mutt_window_reflow(); return 0; } @@ -509,7 +510,7 @@ int main(int argc, char *argv[], char *envp[]) /* Always create the mutt_windows because batch mode has some shared code * paths that end up referencing them. */ - mutt_init_windows(); + mutt_window_init(); /* This must come before mutt_init() because curses needs to be started * before calling the init_pair() function to set the color scheme. */ @@ -946,7 +947,7 @@ int main(int argc, char *argv[], char *envp[]) FREE(&tempfile); } - mutt_free_windows(); + mutt_window_free(); if (rv != 0) goto main_curses; // TEST36: neomutt -H existing -s test john@example.com -E (cancel sending) @@ -1048,7 +1049,7 @@ int main(int argc, char *argv[], char *envp[]) log_queue_empty(); mutt_log_stop(); mutt_free_opts(); - mutt_free_windows(); + mutt_window_free(); // TEST43: neomutt (no change to mailbox) // TEST44: neomutt (change mailbox) } diff --git a/menu.c b/menu.c index e7194ceee..97311db5f 100644 --- a/menu.c +++ b/menu.c @@ -34,6 +34,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "opcodes.h" #include "options.h" #include "pattern.h" @@ -301,7 +302,7 @@ static void menu_pad_string(struct Menu *menu, char *buf, size_t buflen) void menu_redraw_full(struct Menu *menu) { - mutt_reflow_windows(); + mutt_window_reflow(); NORMAL_COLOR; /* clear() doesn't optimize screen redraws */ move(0, 0); diff --git a/mutt_curses.h b/mutt_curses.h index 9c8fbcd12..35ed76df7 100644 --- a/mutt_curses.h +++ b/mutt_curses.h @@ -226,48 +226,6 @@ void mutt_progress_init(struct Progress *progress, const char *msg, * was initialized with positive size, otherwise no percentage is shown */ void mutt_progress_update(struct Progress *progress, long pos, int percent); -/** - * struct MuttWindow - A division of the screen - * - * Windows for different parts of the screen - */ -struct MuttWindow -{ - int rows; - int cols; - int row_offset; - int col_offset; -}; - -extern struct MuttWindow *MuttHelpWindow; -extern struct MuttWindow *MuttIndexWindow; -extern struct MuttWindow *MuttStatusWindow; -extern struct MuttWindow *MuttMessageWindow; -#ifdef USE_SIDEBAR -extern struct MuttWindow *MuttSidebarWindow; -#endif - -void mutt_init_windows(void); -void mutt_free_windows(void); -void mutt_reflow_windows(void); -int mutt_window_move(struct MuttWindow *win, int row, int col); -int mutt_window_mvaddch(struct MuttWindow *win, int row, int col, const chtype ch); -int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str); -int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt, ...); -void mutt_window_clrtoeol(struct MuttWindow *win); -void mutt_window_clearline(struct MuttWindow *win, int row); -void mutt_window_getyx(struct MuttWindow *win, int *y, int *x); - -static inline int mutt_window_wrap_cols(struct MuttWindow *win, short wrap) -{ - if (wrap < 0) - return win->cols > -wrap ? win->cols + wrap : win->cols; - else if (wrap) - return wrap < win->cols ? wrap : win->cols; - else - return win->cols; -} - extern int *ColorQuote; extern int ColorQuoteUsed; extern int ColorDefs[]; diff --git a/mutt_logging.c b/mutt_logging.c index f1fa568a3..c9c4ff976 100644 --- a/mutt_logging.c +++ b/mutt_logging.c @@ -36,6 +36,7 @@ #include "mutt/mutt.h" #include "globals.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "protos.h" struct timeval LastError = { 0 }; diff --git a/mutt_window.c b/mutt_window.c new file mode 100644 index 000000000..4827e7bbd --- /dev/null +++ b/mutt_window.c @@ -0,0 +1,309 @@ +/** + * @file + * Window management + * + * @authors + * Copyright (C) 2018 Richard Russon + * + * @copyright + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "config.h" +#include "globals.h" +#include "mutt/logging.h" +#include "mutt/mutt.h" +#include "mutt_menu.h" +#include "mutt_window.h" +#include "options.h" +#include +#include + +struct MuttWindow *MuttHelpWindow = NULL; +struct MuttWindow *MuttIndexWindow = NULL; +struct MuttWindow *MuttStatusWindow = NULL; +struct MuttWindow *MuttMessageWindow = NULL; +#ifdef USE_SIDEBAR +struct MuttWindow *MuttSidebarWindow = NULL; +#endif + +#ifdef USE_SLANG_CURSES +/** + * vw_printw - Write a formatted string to a Window (function missing from Slang) + * @param win Window + * @param fmt printf format string + * @param ap printf arguments + * @retval 0 Always + */ +static int vw_printw(SLcurses_Window_Type *win, const char *fmt, va_list ap) +{ + char buf[LONG_STRING]; + + (void) SLvsnprintf(buf, sizeof(buf), (char *) fmt, ap); + SLcurses_waddnstr(win, buf, -1); + return 0; +} +#endif + +/** + * mutt_window_clearline - Clear a row of a Window + * @param win Window + * @param row Row to clear + */ +void mutt_window_clearline(struct MuttWindow *win, int row) +{ + mutt_window_move(win, row, 0); + mutt_window_clrtoeol(win); +} + +/** + * mutt_window_clrtoeol - Clear to the end of the line + * @param win Window + * + * @note Assumes the cursor has already been positioned within the window. + */ +void mutt_window_clrtoeol(struct MuttWindow *win) +{ + if (!win || !stdscr) + return; + + if (win->col_offset + win->cols == COLS) + clrtoeol(); + else + { + int row = 0; + int col = 0; + getyx(stdscr, row, col); + int curcol = col; + while (curcol < (win->col_offset + win->cols)) + { + addch(' '); + curcol++; + } + move(row, col); + } +} + +/** + * mutt_window_free - Free the default Windows + */ +void mutt_window_free(void) +{ + FREE(&MuttHelpWindow); + FREE(&MuttIndexWindow); + FREE(&MuttStatusWindow); + FREE(&MuttMessageWindow); +#ifdef USE_SIDEBAR + FREE(&MuttSidebarWindow); +#endif +} + +/** + * mutt_window_getxy - Get the cursor position in the Window + * @param[in] win Window + * @param[out] x X-Coordinate + * @param[out] y Y-Coordinate + * + * Assumes the current position is inside the window. Otherwise it will + * happily return negative or values outside the window boundaries + */ +void mutt_window_getxy(struct MuttWindow *win, int *x, int *y) +{ + int row = 0; + int col = 0; + + getyx(stdscr, row, col); + if (x) + *x = col - win->col_offset; + if (y) + *y = row - win->row_offset; +} + +/** + * mutt_window_init - Create the default Windows + * + * Create the Help, Index, Status, Message and Sidebar Windows. + */ +void mutt_window_init(void) +{ + MuttHelpWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); + MuttIndexWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); + MuttStatusWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); + MuttMessageWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); +#ifdef USE_SIDEBAR + MuttSidebarWindow = mutt_mem_calloc(1, sizeof(struct MuttWindow)); +#endif +} + +/** + * mutt_window_move - Move the cursor in a Window + * @param win Window + * @param row Row to move to + * @param col Column to move to + * @retval OK Success + * @retval ERR Error + */ +int mutt_window_move(struct MuttWindow *win, int row, int col) +{ + return move(win->row_offset + row, win->col_offset + col); +} + +/** + * mutt_window_mvaddch - Move the cursor and write a character to a Window + * @param win Window to write to + * @param row Row to move to + * @param col Column to move to + * @param ch Character to write + * @retval OK Success + * @retval ERR Error + */ +int mutt_window_mvaddch(struct MuttWindow *win, int row, int col, const chtype ch) +{ + return mvaddch(win->row_offset + row, win->col_offset + col, ch); +} + +/** + * mutt_window_mvaddstr - Move the cursor and write a fixed string to a Window + * @param win Window to write to + * @param row Row to move to + * @param col Column to move to + * @param str String to write + * @retval OK Success + * @retval ERR Error + */ +int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str) +{ + return mvaddstr(win->row_offset + row, win->col_offset + col, str); +} + +/** + * mutt_window_mvprintw - Move the cursor and write a formatted string to a Window + * @param win Window to write to + * @param row Row to move to + * @param col Column to move to + * @param fmt printf format string + * @param ... printf arguments + * @retval num Success, number of characters written + * @retval ERR Error, move failed + */ +int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt, ...) +{ + int rc = mutt_window_move(win, row, col); + if (rc == ERR) + return rc; + + va_list ap; + va_start(ap, fmt); + rc = vw_printw(stdscr, fmt, ap); + va_end(ap); + + return rc; +} + +/** + * mutt_window_reflow - Resize the Windows to fit the screen + */ +void mutt_window_reflow(void) +{ + if (OPT_NO_CURSES) + return; + + mutt_debug(2, "entering\n"); + + MuttStatusWindow->rows = 1; + MuttStatusWindow->cols = COLS; + MuttStatusWindow->row_offset = StatusOnTop ? 0 : LINES - 2; + MuttStatusWindow->col_offset = 0; + + memcpy(MuttHelpWindow, MuttStatusWindow, sizeof(struct MuttWindow)); + if (!Help) + MuttHelpWindow->rows = 0; + else + MuttHelpWindow->row_offset = StatusOnTop ? LINES - 2 : 0; + + memcpy(MuttMessageWindow, MuttStatusWindow, sizeof(struct MuttWindow)); + MuttMessageWindow->row_offset = LINES - 1; + + memcpy(MuttIndexWindow, MuttStatusWindow, sizeof(struct MuttWindow)); + MuttIndexWindow->rows = MAX( + LINES - MuttStatusWindow->rows - MuttHelpWindow->rows - MuttMessageWindow->rows, 0); + MuttIndexWindow->row_offset = + StatusOnTop ? MuttStatusWindow->rows : MuttHelpWindow->rows; + +#ifdef USE_SIDEBAR + if (SidebarVisible) + { + memcpy(MuttSidebarWindow, MuttIndexWindow, sizeof(struct MuttWindow)); + MuttSidebarWindow->cols = SidebarWidth; + MuttIndexWindow->cols -= SidebarWidth; + + if (SidebarOnRight) + { + MuttSidebarWindow->col_offset = COLS - SidebarWidth; + } + else + { + MuttIndexWindow->col_offset += SidebarWidth; + } + } +#endif + + mutt_menu_set_current_redraw_full(); + /* the pager menu needs this flag set to recalc line_info */ + mutt_menu_set_current_redraw(REDRAW_FLOW); +} + +/** + * mutt_window_reflow_message_rows - Resize the Message Window + * @param mw_rows Number of rows required + * + * Resize the other Windows to allow a multi-line message to be displayed. + */ +void mutt_window_reflow_message_rows(int mw_rows) +{ + MuttMessageWindow->rows = mw_rows; + MuttMessageWindow->row_offset = LINES - mw_rows; + + MuttStatusWindow->row_offset = StatusOnTop ? 0 : LINES - mw_rows - 1; + + if (Help) + MuttHelpWindow->row_offset = StatusOnTop ? LINES - mw_rows - 1 : 0; + + MuttIndexWindow->rows = MAX( + LINES - MuttStatusWindow->rows - MuttHelpWindow->rows - MuttMessageWindow->rows, 0); + +#ifdef USE_SIDEBAR + if (SidebarVisible) + MuttSidebarWindow->rows = MuttIndexWindow->rows; +#endif + + /* We don't also set REDRAW_FLOW because this function only + * changes rows and is a temporary adjustment. */ + mutt_menu_set_current_redraw_full(); +} + +/** + * mutt_window_wrap_cols - Calculate the wrap column for a Window + * + * The wrap variable can be negative, meaning there should be a right margin. + */ +int mutt_window_wrap_cols(struct MuttWindow *win, short wrap) +{ + if (wrap < 0) + return (win->cols > -wrap) ? (win->cols + wrap) : win->cols; + else if (wrap) + return (wrap < win->cols) ? wrap : win->cols; + else + return win->cols; +} diff --git a/mutt_window.h b/mutt_window.h new file mode 100644 index 000000000..51a6f2aa4 --- /dev/null +++ b/mutt_window.h @@ -0,0 +1,62 @@ +/** + * @file + * Window management + * + * @authors + * Copyright (C) 2018 Richard Russon + * + * @copyright + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef _MUTT_WINDOW_H +#define _MUTT_WINDOW_H + +#include "mutt_curses.h" + +/** + * struct MuttWindow - A division of the screen + * + * Windows for different parts of the screen + */ +struct MuttWindow +{ + int rows; + int cols; + int row_offset; + int col_offset; +}; + +extern struct MuttWindow *MuttHelpWindow; +extern struct MuttWindow *MuttIndexWindow; +extern struct MuttWindow *MuttMessageWindow; +#ifdef USE_SIDEBAR +extern struct MuttWindow *MuttSidebarWindow; +#endif +extern struct MuttWindow *MuttStatusWindow; + +void mutt_window_clearline(struct MuttWindow *win, int row); +void mutt_window_clrtoeol(struct MuttWindow *win); +void mutt_window_free(void); +void mutt_window_getxy(struct MuttWindow *win, int *x, int *y); +void mutt_window_init(void); +int mutt_window_move(struct MuttWindow *win, int row, int col); +int mutt_window_mvaddch(struct MuttWindow *win, int row, int col, const chtype ch); +int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str); +int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt, ...); +void mutt_window_reflow_message_rows(int mw_rows); +void mutt_window_reflow(void); +int mutt_window_wrap_cols(struct MuttWindow *win, short wrap); + +#endif /* _MUTT_WINDOW_H */ diff --git a/muttlib.c b/muttlib.c index c89ed506f..19ffd780f 100644 --- a/muttlib.c +++ b/muttlib.c @@ -51,6 +51,7 @@ #include "header.h" #include "mailbox.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "options.h" diff --git a/ncrypt/crypt_gpgme.c b/ncrypt/crypt_gpgme.c index 0c550d067..06cc5a938 100644 --- a/ncrypt/crypt_gpgme.c +++ b/ncrypt/crypt_gpgme.c @@ -54,6 +54,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "ncrypt.h" #include "opcodes.h" #include "options.h" diff --git a/ncrypt/pgpinvoke.c b/ncrypt/pgpinvoke.c index 6b4ebd02a..161559fd0 100644 --- a/ncrypt/pgpinvoke.c +++ b/ncrypt/pgpinvoke.c @@ -35,6 +35,7 @@ #include "format_flags.h" #include "globals.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "ncrypt.h" #include "pgp.h" #include "pgpkey.h" diff --git a/ncrypt/pgpkey.c b/ncrypt/pgpkey.c index dd05eed15..2fc30b04d 100644 --- a/ncrypt/pgpkey.c +++ b/ncrypt/pgpkey.c @@ -44,6 +44,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "ncrypt.h" #include "opcodes.h" #include "options.h" diff --git a/ncrypt/smime.c b/ncrypt/smime.c index 9761a56c0..6245c4547 100644 --- a/ncrypt/smime.c +++ b/ncrypt/smime.c @@ -45,6 +45,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "ncrypt.h" #include "opcodes.h" #include "options.h" diff --git a/newsrc.c b/newsrc.c index 0afb03176..f6aed9067 100644 --- a/newsrc.c +++ b/newsrc.c @@ -43,6 +43,7 @@ #include "mutt_account.h" #include "mutt_curses.h" #include "mutt_socket.h" +#include "mutt_window.h" #include "mx.h" #include "nntp.h" #include "options.h" diff --git a/pager.c b/pager.c index e819dec97..2daac8bda 100644 --- a/pager.c +++ b/pager.c @@ -47,6 +47,7 @@ #include "mailbox.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "opcodes.h" @@ -1774,7 +1775,7 @@ static void pager_menu_redraw(struct Menu *pager_menu) if (pager_menu->redraw & REDRAW_FULL) { - mutt_reflow_windows(); + mutt_window_reflow(); NORMAL_COLOR; /* clear() doesn't optimize screen redraws */ move(0, 0); @@ -2292,7 +2293,7 @@ int mutt_pager(const char *banner, const char *fname, int flags, struct Pager *e } else { - /* note: mutt_resize_screen() -> mutt_reflow_windows() sets + /* note: mutt_resize_screen() -> mutt_window_reflow() sets * REDRAW_FULL and REDRAW_FLOW */ ch = 0; } @@ -3237,7 +3238,7 @@ int mutt_pager(const char *banner, const char *fname, int flags, struct Pager *e case OP_SIDEBAR_TOGGLE_VISIBLE: SidebarVisible = !SidebarVisible; - mutt_reflow_windows(); + mutt_window_reflow(); break; #endif diff --git a/query.c b/query.c index faa6f64b5..189d4c1ec 100644 --- a/query.c +++ b/query.c @@ -38,6 +38,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "opcodes.h" #include "protos.h" diff --git a/recvattach.c b/recvattach.c index 3b89e483a..514c639cc 100644 --- a/recvattach.c +++ b/recvattach.c @@ -42,6 +42,7 @@ #include "mailbox.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "opcodes.h" diff --git a/recvcmd.c b/recvcmd.c index e7ff67647..45e42542b 100644 --- a/recvcmd.c +++ b/recvcmd.c @@ -35,6 +35,7 @@ #include "globals.h" #include "header.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "options.h" #include "protos.h" #include "state.h" diff --git a/remailer.c b/remailer.c index 3ec59e837..a9afcd83c 100644 --- a/remailer.c +++ b/remailer.c @@ -38,6 +38,7 @@ #include "keymap.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "opcodes.h" #include "options.h" #include "protos.h" diff --git a/resize.c b/resize.c index 96a963ab7..bf8cea2d0 100644 --- a/resize.c +++ b/resize.c @@ -27,6 +27,7 @@ #include #include "mutt/mutt.h" #include "mutt_curses.h" +#include "mutt_window.h" #ifdef HAVE_SYS_IOCTL_H #include #else @@ -80,5 +81,5 @@ void mutt_resize_screen(void) #else resizeterm(SLtt_Screen_Rows, SLtt_Screen_Cols); #endif - mutt_reflow_windows(); + mutt_window_reflow(); } diff --git a/rfc3676.c b/rfc3676.c index ec36d3160..32e6b3fa9 100644 --- a/rfc3676.c +++ b/rfc3676.c @@ -34,6 +34,7 @@ #include "globals.h" #include "header.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "options.h" #include "protos.h" #include "state.h" diff --git a/sendlib.c b/sendlib.c index fbfbbf9b8..dd082daf8 100644 --- a/sendlib.c +++ b/sendlib.c @@ -49,6 +49,7 @@ #include "header.h" #include "mailbox.h" #include "mutt_curses.h" +#include "mutt_window.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "options.h" diff --git a/sidebar.c b/sidebar.c index 5ef642a55..3567cac02 100644 --- a/sidebar.c +++ b/sidebar.c @@ -37,6 +37,7 @@ #include "globals.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "opcodes.h" #include "options.h" diff --git a/status.c b/status.c index 2ac69fb44..339c1f6bf 100644 --- a/status.c +++ b/status.c @@ -30,6 +30,7 @@ #include "mbtable.h" #include "mutt_curses.h" #include "mutt_menu.h" +#include "mutt_window.h" #include "mx.h" #include "options.h" #include "protos.h" -- 2.40.0