C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Manage View Display

Manage the View Display. More...

Functions

void display_line (View *view)
 Display Line on Padparam View *view data structure.
int display_prompt (View *view, char *s)
 Display Command Line Prompt.
int fmt_line (View *view)
 Format Line for Display.
int pad_refresh (View *view)
 Refresh Pad and Line Number Window.
void parse_ansi_str (char *ansi_str, attr_t *attr, int *cpx)
 Parse ANSI SGR Escape Sequence.
void view_display_help (Init *init)
 Display View Help File.
void view_display_page (View *view)
 Display Current Page.
void view_restore_wins ()
 Restore View Windows.

Detailed Description

Manage the View Display.

Function Documentation

◆ display_line()

void display_line ( View * view)

Display Line on Padparam View *view data structure.

This function displays a single line of text on the ncurses pad. If line numbering is enabled (view->f_ln), it is formatted and displayed at the beginning of the line with the specified attributes and color pair.

Because get_next_char calls increment_ln upon encountering a line feed and increment_ln advances view->ln after updating the line table, the line number displayed is one greater than the index to the line table. That means the line counter begins with 1, while the table origin is 0.

Definition at line 1624 of file view_engine.c.

1624 {
1625 char ln_s[16];
1626
1627 if (view->cury < 0)
1628 view->cury = 0;
1629 if (view->cury > view->scroll_lines - 1)
1630 view->cury = view->scroll_lines - 1;
1631 if (view->f_ln) {
1632 ssnprintf(ln_s, 8, "%7jd", view->ln);
1633 wmove(view->ln_win, view->cury, 0);
1634 wclrtoeol(view->ln_win);
1635 mvwaddstr(view->ln_win, view->cury, 0, ln_s);
1636 }
1637 wmove(view->pad, view->cury, 0);
1638 wclrtoeol(view->pad);
1639 wadd_wchstr(view->pad, view->cmplx_buf);
1640 view->cury++;
1641}
View * view
Definition mem.c:48
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:311

References View::cmplx_buf, View::cury, View::f_ln, View::ln, View::ln_win, View::pad, View::scroll_lines, and ssnprintf().

Referenced by scroll_down_n_lines(), scroll_up_n_lines(), search(), and view_display_page().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ display_prompt()

int display_prompt ( View * view,
char * s )

Display Command Line Prompt.

Parameters
viewis the current view data structure
sis the prompt string

Definition at line 1914 of file view_engine.c.

1914 {
1915 char message_str[PAD_COLS + 1];
1916 int l;
1917 l = strnz__cpy(message_str, s, PAD_COLS);
1918 wmove(view->cmdln_win, view->cmd_line, 0);
1919 if (l != 0) {
1920 wclrtoeol(view->cmdln_win);
1921 wattron(view->cmdln_win, WA_REVERSE);
1922 waddstr(view->cmdln_win, " ");
1923 waddstr(view->cmdln_win, message_str);
1924 waddstr(view->cmdln_win, " ");
1925 wattroff(view->cmdln_win, WA_REVERSE);
1926 waddstr(view->cmdln_win, " ");
1927 view->curx = l + 2;
1928 wmove(view->cmdln_win, view->cmd_line, view->curx);
1929 }
1930 return (view->curx);
1931}
#define PAD_COLS
Definition view.h:30
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:435

References View::cmd_line, View::cmdln_win, View::curx, and strnz__cpy().

Referenced by lp(), and view_cmd_processor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fmt_line()

int fmt_line ( View * view)

Format Line for Display.

Parameters
viewpointer to View structure containing line input and output buffers
Returns
length of formatted line in characters

This function processes the input line from view->line_in_s, handling ANSI escape sequences for text attributes and colors, as well as multi-byte characters. It converts the input line into a formatted line suitable for display in the terminal, storing the result in view->cmplx_buf and view->stripped_line_out. The function returns the length of the formatted line in characters, which may be used for tracking the maximum column width of the displayed content.

This section calls the decoder for ANSI escape sequences

This section converts the input string to wide characters, handling tabs and multi-byte characters, and stores the result in the complex buffer for display. ANSI escape sequences are ignored in this section since they are handled separately above.

Definition at line 1655 of file view_engine.c.

