NeoMutt  2025-12-11-769-g906513
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
curs_lib.h File Reference

GUI miscellaneous curses (window drawing) routines. More...

#include <stdbool.h>
#include <stddef.h>
#include "browser/lib.h"
+ Include dependency graph for curs_lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  FileCompletionData
 Input for the file completion function. More...
 

Functions

int mutt_addwch (struct MuttWindow *win, wchar_t wc)
 Addwch would be provided by an up-to-date curses library.
 
int mutt_any_key_to_continue (const char *s)
 Prompt the user to 'press any key' and wait.
 
void mutt_beep (bool force)
 Irritate the user.
 
int mw_enter_fname (const char *prompt, struct Buffer *fname, bool mailbox, struct Mailbox *m, bool multiple, char ***files, int *numfiles, SelectFileFlags flags)
 Ask the user to select a file -.
 
void mutt_edit_file (const char *editor, const char *file)
 Let the user edit a file.
 
void mutt_endwin (void)
 Shutdown curses.
 
void mutt_need_hard_redraw (void)
 Force a hard refresh.
 
void mutt_paddstr (struct MuttWindow *win, int n, const char *s)
 Display a string on screen, padded if necessary.
 
void mutt_query_exit (void)
 Ask the user if they want to leave NeoMutt.
 
void mutt_refresh (void)
 Force a refresh of the screen.
 
char * mutt_str_expand_tabs (char *str, size_t *len, int tabwidth)
 Convert tabs to spaces in a string.
 
size_t mutt_strwidth (const char *s)
 Measure a string's width in screen cells.
 
size_t mutt_strnwidth (const char *s, size_t len)
 Measure a string's width in screen cells.
 
size_t mutt_wstr_trunc (const char *src, size_t maxlen, size_t maxwid, size_t *width)
 Work out how to truncate a widechar string.
 
void mw_what_key (void)
 Display the value of a key -.
 

Detailed Description

GUI miscellaneous curses (window drawing) routines.

Authors
  • Richard Russon
  • Pietro Cerutti

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 http://www.gnu.org/licenses/.

Definition in file curs_lib.h.

Function Documentation

◆ mutt_addwch()

int mutt_addwch ( struct MuttWindow * win,
wchar_t wc )

Addwch would be provided by an up-to-date curses library.

Parameters
winWindow
wcWide char to display
Return values
0Success
-1Error

Definition at line 321 of file curs_lib.c.

322{
323 char buf[MB_LEN_MAX * 2];
324 mbstate_t mbstate = { 0 };
325 size_t n1, n2;
326
327 if (((n1 = wcrtomb(buf, wc, &mbstate)) == ICONV_ILLEGAL_SEQ) ||
328 ((n2 = wcrtomb(buf + n1, 0, &mbstate)) == ICONV_ILLEGAL_SEQ))
329 {
330 return -1; /* ERR */
331 }
332 else
333 {
334 return mutt_window_addstr(win, buf);
335 }
336}
#define ICONV_ILLEGAL_SEQ
Error value for iconv() - Illegal sequence.
Definition charset.h:114
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_any_key_to_continue()

int mutt_any_key_to_continue ( const char * s)

Prompt the user to 'press any key' and wait.

Parameters
sMessage prompt
Return values
numKey pressed
EOFError, or prompt aborted

Definition at line 175 of file curs_lib.c.

