NeoMutt  2025-01-09-117-gace867
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 "key/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_flushinp (void)
 Empty all the keyboard buffers.
 
struct KeyEvent mutt_getch (GetChFlags flags)
 Read a character from the input buffer.
 
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_push_macro_event (int ch, int op)
 Add the character/operation to the macro buffer.
 
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.
 
void mutt_unget_ch (int ch)
 Return a keystroke to the input buffer.
 
void mutt_unget_op (int op)
 Return an operation to the input buffer.
 
void mutt_unget_string (const char *s)
 Return a string to the input buffer.
 
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 320 of file curs_lib.c.

321{
322 char buf[MB_LEN_MAX * 2];
323 mbstate_t mbstate = { 0 };
324 size_t n1, n2;
325
326 if (((n1 = wcrtomb(buf, wc, &mbstate)) == ICONV_ILLEGAL_SEQ) ||
327 ((n2 = wcrtomb(buf + n1, 0, &mbstate)) == ICONV_ILLEGAL_SEQ))
328 {
329 return -1; /* ERR */
330 }
331 else
332 {
333 return mutt_window_addstr(win, buf);
334 }
335}
#define ICONV_ILLEGAL_SEQ
Error value for iconv() - Illegal sequence.
Definition: charset.h:96
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:381
+ 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 174 of file curs_lib.c.

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

118{
119 struct Buffer *cmd = buf_pool_get();
120
121 mutt_endwin();
122 buf_file_expand_fmt_quote(cmd, editor, file);
123 if (mutt_system(buf_string(cmd)) != 0)
124 {
125 mutt_error(_("Error running \"%s\""), buf_string(cmd));
126 }
127 /* the terminal may have been resized while the editor owned it */
129
130 buf_pool_release(&cmd);
131}
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:152
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:1349
#define mutt_error(...)
Definition: logging2.h:93
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:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
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 152 of file curs_lib.c.

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

◆ mutt_flushinp()

void mutt_flushinp ( void  )

Empty all the keyboard buffers.

Definition at line 58 of file get.c.

59{
62 flushinp();
63}
#define ARRAY_SHRINK(head, num)
Mark a number of slots at the end of the array as unused.
Definition: array.h:172
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:87
struct KeyEventArray MacroEvents
These are used for macros and exec/push commands.
Definition: get.c:49
static struct KeyEventArray UngetKeyEvents
These are used in all other "normal" situations, and are not ignored when passing GETCH_IGNORE_MACRO.
Definition: get.c:53
+ Here is the caller graph for this function:

◆ mutt_getch()

struct KeyEvent mutt_getch ( GetChFlags  flags)

Read a character from the input buffer.

Parameters
flagsFlags, e.g. GETCH_IGNORE_MACRO
Return values
objKeyEvent to process

The priority for reading events is:

  1. UngetKeyEvents buffer
  2. MacroEvents buffer
  3. Keyboard

This function can return:

  • Abort { 0, OP_ABORT }
  • Repaint { 0, OP_REPAINT }
  • Timeout { 0, OP_TIMEOUT }

Definition at line 210 of file get.c.

211{
212 static const struct KeyEvent event_abort = { 0, OP_ABORT };
213 static const struct KeyEvent event_repaint = { 0, OP_REPAINT };
214 static const struct KeyEvent event_timeout = { 0, OP_TIMEOUT };
215
216 if (OptNoCurses)
217 return event_abort;
218
219 struct KeyEvent *event_key = array_pop(&UngetKeyEvents);
220 if (event_key)
221 return *event_key;
222
223 if (!(flags & GETCH_IGNORE_MACRO))
224 {
225 event_key = array_pop(&MacroEvents);
226 if (event_key)
227 return *event_key;
228 }
229
230 int ch;
231 SigInt = false;
233 timeout(1000); // 1 second
234#ifdef USE_INOTIFY
236#else
237 ch = getch();
238#endif
240
241 if (SigInt)
242 {
244 return event_abort;
245 }
246
247 if (ch == KEY_RESIZE)
248 {
249 timeout(0);
250 while ((ch = getch()) == KEY_RESIZE)
251 {
252 // do nothing
253 }
254 }
255
256 if (ch == ERR)
257 {
258 if (!isatty(STDIN_FILENO)) // terminal was lost
259 mutt_exit(1);
260
261 if (SigWinch)
262 {
263 SigWinch = false;
265 return event_repaint;
266 }
267
269 return event_timeout;
270 }
271
272 if (ch == AbortKey)
273 return event_abort;
274
275 if (ch & 0x80)
276 {
277 const bool c_meta_key = cs_subset_bool(NeoMutt->sub, "meta_key");
278 if (c_meta_key)
279 {
280 /* send ALT-x as ESC-x */
281 ch &= ~0x80;
283 return (struct KeyEvent) { '\033', OP_NULL }; // Escape
284 }
285 }
286
287 return (struct KeyEvent) { ch, OP_NULL };
288}
void mutt_query_exit(void)
Ask the user if they want to leave NeoMutt.
Definition: curs_lib.c:138
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: exit.c:41
static struct KeyEvent * array_pop(struct KeyEventArray *a)
Remove an event from the array.
Definition: get.c:70
static int mutt_monitor_getch(void)
Get a character and poll the filesystem monitor.
Definition: get.c:177
void mutt_unget_ch(int ch)
Return a keystroke to the input buffer.
Definition: get.c:115
keycode_t AbortKey
code of key to abort prompts, normally Ctrl-G
Definition: lib.c:121
#define GETCH_IGNORE_MACRO
Don't use MacroEvents.
Definition: lib.h:53
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:173
@ NT_TIMEOUT
Timeout has occurred.
Definition: notify_type.h:56
@ NT_RESIZE
Window has been resized.
Definition: notify_type.h:52
#define OP_TIMEOUT
1 second with no events
Definition: opcodes.h:36
#define OP_REPAINT
Repaint is needed.
Definition: opcodes.h:34
#define OP_ABORT
$abort_key pressed (Ctrl-G)
Definition: opcodes.h:37
volatile sig_atomic_t SigInt
true after SIGINT is received
Definition: signal.c:69
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:316
An event such as a keypress.
Definition: lib.h:81
int ch
Raw key pressed.
Definition: lib.h:82
struct Notify * notify_timeout
Timeout notifications handler.
Definition: neomutt.h:46
struct Notify * notify_resize
Window resize notifications handler.
Definition: neomutt.h:45
+ 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 101 of file curs_lib.c.