1655 {
1656 char ansi_tok[MAXLEN];
1657 int i = 0, j = 0;
1658 int len = 0;
1659 const char *s;
1660 attr_t attr = WA_NORMAL;
1661 int cpx = cp_win;
1662 cchar_t cc = {0};
1663 wchar_t wstr[2] = {L'\0', L'\0'};
1664
1665 char *in_str = view->line_in_s;
1666 cchar_t *cmplx_buf = view->cmplx_buf;
1667
1668 rtrim(view->line_out_s);
1669 mbstate_t mbstate;
1670 memset(&mbstate, 0, sizeof(mbstate));
1671 while (in_str[i] != '\0') {
1672 if (in_str[i] == '\033' && in_str[i + 1] == '[') {
1674 len = strcspn(&in_str[i], "mK ") + 1;
1675 memcpy(ansi_tok, &in_str[i], len + 1);
1676 ansi_tok[len] = '\0';
1677 if (ansi_tok[0] == '\0') {
1678 if (i + 2 < MAXLEN)
1679 i += 2;
1680 continue;
1681 }
1682 if (len == 0 || in_str[i + len - 1] == ' ') {
1683 i += 2;
1684 continue;
1685 } else if (in_str[i + len - 1] == 'K') {
1686 i += len;
1687 continue;
1688 }
1689 parse_ansi_str(ansi_tok, &attr, &cpx);
1690 i += len;
1691 } else {
1697 if (in_str[i] == '\033') {
1698 i++;
1699 continue;
1700 }
1701 s = &in_str[i];
1702 if (*s == '\t') {
1703 do {
1704 wstr[0] = L' ';
1705 wstr[1] = L'\0';
1706 setcchar(&cc, wstr, attr, cpx, nullptr);
1707 view->stripped_line_out[j] = ' ';
1708 cmplx_buf[j++] = cc;
1709 } while ((j < PAD_COLS - 2) && (j % view->tab_stop != 0));
1710 i++;
1711 } else {
1712 wstr[1] = L'\0';
1713 len = mbrtowc(wstr, s, MB_CUR_MAX, &mbstate);
1714 if (len <= 0) {
1715 wstr[0] = L'?';
1716 wstr[1] = L'\0';
1717 len = 1;
1718 }
1719 if (setcchar(&cc, wstr, attr, cpx, nullptr) != ERR) {
1720 if (len > 0 && (j + len) < PAD_COLS - 1) {
1721 view->stripped_line_out[j] = *s;
1722 cmplx_buf[j++] = cc;
1723 }
1724 }
1725 i += len;
1726 }
1727 }
1728 }
1729 if (j > view->maxcol)
1730 view->maxcol = j;
1731 wstr[0] = '\0';
1732 wstr[1] = '\0';
1733 setcchar(&cc, wstr, WA_NORMAL, cpx, nullptr);
1734 cmplx_buf[j] = cc;
1735 view->stripped_line_out[j] = '\0';
1736 return j;
1737}
size_t rtrim(char *)
Trims trailing spaces from string s in place.
Definition futil.c:229
char in_str[BUFSIZ+1]
Definition iloan.c:20
#define MAXLEN
Definition curskeys.c:15
int cp_win
Definition dwin.c:146
void parse_ansi_str(char *, attr_t *, int *)
Parse ANSI SGR Escape Sequence.

References View::cmplx_buf, cp_win, View::line_in_s, View::line_out_s, View::maxcol, parse_ansi_str(), rtrim(), View::stripped_line_out, and View::tab_stop.

Referenced by scroll_down_n_lines(), scroll_up_n_lines(), search(), and view_display_page().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pad_refresh()

int pad_refresh ( View * view)

Refresh Pad and Line Number Window.

Parameters
viewdata structure
Returns
OK on success, ERR on failure

Definition at line 1169 of file view_engine.c.