176{
177 struct termios term = { 0 };
178 struct termios old = { 0 };
179
180 int fd = open("/dev/tty", O_RDONLY);
181 if (fd < 0)
182 return EOF;
183
184 tcgetattr(fd, &old); // Save the current tty settings
185
186 term = old;
187 term.c_lflag &= ~(ICANON | ECHO); // Canonical (not line-buffered), don't echo the characters
188 term.c_cc[VMIN] = 1; // Wait for at least one character
189 term.c_cc[VTIME] = 255; // Wait for 25.5s
190 tcsetattr(fd, TCSANOW, &term);
191
192 if (s)
193 fputs(s, stdout);
194 else
195 fputs(_("Press any key to continue..."), stdout);
196 fflush(stdout);
197
198 char ch = '\0';
199 // Wait for a character. This might timeout, so loop.
200 while (read(fd, &ch, 1) == 0)
201 ; // do nothing
202
203 // Change the tty settings to be non-blocking
204 term.c_cc[VMIN] = 0; // Returning with zero characters is acceptable
205 term.c_cc[VTIME] = 0; // Don't wait
206 tcsetattr(fd, TCSANOW, &term);
207
208 char buf[64] = { 0 };
209 while (read(fd, buf, sizeof(buf)) > 0)
210 ; // Mop up any remaining chars
211
212 tcsetattr(fd, TCSANOW, &old); // Restore the previous tty settings
213 close(fd);
214
215 fputs("\r\n", stdout);
217 return (ch >= 0) ? ch : EOF;
218}
#define _(a)
Definition message.h:28
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_beep()

void mutt_beep ( bool force)

Irritate the user.

Parameters
forceIf true, ignore the "$beep" config variable

Definition at line 69 of file curs_lib.c.

70{
71 const bool c_beep = cs_subset_bool(NeoMutt->sub, "beep");
72 if (force || c_beep)
73 beep();
74}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_edit_file()

void mutt_edit_file ( const char * editor,
const char * file )

Let the user edit a file.

Parameters
editorUser's editor config
fileFile to edit

Definition at line 118 of file curs_lib.c.

119{
120 struct Buffer *cmd = buf_pool_get();
121
122 mutt_endwin();
123 buf_file_expand_fmt_quote(cmd, editor, file);
124 if (mutt_system(buf_string(cmd)) != 0)
125 {
126 mutt_error(_("Error running \"%s\""), buf_string(cmd));
127 }
128 /* the terminal may have been resized while the editor owned it */
130
131 buf_pool_release(&cmd);
132}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
void mutt_endwin(void)
Shutdown curses.
Definition curs_lib.c:153
void buf_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition file.c:1351
#define mutt_error(...)
Definition logging2.h:94
int mutt_system(const char *cmd)
Run an external command.
Definition system.c:51
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size.
Definition resize.c:76
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_endwin()

void mutt_endwin ( void )

Shutdown curses.

Definition at line 153 of file curs_lib.c.

154{
155 if (!OptGui)
156 return;
157
158 int e = errno;
159
160 /* at least in some situations (screen + xterm under SuSE11/12) endwin()
161 * doesn't properly flush the screen without an explicit call. */
162 mutt_refresh();
163 endwin();
164 SigWinch = true;
165
166 errno = e;
167}
void mutt_refresh(void)
Force a refresh of the screen.
Definition curs_lib.c:79
bool OptGui
(pseudo) when the gui (and curses) are started
Definition globals.c:48
volatile sig_atomic_t SigWinch
true after SIGWINCH is received
Definition signal.c:69
int endwin(void)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_need_hard_redraw()

void mutt_need_hard_redraw ( void )

Force a hard refresh.

Make sure that the next refresh does a full refresh. This could be optimized by not doing it at all if DISPLAY is set as this might indicate that a GUI based pinentry was used. Having an option to customize this is of course the NeoMutt way.

Definition at line 102 of file curs_lib.c.

103{
104 // Forcibly switch to the alternate screen.
105 // Using encryption can leave ncurses confused about which mode it's in.
106 fputs("\033[?1049h", stdout);
107 fflush(stdout);
108 keypad(stdscr, true);
109 clearok(stdscr, true);
110 window_redraw(NULL);
111}
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_paddstr()

void mutt_paddstr ( struct MuttWindow * win,
int n,
const char * s )

Display a string on screen, padded if necessary.

Parameters
winWindow
nFinal width of field
sString to display

Definition at line 344 of file curs_lib.c.