102{
103 // Forcibly switch to the alternate screen.
104 // Using encryption can leave ncurses confused about which mode it's in.
105 fputs("\033[?1049h", stdout);
106 fflush(stdout);
107 keypad(stdscr, true);
108 clearok(stdscr, true);
109 window_redraw(NULL);
110}
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:599
+ 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 343 of file curs_lib.c.

344{
345 wchar_t wc = 0;
346 size_t k;
347 size_t len = mutt_str_len(s);
348 mbstate_t mbstate = { 0 };
349
350 for (; len && (k = mbrtowc(&wc, s, len, &mbstate)); s += k, len -= k)
351 {
352 if ((k == ICONV_ILLEGAL_SEQ) || (k == ICONV_BUF_TOO_SMALL))
353 {
354 if (k == ICONV_ILLEGAL_SEQ)
355 memset(&mbstate, 0, sizeof(mbstate));
356 k = (k == ICONV_ILLEGAL_SEQ) ? 1 : len;
357 wc = ReplacementChar;
358 }
359 if (!IsWPrint(wc))
360 wc = '?';
361 const int w = wcwidth(wc);
362 if (w >= 0)
363 {
364 if (w > n)
365 break;
366 mutt_addwch(win, wc);
367 n -= w;
368 }
369 }
370 while (n-- > 0)
371 mutt_window_addch(win, ' ');
372}
int mutt_addwch(struct MuttWindow *win, wchar_t wc)
Addwch would be provided by an up-to-date curses library.
Definition: curs_lib.c:320
#define IsWPrint(wc)
Definition: mbyte.h:41
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:98
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:497
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:353
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_push_macro_event()

void mutt_push_macro_event ( int  ch,
int  op 
)

Add the character/operation to the macro buffer.

Parameters
chCharacter to add
opOperation to add

Adds the ch/op to the macro buffer. This should be used for macros, push, and exec commands only.

Definition at line 155 of file get.c.

156{
157 array_add(&MacroEvents, ch, op);
158}
static void array_add(struct KeyEventArray *a, int ch, int op)
Add an event to the end of the array.
Definition: get.c:88
+ 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 138 of file curs_lib.c.

139{
141 if (query_yesorno(_("Exit NeoMutt without saving?"), MUTT_YES) == MUTT_YES)
142 {
143 mutt_exit(0); /* This call never returns */
144 }
146 SigInt = false;
147}
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: get.c:58
@ 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:327
+ 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 return;
88
89 /* else */
90 refresh();
91}
#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:60
bool OptForceRefresh
(pseudo) refresh even during macros
Definition: globals.c:59
+ 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 592 of file curs_lib.c.

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

446{
447 if (!s)
448 return 0;
449 return mutt_strnwidth(s, mutt_str_len(s));
450}
+ 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 458 of file curs_lib.c.

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

◆ mutt_unget_ch()

void mutt_unget_ch ( int  ch)

Return a keystroke to the input buffer.

Parameters
chKey press

This puts events into the UngetKeyEvents buffer

Definition at line 115 of file get.c.

116{
117 array_add(&UngetKeyEvents, ch, OP_NULL);
118}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_unget_op()

void mutt_unget_op ( int  op)

Return an operation to the input buffer.

Parameters
opOperation, e.g. OP_DELETE

This puts events into the UngetKeyEvents buffer

Definition at line 126 of file get.c.

127{
128 array_add(&UngetKeyEvents, 0, op);
129}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_unget_string()

void mutt_unget_string ( const char *  s)

Return a string to the input buffer.

Parameters
sString to return

This puts events into the UngetKeyEvents buffer

Definition at line 137 of file get.c.

138{
139 const char *p = s + mutt_str_len(s) - 1;
140
141 while (p >= s)
142 {
143 mutt_unget_ch((unsigned char) *p--);
144 }
145}
+ Here is the call graph for this function:
+ 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 385 of file curs_lib.c.

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