1169 {
1170 int rc;
1171 if (view->f_ln)
1172 rc = prefresh(view->pad, view->pminrow, view->pmincol, view->sminrow,
1173 view->smincol + 8, view->smaxrow, view->smaxcol);
1174 else
1175 rc = prefresh(view->pad, view->pminrow, view->pmincol, view->sminrow,
1176 view->smincol, view->smaxrow, view->smaxcol);
1177 if (rc == ERR)
1178 Perror("Error refreshing screen");
1179 wrefresh(view->cmdln_win);
1180 if (view->f_ln)
1181 wrefresh(view->ln_win);
1182 return rc;
1183}
int Perror(char *)
Display a simple error message window or print to stderr.
Definition dwin.c:1162

References View::cmdln_win, View::f_ln, View::ln_win, View::pad, Perror(), View::pmincol, View::pminrow, View::smaxcol, View::smaxrow, View::smincol, and View::sminrow.

Referenced by get_cmd_char(), and view_cmd_processor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_ansi_str()

void parse_ansi_str ( char * ansi_str,
attr_t * attr,
int * cpx )

Parse ANSI SGR Escape Sequence.

Parameters
ansi_stris the ANSI escape sequence string to parse
attris a pointer to an attr_t variable where the parsed attributes will be stored
cpxis a pointer to an int variable where the parsed color pair index will be stored

This function parses an ANSI escape sequence and updates the color pair and color tables according to the attributes specified. Despite the depth of nested conditionals, with an understanding of the ANSI Select Graphics Rendition (SGR) scheme, which is defined in the ECMA-48 standard (ISO/IEC 6429), you will find that it is exceptionally simple and straightforward.

 This function converts the following SGR specification types to the