345{
346 wchar_t wc = 0;
347 size_t k;
348 size_t len = mutt_str_len(s);
349 mbstate_t mbstate = { 0 };
350
351 for (; len && (k = mbrtowc(&wc, s, len, &mbstate)); s += k, len -= k)
352 {
353 if ((k == ICONV_ILLEGAL_SEQ) || (k == ICONV_BUF_TOO_SMALL))
354 {
355 if (k == ICONV_ILLEGAL_SEQ)
356 memset(&mbstate, 0, sizeof(mbstate));
357 k = (k == ICONV_ILLEGAL_SEQ) ? 1 : len;
358 wc = ReplacementChar;
359 }
360 if (!IsWPrint(wc))
361 wc = '?';
362 const int w = wcwidth(wc);
363 if (w >= 0)
364 {
365 if (w > n)
366 break;
367 mutt_addwch(win, wc);
368 n -= w;
369 }
370 }
371 while (n-- > 0)
372 mutt_window_addch(win, ' ');
373}
int mutt_addwch(struct MuttWindow *win, wchar_t wc)
Addwch would be provided by an up-to-date curses library.
Definition curs_lib.c:321
#define IsWPrint(wc)
Definition mbyte.h:40
wchar_t ReplacementChar
When a Unicode character can't be displayed, use this instead.
Definition charset.c:61
#define ICONV_BUF_TOO_SMALL
Error value for iconv() - Buffer too small.
Definition charset.h:116
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_query_exit()

void mutt_query_exit ( void )

Ask the user if they want to leave NeoMutt.

This function is called when the user presses the abort key.

Definition at line 139 of file curs_lib.c.

140{
142 if (query_yesorno(_("Exit NeoMutt without saving?"), MUTT_YES) == MUTT_YES)
143 {
144 mutt_exit(0); /* This call never returns */
145 }
147 SigInt = false;
148}
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition exit.c:41
void mutt_flushinp(void)
MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
Definition get.c:60
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition quad.h:39
enum QuadOption query_yesorno(const char *prompt, enum QuadOption def)
Ask the user a Yes/No question.
Definition question.c:329
volatile sig_atomic_t SigInt
true after SIGINT is received
Definition signal.c:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_refresh()

void mutt_refresh ( void )

Force a refresh of the screen.

Definition at line 79 of file curs_lib.c.

80{
81 /* don't refresh when we are waiting for a child. */
82 if (OptKeepQuiet)
83 return;
84
85 /* don't refresh in the middle of macros unless necessary */
87 if (!ARRAY_EMPTY(&key_mod_data->macro_events) && !OptForceRefresh)
88 return;
89
90 /* else */
91 refresh();
92}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program
Definition globals.c:49
bool OptForceRefresh
(pseudo) refresh even during macros
Definition globals.c:47
@ MODULE_ID_KEY
ModuleKey, Key mappings
Definition module_api.h:73
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:665
Key private Module data.
Definition module_data.h:34
struct KeyEventArray macro_events
Macro event buffer.
Definition module_data.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_str_expand_tabs()

char * mutt_str_expand_tabs ( char * str,
size_t * len,
int tabwidth )

Convert tabs to spaces in a string.

Parameters
strInput string
lenLength of the string
tabwidthThe number of spaces per indentation-level

Replace tab characters (\t) with spaces in the string. The string will be resized to fit the expanded version if necessary.

Definition at line 597 of file curs_lib.c.

598{
599 if (!str || !len || (tabwidth < 1))
600 return NULL;
601
602 // calculate how much space we need
603 size_t required_len = 0;
604 for (int i = 0; (i < *len) && (str[i] != '\0'); i++)
605 {
606 if (str[i] == '\t')
607 required_len += tabwidth; // cheat, just assume full tab width
608 else
609 required_len++;
610 }
611
612 // resize the string if there isn't enough space
613 while (required_len > *len)
614 {
615 *len += 256;
616 MUTT_MEM_REALLOC(&str, *len, char);
617 }
618
619 // expand tabs
620 for (int i = 0; str[i] != '\0'; i++)
621 {
622 if (str[i] == '\t')
623 {
624 int num_cells = mutt_strnwidth(str, i);
625 int indent = abs((num_cells % tabwidth) - tabwidth);
626 memmove(str + i + indent, str + i + 1, *len - (i + indent) - indent);
627 memset(str + i, ' ', indent);
628 }
629 }
630
631 return str;
632}
size_t mutt_strnwidth(const char *s, size_t n)
Measure a string's width in screen cells.
Definition curs_lib.c:459
#define MUTT_MEM_REALLOC(pptr, n, type)
Definition memory.h:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_strwidth()

