changeset: 6991:7f6ff45a7f59 user: Kevin McCarthy <ke...@8t8.us> date: Wed Apr 05 16:09:31 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/7f6ff45a7f59
Remove redraw flag setting after mutt_endwin(). There is no need to set a redraw flag in this case. The screen will automatically be properly redrawn on the next refresh(). Remove, lest it get propagated. changeset: 6992:231fa2eff206 user: Kevin McCarthy <ke...@8t8.us> date: Wed Apr 05 16:09:33 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/231fa2eff206 Change km_dokey() to pass SigWinch on for the MENU_EDITOR. (see #3877) Change _mutt_enter_string() to pass the SigWinch through for _mutt_get_field() or mutt_enter_string() to handle. Add a call to mutt_current_menu() in _mutt_get_field() to properly redisplay the screen in that case. changeset: 6993:c651b528f958 user: Kevin McCarthy <ke...@8t8.us> date: Wed Apr 05 16:09:34 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/c651b528f958 Separate out the compose menu redrawing. (see #3877) Add a custom_menu_redraw to the menu and change menu_redraw() to call that instead if set. changeset: 6994:178bd8b53cab user: Kevin McCarthy <ke...@8t8.us> date: Wed Apr 05 16:09:35 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/178bd8b53cab Separate out the index menu redrawing. (see #3877) changeset: 6995:dcc95921c3c5 user: Kevin McCarthy <ke...@8t8.us> date: Wed Apr 05 16:09:36 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/dcc95921c3c5 Prepare for pager redraw separation. (see #3877) Move some of the code inside SigWinch handling into the REDRAW part of the code. SigInt is handled by mutt_getch(), so remove the redundant code from inside the pager. changeset: 6996:86848e5932b0 user: Kevin McCarthy <ke...@8t8.us> date: Wed Apr 05 16:09:37 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/86848e5932b0 Separate out the pager menu redrawing. (see #3877) The pager relies on REDRAW_SIGWINCH, so add that to _mutt_get_field(). changeset: 6997:303fc058692f user: Kevin McCarthy <ke...@8t8.us> date: Wed Apr 05 16:09:39 2017 -0700 link: http://dev.mutt.org/hg/mutt/rev/303fc058692f Don't create query menu until after initial prompt. (see #3877) A resize in the prompt will trigger a redraw, but the data won't be loaded yet, displaying a blank screen instead of the previous menu. Once the query is done, the data is loaded, but the menu->redraw state has been changed by the resize. We could manually flag a redraw, but it makes more sense visually logically to just create the menu after the query and results are loaded. diffs (truncated from 1792 to 950 lines): diff -r 8b9bbd983b1a -r 303fc058692f compose.c --- a/compose.c Fri Mar 31 18:15:31 2017 -0700 +++ b/compose.c Wed Apr 05 16:09:39 2017 -0700 @@ -468,6 +468,54 @@ (unsigned long) menu, 0); } +typedef struct +{ + HEADER *msg; + char *fcc; +} compose_redraw_data_t; + +static void compose_menu_redraw (MUTTMENU *menu) +{ + char buf[LONG_STRING]; + compose_redraw_data_t *rd = menu->redraw_data; + + if (!rd) + return; + + if (menu->redraw & REDRAW_FULL) + { + menu_redraw_full (menu); + + draw_envelope (rd->msg, rd->fcc); + menu->offset = HDR_ATTACH; + menu->pagelen = MuttIndexWindow->rows - HDR_ATTACH; + } + + menu_check_recenter (menu); + + if (menu->redraw & REDRAW_STATUS) + { + compose_status_line (buf, sizeof (buf), 0, MuttStatusWindow->cols, menu, NONULL(ComposeFormat)); + mutt_window_move (MuttStatusWindow, 0, 0); + SETCOLOR (MT_COLOR_STATUS); + mutt_paddstr (MuttStatusWindow->cols, buf); + NORMAL_COLOR; + menu->redraw &= ~REDRAW_STATUS; + } + +#ifdef USE_SIDEBAR + if (menu->redraw & REDRAW_SIDEBAR) + menu_redraw_sidebar (menu); +#endif + + if (menu->redraw & REDRAW_INDEX) + menu_redraw_index (menu); + else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNCH)) + menu_redraw_motion (menu); + else if (menu->redraw == REDRAW_CURRENT) + menu_redraw_current (menu); +} + /* return values: * @@ -497,6 +545,10 @@ /* Sort, SortAux could be changed in mutt_index_menu() */ int oldSort, oldSortAux; struct stat st; + compose_redraw_data_t rd; + + rd.msg = msg; + rd.fcc = fcc; mutt_attach_init (msg->content); idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1); @@ -508,17 +560,14 @@ menu->tag = mutt_tag_attach; menu->data = idx; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_COMPOSE, ComposeHelp); + menu->custom_menu_redraw = compose_menu_redraw; + menu->redraw_data = &rd; mutt_push_current_menu (menu); while (loop) { switch (op = mutt_menuLoop (menu)) { - case OP_REDRAW: - draw_envelope (msg, fcc); - menu->offset = HDR_ATTACH; - menu->pagelen = MuttIndexWindow->rows - HDR_ATTACH; - break; case OP_COMPOSE_EDIT_FROM: edit_address_list (HDR_FROM, &msg->env->from); mutt_message_hook (NULL, msg, MUTT_SEND2HOOK); @@ -1320,17 +1369,6 @@ #endif } - - /* Draw formatted compose status line */ - if (menu->redraw & REDRAW_STATUS) - { - compose_status_line (buf, sizeof (buf), 0, MuttStatusWindow->cols, menu, NONULL(ComposeFormat)); - mutt_window_move (MuttStatusWindow, 0, 0); - SETCOLOR (MT_COLOR_STATUS); - mutt_paddstr (MuttStatusWindow->cols, buf); - NORMAL_COLOR; - menu->redraw &= ~REDRAW_STATUS; - } } mutt_pop_current_menu (menu); diff -r 8b9bbd983b1a -r 303fc058692f curs_lib.c --- a/curs_lib.c Fri Mar 31 18:15:31 2017 -0700 +++ b/curs_lib.c Wed Apr 05 16:09:39 2017 -0700 @@ -162,6 +162,16 @@ do { + if (SigWinch) + { + SigWinch = 0; + mutt_resize_screen (); + /* mutt_resize_screen sets REDRAW_FULL, but the pager also + * requires SIGWINCH. */ + mutt_set_current_menu_redraw (REDRAW_SIGWINCH); + clearok(stdscr, TRUE); + mutt_current_menu_redraw (); + } mutt_window_clearline (MuttMessageWindow, 0); SETCOLOR (MT_COLOR_PROMPT); addstr ((char *)field); /* cast to get around bad prototypes */ @@ -173,7 +183,7 @@ while (ret == 1); mutt_window_clearline (MuttMessageWindow, 0); mutt_free_enter_state (&es); - + return (ret); } diff -r 8b9bbd983b1a -r 303fc058692f curs_main.c --- a/curs_main.c Fri Mar 31 18:15:31 2017 -0700 +++ b/curs_main.c Wed Apr 05 16:09:39 2017 -0700 @@ -494,6 +494,59 @@ { NULL, 0 } }; +static void index_menu_redraw (MUTTMENU *menu) +{ + char buf[LONG_STRING]; + + if (menu->redraw & REDRAW_FULL) + { + menu_redraw_full (menu); + mutt_show_error (); + } + +#ifdef USE_SIDEBAR + if (menu->redraw & REDRAW_SIDEBAR) + { + mutt_sb_set_buffystats (Context); + menu_redraw_sidebar (menu); + } +#endif + + if (Context && Context->hdrs && !(menu->current >= Context->vcount)) + { + menu_check_recenter (menu); + + if (menu->redraw & REDRAW_INDEX) + { + menu_redraw_index (menu); + menu->redraw |= REDRAW_STATUS; + } + else if (menu->redraw & (REDRAW_MOTION_RESYNCH | REDRAW_MOTION)) + menu_redraw_motion (menu); + else if (menu->redraw & REDRAW_CURRENT) + menu_redraw_current (menu); + } + + if (menu->redraw & REDRAW_STATUS) + { + menu_status_line (buf, sizeof (buf), menu, NONULL (Status)); + mutt_window_move (MuttStatusWindow, 0, 0); + SETCOLOR (MT_COLOR_STATUS); + mutt_paddstr (MuttStatusWindow->cols, buf); + NORMAL_COLOR; + menu->redraw &= ~REDRAW_STATUS; + if (option(OPTTSENABLED) && TSSupported) + { + menu_status_line (buf, sizeof (buf), menu, NONULL (TSStatusFormat)); + mutt_ts_status(buf); + menu_status_line (buf, sizeof (buf), menu, NONULL (TSIconFormat)); + mutt_ts_icon(buf); + } + } + + menu->redraw = 0; +} + /* This function handles the message index window as well as commands returned * from the pager (MENU_PAGER). */ @@ -519,6 +572,7 @@ menu->color = index_color; menu->current = ci_first_message (); menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN, IndexHelp); + menu->custom_menu_redraw = index_menu_redraw; mutt_push_current_menu (menu); if (!attach_msg) @@ -615,63 +669,19 @@ if (menu->menu == MENU_MAIN) { - if (menu->redraw & REDRAW_FULL) - { - menu_redraw_full (menu); - mutt_show_error (); - } + index_menu_redraw (menu); -#ifdef USE_SIDEBAR - if (menu->redraw & REDRAW_SIDEBAR) - { - mutt_sb_set_buffystats (Context); - menu_redraw_sidebar (menu); - } -#endif - if (Context && Context->hdrs && !(menu->current >= Context->vcount)) - { - menu_check_recenter (menu); - - if (menu->redraw & REDRAW_INDEX) - { - menu_redraw_index (menu); - menu->redraw |= REDRAW_STATUS; - } - else if (menu->redraw & (REDRAW_MOTION_RESYNCH | REDRAW_MOTION)) - menu_redraw_motion (menu); - else if (menu->redraw & REDRAW_CURRENT) - menu_redraw_current (menu); - } - - if (menu->redraw & REDRAW_STATUS) - { - menu_status_line (buf, sizeof (buf), menu, NONULL (Status)); - mutt_window_move (MuttStatusWindow, 0, 0); - SETCOLOR (MT_COLOR_STATUS); - mutt_paddstr (MuttStatusWindow->cols, buf); - NORMAL_COLOR; - menu->redraw &= ~REDRAW_STATUS; - if (option(OPTTSENABLED) && TSSupported) - { - menu_status_line (buf, sizeof (buf), menu, NONULL (TSStatusFormat)); - mutt_ts_status(buf); - menu_status_line (buf, sizeof (buf), menu, NONULL (TSIconFormat)); - mutt_ts_icon(buf); - } - } - - menu->redraw = 0; if (menu->current < menu->max) - menu->oldcurrent = menu->current; + menu->oldcurrent = menu->current; else - menu->oldcurrent = -1; + menu->oldcurrent = -1; if (option (OPTARROWCURSOR)) - mutt_window_move (MuttIndexWindow, menu->current - menu->top + menu->offset, 2); + mutt_window_move (MuttIndexWindow, menu->current - menu->top + menu->offset, 2); else if (option (OPTBRAILLEFRIENDLY)) - mutt_window_move (MuttIndexWindow, menu->current - menu->top + menu->offset, 0); + mutt_window_move (MuttIndexWindow, menu->current - menu->top + menu->offset, 0); else - mutt_window_move (MuttIndexWindow, menu->current - menu->top + menu->offset, + mutt_window_move (MuttIndexWindow, menu->current - menu->top + menu->offset, MuttIndexWindow->cols - 1); mutt_refresh (); @@ -680,8 +690,6 @@ { mutt_flushinp (); mutt_resize_screen (); - menu->redraw = REDRAW_FULL; - menu->menu = MENU_MAIN; SigWinch = 0; menu->top = 0; /* so we scroll the right amount */ /* diff -r 8b9bbd983b1a -r 303fc058692f enter.c --- a/enter.c Fri Mar 31 18:15:31 2017 -0700 +++ b/enter.c Wed Apr 05 16:09:39 2017 -0700 @@ -203,22 +203,40 @@ return wcschr(shell_chars, ch) != NULL; } -/* +/* This function is for very basic input, currently used only by the + * built-in editor. It does not handle screen redrawing on resizes + * well, because there is no active menu for the built-in editor. + * Most callers should prefer mutt_get_field() instead. + * * Returns: - * 1 need to redraw the screen and call me again * 0 if input was given * -1 if abort. */ - int mutt_enter_string(char *buf, size_t buflen, int col, int flags) { int rv; ENTER_STATE *es = mutt_new_enter_state (); - rv = _mutt_enter_string (buf, buflen, col, flags, 0, NULL, NULL, es); + do + { + if (SigWinch) + { + SigWinch = 0; + mutt_resize_screen (); + clearok(stdscr, TRUE); + } + rv = _mutt_enter_string (buf, buflen, col, flags, 0, NULL, NULL, es); + } + while (rv == 1); mutt_free_enter_state (&es); return rv; } +/* + * Returns: + * 1 need to redraw the screen and call me again + * 0 if input was given + * -1 if abort. + */ int _mutt_enter_string (char *buf, size_t buflen, int col, int flags, int multiple, char ***files, int *numfiles, ENTER_STATE *state) @@ -297,7 +315,7 @@ if ((ch = km_dokey (MENU_EDITOR)) == -1) { - rv = -1; + rv = SigWinch ? 1 : -1; goto bye; } @@ -785,7 +803,7 @@ } bye: - + mutt_reset_history_state (hclass); FREE (&tempbuf); return rv; diff -r 8b9bbd983b1a -r 303fc058692f init.c --- a/init.c Fri Mar 31 18:15:31 2017 -0700 +++ b/init.c Wed Apr 05 16:09:39 2017 -0700 @@ -1291,8 +1291,6 @@ print_attach_list(AttachExclude, '-', "A"); print_attach_list(InlineAllow, '+', "I"); print_attach_list(InlineExclude, '-', "I"); - mutt_set_menu_redraw_full (MENU_MAIN); - mutt_set_menu_redraw_full (MENU_PAGER); mutt_any_key_to_continue (NULL); return 0; } @@ -1974,7 +1972,6 @@ if (found) { - mutt_set_current_menu_redraw_full (); mutt_any_key_to_continue (NULL); return 0; } diff -r 8b9bbd983b1a -r 303fc058692f keymap.c --- a/keymap.c Fri Mar 31 18:15:31 2017 -0700 +++ b/keymap.c Wed Apr 05 16:09:39 2017 -0700 @@ -464,8 +464,8 @@ #ifdef USE_IMAP gotkey: #endif - /* hide timeouts and window resizes from line editor. */ - if (menu == MENU_EDITOR && tmp.ch == -2) + /* hide timeouts, but not window resizes, from the line editor. */ + if (menu == MENU_EDITOR && tmp.ch == -2 && !SigWinch) continue; LastKey = tmp.ch; diff -r 8b9bbd983b1a -r 303fc058692f menu.c --- a/menu.c Fri Mar 31 18:15:31 2017 -0700 +++ b/menu.c Wed Apr 05 16:09:39 2017 -0700 @@ -798,6 +798,22 @@ mutt_set_current_menu_redraw_full (); } +void mutt_current_menu_redraw () +{ + MUTTMENU *current_menu; + + current_menu = get_current_menu (); + if (current_menu) + { + if (menu_redraw (current_menu) == OP_REDRAW) + /* On a REDRAW_FULL with a non-customized redraw, menu_redraw() + * will return OP_REDRAW to give the calling menu-loop a chance to + * customize output. + */ + menu_redraw (current_menu); + } +} + #define MUTT_SEARCH_UP 1 #define MUTT_SEARCH_DOWN 2 @@ -910,6 +926,12 @@ int menu_redraw (MUTTMENU *menu) { + if (menu->custom_menu_redraw) + { + menu->custom_menu_redraw (menu); + return OP_NULL; + } + /* See if all or part of the screen needs to be updated. */ if (menu->redraw & REDRAW_FULL) { @@ -1012,7 +1034,6 @@ if (SigWinch) { mutt_resize_screen (); - menu->redraw = REDRAW_FULL; SigWinch = 0; clearok(stdscr,TRUE);/*force complete redraw*/ } diff -r 8b9bbd983b1a -r 303fc058692f mutt_menu.h --- a/mutt_menu.h Fri Mar 31 18:15:31 2017 -0700 +++ b/mutt_menu.h Wed Apr 05 16:09:39 2017 -0700 @@ -75,6 +75,10 @@ int (*tag) (struct menu_t *, int i, int m); + /* these are used for custom redrawing callbacks */ + void (*custom_menu_redraw) (struct menu_t *); + void *redraw_data; + /* color pair to be used for the requested element * (default function returns ColorDefs[MT_COLOR_NORMAL]) */ @@ -125,6 +129,7 @@ void mutt_set_current_menu_redraw (int); void mutt_set_current_menu_redraw_full (); void mutt_set_menu_redraw_full (int); +void mutt_current_menu_redraw (void); int mutt_menuLoop (MUTTMENU *); /* used in both the index and pager index to make an entry. */ diff -r 8b9bbd983b1a -r 303fc058692f pager.c --- a/pager.c Fri Mar 31 18:15:31 2017 -0700 +++ b/pager.c Wed Apr 05 16:09:39 2017 -0700 @@ -1576,6 +1576,307 @@ OldHdr = NULL; } +typedef struct +{ + int flags; + pager_t *extra; + int indexlen; + int indicator; /* the indicator line of the PI */ + int oldtopline; + int lines; + int maxLine; + int lastLine; + int curline; + int topline; + int force_redraw; + int has_types; + int hideQuoted; + int q_level; + struct q_class_t *QuoteList; + LOFF_T last_pos; + LOFF_T last_offset; + mutt_window_t *index_status_window; + mutt_window_t *index_window; + mutt_window_t *pager_status_window; + mutt_window_t *pager_window; + MUTTMENU *index; /* the Pager Index (PI) */ + regex_t SearchRE; + int SearchCompiled; + int SearchFlag; + int SearchBack; + const char *banner; + char *helpstr; + char *searchbuf; + struct line_t *lineInfo; + FILE *fp; + struct stat sb; +} pager_redraw_data_t; + +static void pager_menu_redraw (MUTTMENU *pager_menu) +{ + pager_redraw_data_t *rd = pager_menu->redraw_data; + int i, j; + char buffer[LONG_STRING]; + + if (!rd) + return; + + if (pager_menu->redraw & REDRAW_FULL) + { +#if ! (defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM)) + mutt_reflow_windows (); +#endif + NORMAL_COLOR; + /* clear() doesn't optimize screen redraws */ + move (0, 0); + clrtobot (); + + if (IsHeader (rd->extra) && Context->vcount + 1 < PagerIndexLines) + rd->indexlen = Context->vcount + 1; + else + rd->indexlen = PagerIndexLines; + + rd->indicator = rd->indexlen / 3; + + memcpy (rd->pager_window, MuttIndexWindow, sizeof(mutt_window_t)); + memcpy (rd->pager_status_window, MuttStatusWindow, sizeof(mutt_window_t)); + rd->index_status_window->rows = rd->index_window->rows = 0; + + if (IsHeader (rd->extra) && PagerIndexLines) + { + memcpy (rd->index_window, MuttIndexWindow, sizeof(mutt_window_t)); + rd->index_window->rows = rd->indexlen > 0 ? rd->indexlen - 1 : 0; + + if (option (OPTSTATUSONTOP)) + { + memcpy (rd->index_status_window, MuttStatusWindow, sizeof(mutt_window_t)); + + memcpy (rd->pager_status_window, MuttIndexWindow, sizeof(mutt_window_t)); + rd->pager_status_window->rows = 1; + rd->pager_status_window->row_offset += rd->index_window->rows; + + rd->pager_window->rows -= rd->index_window->rows + rd->pager_status_window->rows; + rd->pager_window->row_offset += rd->index_window->rows + rd->pager_status_window->rows; + } + else + { + memcpy (rd->index_status_window, MuttIndexWindow, sizeof(mutt_window_t)); + rd->index_status_window->rows = 1; + rd->index_status_window->row_offset += rd->index_window->rows; + + rd->pager_window->rows -= rd->index_window->rows + rd->index_status_window->rows; + rd->pager_window->row_offset += rd->index_window->rows + rd->index_status_window->rows; + } + } + + if (option (OPTHELP)) + { + SETCOLOR (MT_COLOR_STATUS); + mutt_window_move (MuttHelpWindow, 0, 0); + mutt_paddstr (MuttHelpWindow->cols, rd->helpstr); + NORMAL_COLOR; + } + +#if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM) + if (Resize != NULL) + { + if ((rd->SearchCompiled = Resize->SearchCompiled)) + { + REGCOMP + (&rd->SearchRE, rd->searchbuf, REG_NEWLINE | mutt_which_case (rd->searchbuf)); + rd->SearchFlag = MUTT_SEARCH; + rd->SearchBack = Resize->SearchBack; + } + rd->lines = Resize->line; + pager_menu->redraw |= REDRAW_SIGWINCH; + + FREE (&Resize); + } +#endif + + if (IsHeader (rd->extra) && PagerIndexLines) + { + if (rd->index == NULL) + { + /* only allocate the space if/when we need the index. + Initialise the menu as per the main index */ + rd->index = mutt_new_menu(MENU_MAIN); + rd->index->make_entry = index_make_entry; + rd->index->color = index_color; + rd->index->max = Context->vcount; + rd->index->current = rd->extra->hdr->virtual; + rd->index->indexwin = rd->index_window; + rd->index->statuswin = rd->index_status_window; + } + + NORMAL_COLOR; + rd->index->pagelen = rd->index_window->rows;; + + /* some fudge to work out where abouts the indicator should go */ + if (rd->index->current - rd->indicator < 0) + rd->index->top = 0; + else if (rd->index->max - rd->index->current < rd->index->pagelen - rd->indicator) + rd->index->top = rd->index->max - rd->index->pagelen; + else + rd->index->top = rd->index->current - rd->indicator; + + menu_redraw_index(rd->index); + } + + pager_menu->redraw |= REDRAW_BODY | REDRAW_INDEX | REDRAW_STATUS; +#ifdef USE_SIDEBAR + pager_menu->redraw |= REDRAW_SIDEBAR; +#endif + mutt_show_error (); + } + + if (pager_menu->redraw & REDRAW_SIGWINCH) + { + if (!(rd->flags & MUTT_PAGER_RETWINCH)) + { + rd->lines = -1; + for (i = 0; i <= rd->topline; i++) + if (!rd->lineInfo[i].continuation) + rd->lines++; + for (i = 0; i < rd->maxLine; i++) + { + rd->lineInfo[i].offset = 0; + rd->lineInfo[i].type = -1; + rd->lineInfo[i].continuation = 0; + rd->lineInfo[i].chunks = 0; + rd->lineInfo[i].search_cnt = -1; + rd->lineInfo[i].quote = NULL; + + safe_realloc (&(rd->lineInfo[i].syntax), + sizeof (struct syntax_t)); + if (rd->SearchCompiled && rd->lineInfo[i].search) + FREE (&(rd->lineInfo[i].search)); + } + + rd->lastLine = 0; + rd->topline = 0; + } + i = -1; + j = -1; + while (display_line (rd->fp, &rd->last_pos, &rd->lineInfo, ++i, &rd->lastLine, &rd->maxLine, + rd->has_types | rd->SearchFlag | (rd->flags & MUTT_PAGER_NOWRAP), + &rd->QuoteList, &rd->q_level, &rd->force_redraw, + &rd->SearchRE, rd->pager_window) == 0) + if (!rd->lineInfo[i].continuation && ++j == rd->lines) + { + rd->topline = i; + if (!rd->SearchFlag) + break; + } + } + +#ifdef USE_SIDEBAR + if (pager_menu->redraw & REDRAW_SIDEBAR) + { + menu_redraw_sidebar (pager_menu); + } +#endif + + if ((pager_menu->redraw & REDRAW_BODY) || rd->topline != rd->oldtopline) + { + do + { + mutt_window_move (rd->pager_window, 0, 0); + rd->curline = rd->oldtopline = rd->topline; + rd->lines = 0; + rd->force_redraw = 0; + + while (rd->lines < rd->pager_window->rows && + rd->lineInfo[rd->curline].offset <= rd->sb.st_size - 1) + { + if (display_line (rd->fp, &rd->last_pos, &rd->lineInfo, rd->curline, &rd->lastLine, + &rd->maxLine, + (rd->flags & MUTT_DISPLAYFLAGS) | rd->hideQuoted | rd->SearchFlag | (rd->flags & MUTT_PAGER_NOWRAP), + &rd->QuoteList, &rd->q_level, &rd->force_redraw, &rd->SearchRE, + rd->pager_window) > 0) + rd->lines++; + rd->curline++; + mutt_window_move (rd->pager_window, rd->lines, 0); + } + rd->last_offset = rd->lineInfo[rd->curline].offset; + } while (rd->force_redraw); + + SETCOLOR (MT_COLOR_TILDE); + while (rd->lines < rd->pager_window->rows) + { + mutt_window_clrtoeol (rd->pager_window); + if (option (OPTTILDE)) + addch ('~'); + rd->lines++; + mutt_window_move (rd->pager_window, rd->lines, 0); + } + NORMAL_COLOR; + + /* We are going to update the pager status bar, so it isn't + * necessary to reset to normal color now. */ + + pager_menu->redraw |= REDRAW_STATUS; /* need to update the % seen */ + } + + if (pager_menu->redraw & REDRAW_STATUS) + { + struct hdr_format_info hfi; + char pager_progress_str[4]; + + hfi.ctx = Context; + hfi.pager_progress = pager_progress_str; + + if (rd->last_pos < rd->sb.st_size - 1) + snprintf(pager_progress_str, sizeof(pager_progress_str), OFF_T_FMT "%%", (100 * rd->last_offset / rd->sb.st_size)); + else + strfcpy(pager_progress_str, (rd->topline == 0) ? "all" : "end", sizeof(pager_progress_str)); + + /* print out the pager status bar */ + mutt_window_move (rd->pager_status_window, 0, 0); + SETCOLOR (MT_COLOR_STATUS); + + if (IsHeader (rd->extra) || IsMsgAttach (rd->extra)) + { + size_t l1 = rd->pager_status_window->cols * MB_LEN_MAX; + size_t l2 = sizeof (buffer); + hfi.hdr = (IsHeader (rd->extra)) ? rd->extra->hdr : rd->extra->bdy->hdr; + mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, rd->pager_status_window->cols, NONULL (PagerFmt), &hfi, MUTT_FORMAT_MAKEPRINT); + mutt_paddstr (rd->pager_status_window->cols, buffer); + } + else + { + char bn[STRING]; + snprintf (bn, sizeof (bn), "%s (%s)", rd->banner, pager_progress_str); + mutt_paddstr (rd->pager_status_window->cols, bn); + } + NORMAL_COLOR; + if (option(OPTTSENABLED) && TSSupported) + { + menu_status_line (buffer, sizeof (buffer), rd->index, NONULL (TSStatusFormat)); + mutt_ts_status(buffer); + menu_status_line (buffer, sizeof (buffer), rd->index, NONULL (TSIconFormat)); + mutt_ts_icon(buffer); + } + } + + if ((pager_menu->redraw & REDRAW_INDEX) && rd->index) + { + /* redraw the pager_index indicator, because the + * flags for this message might have changed. */ + if (rd->index_window->rows > 0) + menu_redraw_current (rd->index); + + /* print out the index status bar */ + menu_status_line (buffer, sizeof (buffer), rd->index, NONULL(Status)); + + mutt_window_move (rd->index_status_window, 0, 0); + SETCOLOR (MT_COLOR_STATUS); + mutt_paddstr (rd->index_status_window->cols, buffer); + NORMAL_COLOR; + } + + pager_menu->redraw = 0; +} /* This pager is actually not so simple as it once was. It now operates in two modes: one for viewing messages and the other for viewing help. These @@ -1589,45 +1890,40 @@ char buffer[LONG_STRING]; char helpstr[SHORT_STRING*2]; char tmphelp[SHORT_STRING*2]; - int maxLine, lastLine = 0; - struct line_t *lineInfo; - struct q_class_t *QuoteList = NULL; - int i, j, ch = 0, rc = -1, hideQuoted = 0, q_level = 0, force_redraw = 0; - int lines = 0, curline = 0, topline = 0, oldtopline = 0, err, first = 1; + int i, j, ch = 0, rc = -1; + int err, first = 1; int r = -1, wrapped = 0, searchctx = 0; - FILE *fp = NULL; - LOFF_T last_pos = 0, last_offset = 0; int old_smart_wrap, old_markers; - struct stat sb; - regex_t SearchRE; - int SearchCompiled = 0, SearchFlag = 0, SearchBack = 0; - int has_types = (IsHeader(extra) || (flags & MUTT_SHOWCOLOR)) ? MUTT_TYPES : 0; /* main message or rfc822 attachment */ - - mutt_window_t *index_status_window = NULL; - mutt_window_t *index_window = NULL; - mutt_window_t *pager_status_window = NULL; - mutt_window_t *pager_window = NULL; MUTTMENU *pager_menu = NULL; - MUTTMENU *index = NULL; /* the Pager Index (PI) */ - int indexlen = PagerIndexLines; /* indexlen not always == PIL */ - int indicator = indexlen / 3; /* the indicator line of the PI */ int old_PagerIndexLines; /* some people want to resize it * while inside the pager... */ + pager_redraw_data_t rd; + if (!(flags & MUTT_SHOWCOLOR)) flags |= MUTT_SHOWFLAT; - if ((fp = fopen (fname, "r")) == NULL) + memset (&rd, 0, sizeof (rd)); + rd.banner = banner; + rd.flags = flags; + rd.extra = extra; + rd.indexlen = PagerIndexLines; + rd.indicator = rd.indexlen / 3; + rd.helpstr = helpstr; + rd.searchbuf = searchbuf; + rd.has_types = (IsHeader(extra) || (flags & MUTT_SHOWCOLOR)) ? MUTT_TYPES : 0; /* main message or rfc822 attachment */ + + if ((rd.fp = fopen (fname, "r")) == NULL) { mutt_perror (fname); return (-1); } - if (stat (fname, &sb) != 0) + if (stat (fname, &rd.sb) != 0) { mutt_perror (fname); - safe_fclose (&fp); + safe_fclose (&rd.fp); return (-1); } unlink (fname); @@ -1640,14 +1936,14 @@ mutt_set_flag (Context, extra->hdr, MUTT_READ, 1); } - lineInfo = safe_malloc (sizeof (struct line_t) * (maxLine = LINES)); - for (i = 0 ; i < maxLine ; i++) + rd.lineInfo = safe_malloc (sizeof (struct line_t) * (rd.maxLine = LINES)); + for (i = 0 ; i < rd.maxLine ; i++) { - memset (&lineInfo[i], 0, sizeof (struct line_t)); - lineInfo[i].type = -1; - lineInfo[i].search_cnt = -1; - lineInfo[i].syntax = safe_malloc (sizeof (struct syntax_t)); - (lineInfo[i].syntax)[0].first = (lineInfo[i].syntax)[0].last = -1; + memset (&rd.lineInfo[i], 0, sizeof (struct line_t)); + rd.lineInfo[i].type = -1; + rd.lineInfo[i].search_cnt = -1; + rd.lineInfo[i].syntax = safe_malloc (sizeof (struct syntax_t)); + (rd.lineInfo[i].syntax)[0].first = (rd.lineInfo[i].syntax)[0].last = -1; } mutt_compile_help (helpstr, sizeof (helpstr), MENU_PAGER, PagerHelp); @@ -1664,246 +1960,21 @@ snprintf (helpstr, sizeof (helpstr), "%s %s", tmphelp, buffer); } - index_status_window = safe_calloc (sizeof (mutt_window_t), 1); - index_window = safe_calloc (sizeof (mutt_window_t), 1); - pager_status_window = safe_calloc (sizeof (mutt_window_t), 1); - pager_window = safe_calloc (sizeof (mutt_window_t), 1); + rd.index_status_window = safe_calloc (sizeof (mutt_window_t), 1); + rd.index_window = safe_calloc (sizeof (mutt_window_t), 1); + rd.pager_status_window = safe_calloc (sizeof (mutt_window_t), 1); + rd.pager_window = safe_calloc (sizeof (mutt_window_t), 1); pager_menu = mutt_new_menu (MENU_PAGER); + pager_menu->custom_menu_redraw = pager_menu_redraw; + pager_menu->redraw_data = &rd; mutt_push_current_menu (pager_menu); while (ch != -1) { mutt_curs_set (0); - if (pager_menu->redraw & REDRAW_FULL) - { -#if ! (defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM)) - mutt_reflow_windows (); -#endif - NORMAL_COLOR; - /* clear() doesn't optimize screen redraws */ - move (0, 0); - clrtobot (); - - if (IsHeader (extra) && Context->vcount + 1 < PagerIndexLines) - indexlen = Context->vcount + 1; - else - indexlen = PagerIndexLines; - - indicator = indexlen / 3; - - memcpy (pager_window, MuttIndexWindow, sizeof(mutt_window_t)); - memcpy (pager_status_window, MuttStatusWindow, sizeof(mutt_window_t)); - index_status_window->rows = index_window->rows = 0; - - if (IsHeader (extra) && PagerIndexLines) - { - memcpy (index_window, MuttIndexWindow, sizeof(mutt_window_t)); - index_window->rows = indexlen > 0 ? indexlen - 1 : 0; - - if (option (OPTSTATUSONTOP)) - { - memcpy (index_status_window, MuttStatusWindow, sizeof(mutt_window_t)); - - memcpy (pager_status_window, MuttIndexWindow, sizeof(mutt_window_t)); - pager_status_window->rows = 1; - pager_status_window->row_offset += index_window->rows; - - pager_window->rows -= index_window->rows + pager_status_window->rows; - pager_window->row_offset += index_window->rows + pager_status_window->rows; - } - else - { - memcpy (index_status_window, MuttIndexWindow, sizeof(mutt_window_t)); - index_status_window->rows = 1; - index_status_window->row_offset += index_window->rows; - - pager_window->rows -= index_window->rows + index_status_window->rows; - pager_window->row_offset += index_window->rows + index_status_window->rows; - } - } - - if (option (OPTHELP)) - { - SETCOLOR (MT_COLOR_STATUS); - mutt_window_move (MuttHelpWindow, 0, 0); - mutt_paddstr (MuttHelpWindow->cols, helpstr); - NORMAL_COLOR; - } - -#if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM) - if (Resize != NULL) - { - if ((SearchCompiled = Resize->SearchCompiled)) - { - REGCOMP - (&SearchRE, searchbuf, REG_NEWLINE | mutt_which_case (searchbuf)); - SearchFlag = MUTT_SEARCH; - SearchBack = Resize->SearchBack; - } - lines = Resize->line; - pager_menu->redraw |= REDRAW_SIGWINCH; - - FREE (&Resize); - } -#endif - - if (IsHeader (extra) && PagerIndexLines) - { - if (index == NULL) - {