appropriate curses color pair index for use in the terminal display.

 RGB:

     foreground \033[38;2;r;g;bm
     background \033[48;2;r;g;bm

     Where r, g, b are the red, green, and blue color components
(0-255)

 XTERM 256-color:

     foreground \033[38;5;xm
     background \033[48;5;xm

     Where x is the 256-color index (0-255)

     uses xterm256_idx_to_rgb() to convert the 256-color index to
RGB

 8-color:

     foreground \033[3cm
     background \033[4cm

     Where c is the color code (0 for black, 1 for red, 2 for green, 3
for yellow, 4 for blue, 5 for magenta, 6 for cyan, 7 for white).

 Attributes:

     \033[am

     Where a is the attribute code (1 for bold, 2 for dim, 3 for italic,
4 for underline, 5 for blink, 7 for reverse, 8 for invis). The function
also supports resetting attributes and colors to default using \033[0m.

 @sa xterm256_idx_to_rgb(), rgb_to_curses_clr(), extended_pair_content(),
get_clr_pair()

Definition at line 1796 of file view_engine.c.

1796 {
1797 char *tok;
1798 char t0, t1;
1799 char tstr[3];
1800 int len, x_idx;
1801 int fg, bg;
1802 int fg_clr, bg_clr;
1803 char *ansi_p = ansi_str + 2;
1804 extended_pair_content(*cpx, &fg_clr, &bg_clr);
1805 fg = fg_clr;
1806 bg = bg_clr;
1807 RGB rgb;
1808 tok = strtok((char *)ansi_p, ";m");
1809 bool a_toi_error = false;
1810 while (1) {
1811 if (tok == nullptr || *tok == '\0')
1812 break;
1813 len = strlen(tok);
1814 if (len == 2) {
1815 t0 = tok[0];
1816 t1 = tok[1];
1817 if (t0 == '3' || t0 == '4') {
1818 if (t1 == '8') {
1819 tok = strtok(nullptr, ";m");
1820 if (tok != nullptr) {
1821 if (*tok == '5') {
1822 tok = strtok(nullptr, ";m");
1823 if (tok != nullptr) {
1824 x_idx = a_toi(tok, &a_toi_error);
1825 rgb = xterm256_idx_to_rgb(x_idx);
1826 }
1827 } else if (*tok == '2') {
1828 tok = strtok(nullptr, ";m");
1829 rgb.r = a_toi(tok, &a_toi_error);
1830 tok = strtok(nullptr, ";m");
1831 rgb.g = a_toi(tok, &a_toi_error);
1832 tok = strtok(nullptr, ";m");
1833 rgb.b = a_toi(tok, &a_toi_error);
1834 }
1835 }
1836 if (t0 == '3')
1837 fg_clr = rgb_to_curses_clr(&rgb);
1838 else if (t0 == '4')
1839 bg_clr = rgb_to_curses_clr(&rgb);
1840 } else if (t1 == '9') {
1841 if (t0 == '3')
1842 fg_clr = CLR_FG;
1843 else if (t0 == '4')
1844 bg_clr = CLR_BG;
1845 } else if (t1 >= '0' && t1 <= '7') {
1846 if (t0 == '3') {
1847 tstr[0] = t1;
1848 tstr[1] = '\0';
1849 x_idx = a_toi(tstr, &a_toi_error);
1850 rgb = xterm256_idx_to_rgb(x_idx);
1851 fg_clr = rgb_to_curses_clr(&rgb);
1852 } else if (t0 == '4') {
1853 tstr[0] = t1;
1854 tstr[1] = '\0';
1855 x_idx = a_toi(tstr, &a_toi_error);
1856 rgb = xterm256_idx_to_rgb(x_idx);
1857 bg_clr = rgb_to_curses_clr(&rgb);
1858 }
1859 }
1860 } else if (t0 == '0') {
1861 *tok = t1;
1862 len = 1;
1863 }
1864 }
1865 if (len == 1) {
1866 if (*tok == '0') {
1867 *attr = WA_NORMAL;
1868 fg_clr = CLR_FG;
1869 bg_clr = CLR_BG;
1870 } else {
1871 switch (a_toi(tok, &a_toi_error)) {
1872 case 1:
1873 *attr |= WA_BOLD;
1874 break;
1875 case 2:
1876 *attr |= WA_DIM;
1877 break;
1878 case 3:
1879 *attr |= WA_ITALIC;
1880 break;
1881 case 4:
1882 *attr |= WA_UNDERLINE;
1883 break;
1884 case 5:
1885 *attr |= WA_BLINK;
1886 break;
1887 case 7:
1888 *attr |= WA_REVERSE;
1889 break;
1890 case 8:
1891 *attr |= WA_INVIS;
1892 break;
1893 default:
1894 break;
1895 }
1896 }
1897 } else if (len == 0) {
1898 *attr = WA_NORMAL;
1899 fg_clr = CLR_FG;
1900 bg_clr = CLR_BG;
1901 }
1902 tok = strtok(nullptr, ";m");
1903 }
1904 if (!a_toi_error && (fg_clr != fg || bg_clr != bg)) {
1905 clr_pair_idx = get_clr_pair(fg_clr, bg_clr);
1906 *cpx = clr_pair_idx;
1907 }
1908 return;
1909}
@ CLR_FG
Definition cm.h:141
@ CLR_BG
Definition cm.h:142
int clr_pair_idx
Definition dwin.c:154
RGB xterm256_idx_to_rgb(int)
Convert XTerm 256 color index to RGB color.
Definition dwin.c:366
int rgb_to_curses_clr(RGB *)
Get color index for RGB color.
Definition dwin.c:315
int get_clr_pair(int fg, int bg)
Get color pair index for foreground and background colors.
Definition dwin.c:284
int a_toi(char *, bool *)
a safer alternative to atoi() for converting ASCII strings to integers.
Definition futil.c:671
Definition cm.h:304
int r
Definition cm.h:305
int b
Definition cm.h:307
int g
Definition cm.h:306

References a_toi(), RGB::b, CLR_BG, CLR_FG, clr_pair_idx, RGB::g, get_clr_pair(), RGB::r, rgb_to_curses_clr(), and xterm256_idx_to_rgb().

Referenced by fmt_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ view_display_help()

void view_display_help ( Init * init)

Display View Help File.

Parameters
initis the current initialization data structure.

The current View context is set aside by assigning the view structure to "view_save" while the help file is displayed using a new, separate view structure. The help file is specified by the VIEW_HELP_FILE macro can be set to a default help file path or overridden by the user through an environment variable. After the help file is closed, the original view is restored and the page is redisplayed. It may be necessary to reassign view after calling this function because the init->view pointer is temporarily set to nullptr during the help file display, and the original view is restored afterward. The default screen size for help can be set in the code below. If set to 0, popup_view will determine reasonable maximal size based on the terminal dimensions. The help file may contain Unicode characters and ANSI escape sequences for formatting, which will be properly handled and displayed by popup_view.

Definition at line 1967 of file view_engine.c.

1967 {
1968 char tmp_str[MAXLEN];
1969 int eargc = 0;
1970 char *eargv[MAXARGS];
1971 if (view->f_help_spec && view->help_spec[0] != '\0')
1972 strnz__cpy(tmp_str, view->help_spec, MAXLEN - 1);
1973 else {
1974 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
1975 strnz__cat(tmp_str, "/", MAXLEN - 1);
1976 strnz__cat(tmp_str, VIEW_HELP_FILE, MAXLEN - 1);
1977 }
1978 eargv[eargc++] = strdup("view");
1979 eargv[eargc++] = strdup("-N");
1980 eargv[eargc++] = strdup("f");
1981 eargv[eargc++] = strdup(tmp_str);
1982 eargv[eargc] = nullptr;
1983 init->lines = 48;
1984 init->cols = 72;
1985 init->begy = 0;
1986 init->begx = 0;
1987 strnz__cpy(init->title, "View Help", MAXLEN - 1);
1988 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
1989 init->begx);
1991 init->view->f_redisplay_page = true;
1992}
Init * init
Definition init.c:74
int popup_view(Init *, int, char **, int, int, int, int)
instantiate a view popup window
Definition popups.c:146
#define VIEW_HELP_FILE
Definition common.h:37
#define MAXARGS
Definition cm.h:30
int eargc
Definition futil.c:51
char * eargv[MAXARGS]
Definition futil.c:52
int destroy_argv(int argc, char **argv)
Deallocates memory allocated for argument strings in argv.
Definition futil.c:385
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:464

References Init::begx, Init::begy, Init::cols, destroy_argv(), View::f_help_spec, View::f_redisplay_page, View::help_spec, Init::lines, Init::mapp_help, popup_view(), strnz__cat(), strnz__cpy(), Init::title, Init::view, and view.

Referenced by view_cmd_processor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ view_display_page()

void view_display_page ( View * view)

Display Current Page.

Parameters
viewdata structure

Definition at line 1229 of file view_engine.c.

1229 {
1230 int i;
1231 view->cury = 0;
1232 wmove(view->pad, 0, 0);
1233 if (view->ln_win)
1234 wmove(view->ln_win, 0, 0);
1235 view->ln = view->page_top_ln;
1236 view->page_bot_ln = view->ln;
1237 view->page_top_pos = view->ln_tbl[view->ln];
1238 view->file_pos = view->page_top_pos;
1239 view->page_bot_pos = view->file_pos;
1240 for (i = 0; i < view->scroll_lines; i++) {
1241 view->page_bot_pos = get_next_line(view, view->page_bot_pos);
1242 if (view->f_eod)
1243 break;
1244 fmt_line(view);
1246 }
1247 if (view->cury < view->scroll_lines) {
1248 wmove(view->ln_win, view->cury, 0);
1249 wclrtobot(view->ln_win);
1250 wmove(view->pad, view->cury, 0);
1251 wclrtobot(view->pad);
1252 }
1253 view->page_bot_ln = view->ln;
1254}
off_t get_next_line(View *, off_t)
Get Next Line from View->buf.
void display_line(View *)
Display Line on Padparam View *view data structure.
int fmt_line(View *)
Format Line for Display.

References View::cury, display_line(), View::f_eod, View::file_pos, fmt_line(), get_next_line(), View::ln, View::ln_tbl, View::ln_win, View::pad, View::page_bot_ln, View::page_bot_pos, View::page_top_ln, View::page_top_pos, and View::scroll_lines.

Referenced by next_page(), and view_cmd_processor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ view_restore_wins()

void view_restore_wins ( )

Restore View Windows.

This function restores the content of the view windows (line number window and command line window) after they may have been overwritten by a popup or other temporary display. It uses wnoutrefresh to update the virtual screen with the content of the windows and then calls wrefresh to update the physical screen.

Definition at line 2000 of file view_engine.c.

2000 {
2001 wnoutrefresh(view->ln_win);
2002 wrefresh(view->ln_win);
2003 wnoutrefresh(view->cmdln_win);
2004 wrefresh(view->cmdln_win);
2005}

References View::cmdln_win, View::ln_win, and view.