size_t mutt_strwidth ( const char * s)

Measure a string's width in screen cells.

Parameters
sString to be measured
Return values
numScreen cells string would use

Definition at line 446 of file curs_lib.c.

447{
448 if (!s)
449 return 0;
450 return mutt_strnwidth(s, mutt_str_len(s));
451}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_strnwidth()

size_t mutt_strnwidth ( const char * s,
size_t n )

Measure a string's width in screen cells.

Parameters
sString to be measured
nLength of string to be measured
Return values
numScreen cells string would use

Definition at line 459 of file curs_lib.c.

460{
461 if (!s)
462 return 0;
463
464 wchar_t wc = 0;
465 int w;
466 size_t k;
467 mbstate_t mbstate = { 0 };
468
469 for (w = 0; n && (k = mbrtowc(&wc, s, n, &mbstate)); s += k, n -= k)
470 {
471 if (*s == MUTT_SPECIAL_INDEX)
472 {
473 if (n < 2)
474 break;
475 s += 2; /* skip the index coloring sequence */
476 n -= 2;
477 k = 0;
478 continue;
479 }
480
481 if ((k == ICONV_ILLEGAL_SEQ) || (k == ICONV_BUF_TOO_SMALL))
482 {
483 if (k == ICONV_ILLEGAL_SEQ)
484 memset(&mbstate, 0, sizeof(mbstate));
485 k = (k == ICONV_ILLEGAL_SEQ) ? 1 : n;
486 wc = ReplacementChar;
487 }
488 if (!IsWPrint(wc))
489 wc = '?';
490 w += wcwidth(wc);
491 }
492 return w;
493}
@ MUTT_SPECIAL_INDEX
Colour indicator.
Definition thread.h:72
+ Here is the caller graph for this function:

◆ mutt_wstr_trunc()

size_t mutt_wstr_trunc ( const char * src,
size_t maxlen,
size_t maxwid,
size_t * width )

Work out how to truncate a widechar string.

Parameters
[in]srcString to measure
[in]maxlenMaximum length of string in bytes
[in]maxwidMaximum width in screen columns
[out]widthSave the truncated screen column width
Return values
numBytes to use

See how many bytes to copy from string so it's at most maxlen bytes long and maxwid columns wide

Definition at line 386 of file curs_lib.c.

387{
388 wchar_t wc = 0;
389 size_t n, w = 0, l = 0, cl;
390 int cw;
391 mbstate_t mbstate = { 0 };
392
393 if (!src)
394 goto out;
395
396 n = mutt_str_len(src);
397
398 for (w = 0; n && (cl = mbrtowc(&wc, src, n, &mbstate)); src += cl, n -= cl)
399 {
400 if (cl == ICONV_ILLEGAL_SEQ)
401 {
402 memset(&mbstate, 0, sizeof(mbstate));
403 cl = 1;
404 wc = ReplacementChar;
405 }
406 else if (cl == ICONV_BUF_TOO_SMALL)
407 {
408 cl = n;
409 wc = ReplacementChar;
410 }
411
412 cw = wcwidth(wc);
413 /* hack because MUTT_TREE symbols aren't turned into characters
414 * until rendered by print_enriched_string() */
415 if ((cw < 0) && (src[0] == MUTT_SPECIAL_INDEX))
416 {
417 cl = 2; /* skip the index coloring sequence */
418 cw = 0;
419 }
420 else if ((cw < 0) && (cl == 1) && (src[0] != '\0') && (src[0] < MUTT_TREE_MAX))
421 {
422 cw = 1;
423 }
424 else if (cw < 0)
425 {
426 cw = 0; /* unprintable wchar */
427 }
428 if (wc == '\n')
429 break;
430 if (((cl + l) > maxlen) || ((cw + w) > maxwid))
431 break;
432 l += cl;
433 w += cw;
434 }
435out:
436 if (width)
437 *width = w;
438 return l;
439}
@ MUTT_TREE_MAX
Definition thread.h:70
+ Here is the call graph for this function:
+ Here is the caller graph for this function: