diff options
Diffstat (limited to 'Utilities/cmpdcurses/pdcurses')
41 files changed, 11558 insertions, 0 deletions
diff --git a/Utilities/cmpdcurses/pdcurses/README.md b/Utilities/cmpdcurses/pdcurses/README.md new file mode 100644 index 0000000..d7b7c65 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/README.md @@ -0,0 +1,25 @@ +PDCurses Portable Core +====================== + +This directory contains core PDCurses source code files common to all +platforms. + + +Building +-------- + +These modules are built by the platform-specific makefiles, in the +platform directories. + + +Distribution Status +------------------- + +The files in this directory are released to the public domain. + + +Acknowledgements +---------------- + +The panel library was originally provided by +Warren Tucker <wht@n4hgf.mt-park.ga.us> diff --git a/Utilities/cmpdcurses/pdcurses/addch.c b/Utilities/cmpdcurses/pdcurses/addch.c new file mode 100644 index 0000000..9931fd6 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/addch.c @@ -0,0 +1,408 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +addch +----- + +### Synopsis + + int addch(const chtype ch); + int waddch(WINDOW *win, const chtype ch); + int mvaddch(int y, int x, const chtype ch); + int mvwaddch(WINDOW *win, int y, int x, const chtype ch); + int echochar(const chtype ch); + int wechochar(WINDOW *win, const chtype ch); + + int addrawch(chtype ch); + int waddrawch(WINDOW *win, chtype ch); + int mvaddrawch(int y, int x, chtype ch); + int mvwaddrawch(WINDOW *win, int y, int x, chtype ch); + + int add_wch(const cchar_t *wch); + int wadd_wch(WINDOW *win, const cchar_t *wch); + int mvadd_wch(int y, int x, const cchar_t *wch); + int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch); + int echo_wchar(const cchar_t *wch); + int wecho_wchar(WINDOW *win, const cchar_t *wch); + +### Description + + addch() adds the chtype ch to the default window (stdscr) at the + current cursor position, and advances the cursor. Note that chtypes + can convey both text (a single character) and attributes, including a + color pair. add_wch() is the wide-character version of this function, + taking a pointer to a cchar_t instead of a chtype. + + waddch() is like addch(), but also lets you specify the window. (This + is in fact the core output routine.) wadd_wch() is the wide version. + + mvaddch() moves the cursor to the specified (y, x) position, and adds + ch to stdscr. mvadd_wch() is the wide version. + + mvwaddch() moves the cursor to the specified position and adds ch to + the specified window. mvwadd_wch() is the wide version. + + echochar() adds ch to stdscr at the current cursor position and calls + refresh(). echo_wchar() is the wide version. + + wechochar() adds ch to the specified window and calls wrefresh(). + wecho_wchar() is the wide version. + + addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are PDCurses- + specific wrappers for addch() etc. that disable the translation of + control characters. + + The following applies to all these functions: + + If the cursor moves on to the right margin, an automatic newline is + performed. If scrollok is enabled, and a character is added to the + bottom right corner of the window, the scrolling region will be + scrolled up one line. If scrolling is not allowed, ERR will be + returned. + + If ch is a tab, newline, or backspace, the cursor will be moved + appropriately within the window. If ch is a newline, the clrtoeol + routine is called before the cursor is moved to the beginning of the + next line. If newline mapping is off, the cursor will be moved to + the next line, but the x coordinate will be unchanged. If ch is a + tab the cursor is moved to the next tab position within the window. + If ch is another control character, it will be drawn in the ^X + notation. Calling the inch() routine after adding a control + character returns the representation of the control character, not + the control character. + + Video attributes can be combined with a character by ORing them into + the parameter. Text, including attributes, can be copied from one + place to another by using inch() and addch(). + + Note that in PDCurses, for now, a cchar_t and a chtype are the same. + The text field is 16 bits wide, and is treated as Unicode (UCS-2) + when PDCurses is built with wide-character support (define PDC_WIDE). + So, in functions that take a chtype, like addch(), both the wide and + narrow versions will handle Unicode. But for portability, you should + use the wide functions. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + addch Y Y Y + waddch Y Y Y + mvaddch Y Y Y + mvwaddch Y Y Y + echochar Y Y Y + wechochar Y Y Y + add_wch Y Y Y + wadd_wch Y Y Y + mvadd_wch Y Y Y + mvwadd_wch Y Y Y + echo_wchar Y Y Y + wecho_wchar Y Y Y + addrawch - - - + waddrawch - - - + mvaddrawch - - - + mvwaddrawch - - - + +**man-end****************************************************************/ + +int waddch(WINDOW *win, const chtype ch) +{ + int x, y; + chtype text, attr; + bool xlat; + + PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n", + win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES)); + + if (!win || !SP) + return ERR; + + x = win->_curx; + y = win->_cury; + + if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0) + return ERR; + + xlat = !SP->raw_out && !(ch & A_ALTCHARSET); + text = ch & A_CHARTEXT; + attr = ch & A_ATTRIBUTES; + + if (xlat && (text < ' ' || text == 0x7f)) + { + int x2; + + switch (text) + { + case '\t': + for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++) + { + if (waddch(win, attr | ' ') == ERR) + return ERR; + + /* if tab to next line, exit the loop */ + + if (!win->_curx) + break; + } + return OK; + + case '\n': + /* if lf -> crlf */ + + if (!SP->raw_out) + x = 0; + + wclrtoeol(win); + + if (++y > win->_bmarg) + { + y--; + + if (wscrl(win, 1) == ERR) + return ERR; + } + + break; + + case '\b': + /* don't back over left margin */ + + if (--x < 0) + case '\r': + x = 0; + + break; + + case 0x7f: + if (waddch(win, attr | '^') == ERR) + return ERR; + + return waddch(win, attr | '?'); + + default: + /* handle control chars */ + + if (waddch(win, attr | '^') == ERR) + return ERR; + + return waddch(win, ch + '@'); + } + } + else + { + /* If the incoming character doesn't have its own attribute, + then use the current attributes for the window. If it has + attributes but not a color component, OR the attributes to + the current attributes for the window. If it has a color + component, use the attributes solely from the incoming + character. */ + + if (!(attr & A_COLOR)) + attr |= win->_attrs; + + /* wrs (4/10/93): Apply the same sort of logic for the window + background, in that it only takes precedence if other color + attributes are not there and that the background character + will only print if the printing character is blank. */ + + if (!(attr & A_COLOR)) + attr |= win->_bkgd & A_ATTRIBUTES; + else + attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR); + + if (text == ' ') + text = win->_bkgd & A_CHARTEXT; + + /* Add the attribute back into the character. */ + + text |= attr; + + /* Only change _firstch/_lastch if the character to be added is + different from the character/attribute that is already in + that position in the window. */ + + if (win->_y[y][x] != text) + { + if (win->_firstch[y] == _NO_CHANGE) + win->_firstch[y] = win->_lastch[y] = x; + else + if (x < win->_firstch[y]) + win->_firstch[y] = x; + else + if (x > win->_lastch[y]) + win->_lastch[y] = x; + + win->_y[y][x] = text; + } + + if (++x >= win->_maxx) + { + /* wrap around test */ + + x = 0; + + if (++y > win->_bmarg) + { + y--; + + if (wscrl(win, 1) == ERR) + { + PDC_sync(win); + return ERR; + } + } + } + } + + win->_curx = x; + win->_cury = y; + + if (win->_immed) + wrefresh(win); + if (win->_sync) + wsyncup(win); + + return OK; +} + +int addch(const chtype ch) +{ + PDC_LOG(("addch() - called: ch=%x\n", ch)); + + return waddch(stdscr, ch); +} + +int mvaddch(int y, int x, const chtype ch) +{ + PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch)); + + if (move(y,x) == ERR) + return ERR; + + return waddch(stdscr, ch); +} + +int mvwaddch(WINDOW *win, int y, int x, const chtype ch) +{ + PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddch(win, ch); +} + +int echochar(const chtype ch) +{ + PDC_LOG(("echochar() - called: ch=%x\n", ch)); + + return wechochar(stdscr, ch); +} + +int wechochar(WINDOW *win, const chtype ch) +{ + PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch)); + + if (waddch(win, ch) == ERR) + return ERR; + + return wrefresh(win); +} + +int waddrawch(WINDOW *win, chtype ch) +{ + PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n", + win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES)); + + if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f) + ch |= A_ALTCHARSET; + + return waddch(win, ch); +} + +int addrawch(chtype ch) +{ + PDC_LOG(("addrawch() - called: ch=%x\n", ch)); + + return waddrawch(stdscr, ch); +} + +int mvaddrawch(int y, int x, chtype ch) +{ + PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch)); + + if (move(y, x) == ERR) + return ERR; + + return waddrawch(stdscr, ch); +} + +int mvwaddrawch(WINDOW *win, int y, int x, chtype ch) +{ + PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n", + win, y, x, ch)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddrawch(win, ch); +} + +#ifdef PDC_WIDE +int wadd_wch(WINDOW *win, const cchar_t *wch) +{ + PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch)); + + return wch ? waddch(win, *wch) : ERR; +} + +int add_wch(const cchar_t *wch) +{ + PDC_LOG(("add_wch() - called: wch=%x\n", *wch)); + + return wadd_wch(stdscr, wch); +} + +int mvadd_wch(int y, int x, const cchar_t *wch) +{ + PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch)); + + if (move(y,x) == ERR) + return ERR; + + return wadd_wch(stdscr, wch); +} + +int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch) +{ + PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n", + win, y, x, *wch)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wadd_wch(win, wch); +} + +int echo_wchar(const cchar_t *wch) +{ + PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch)); + + return wecho_wchar(stdscr, wch); +} + +int wecho_wchar(WINDOW *win, const cchar_t *wch) +{ + PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch)); + + if (!wch || (wadd_wch(win, wch) == ERR)) + return ERR; + + return wrefresh(win); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/addchstr.c b/Utilities/cmpdcurses/pdcurses/addchstr.c new file mode 100644 index 0000000..10fc279 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/addchstr.c @@ -0,0 +1,244 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +addchstr +-------- + +### Synopsis + + int addchstr(const chtype *ch); + int addchnstr(const chtype *ch, int n); + int waddchstr(WINDOW *win, const chtype *ch); + int waddchnstr(WINDOW *win, const chtype *ch, int n); + int mvaddchstr(int y, int x, const chtype *ch); + int mvaddchnstr(int y, int x, const chtype *ch, int n); + int mvwaddchstr(WINDOW *, int y, int x, const chtype *ch); + int mvwaddchnstr(WINDOW *, int y, int x, const chtype *ch, int n); + + int add_wchstr(const cchar_t *wch); + int add_wchnstr(const cchar_t *wch, int n); + int wadd_wchstr(WINDOW *win, const cchar_t *wch); + int wadd_wchnstr(WINDOW *win, const cchar_t *wch, int n); + int mvadd_wchstr(int y, int x, const cchar_t *wch); + int mvadd_wchnstr(int y, int x, const cchar_t *wch, int n); + int mvwadd_wchstr(WINDOW *win, int y, int x, const cchar_t *wch); + int mvwadd_wchnstr(WINDOW *win, int y, int x, const cchar_t *wch, + int n); + +### Description + + These routines write a chtype or cchar_t string directly into the + window structure, starting at the current or specified position. The + four routines with n as the last argument copy at most n elements, + but no more than will fit on the line. If n == -1 then the whole + string is copied, up to the maximum number that will fit on the line. + + The cursor position is not advanced. These routines do not check for + newline or other special characters, nor does any line wrapping + occur. + +### Return Value + + All functions return OK or ERR. + +### Portability + X/Open ncurses NetBSD + addchstr Y Y Y + waddchstr Y Y Y + mvaddchstr Y Y Y + mvwaddchstr Y Y Y + addchnstr Y Y Y + waddchnstr Y Y Y + mvaddchnstr Y Y Y + mvwaddchnstr Y Y Y + add_wchstr Y Y Y + wadd_wchstr Y Y Y + mvadd_wchstr Y Y Y + mvwadd_wchstr Y Y Y + add_wchnstr Y Y Y + wadd_wchnstr Y Y Y + mvadd_wchnstr Y Y Y + mvwadd_wchnstr Y Y Y + +**man-end****************************************************************/ + +#include <string.h> + +int waddchnstr(WINDOW *win, const chtype *ch, int n) +{ + int y, x, maxx, minx; + chtype *ptr; + + PDC_LOG(("waddchnstr() - called: win=%p n=%d\n", win, n)); + + if (!win || !ch || !n || n < -1) + return ERR; + + x = win->_curx; + y = win->_cury; + ptr = &(win->_y[y][x]); + + if (n == -1 || n > win->_maxx - x) + n = win->_maxx - x; + + minx = win->_firstch[y]; + maxx = win->_lastch[y]; + + for (; n && *ch; n--, x++, ptr++, ch++) + { + if (*ptr != *ch) + { + if (x < minx || minx == _NO_CHANGE) + minx = x; + + if (x > maxx) + maxx = x; + + PDC_LOG(("y %d x %d minx %d maxx %d *ptr %x *ch" + " %x firstch: %d lastch: %d\n", + y, x, minx, maxx, *ptr, *ch, + win->_firstch[y], win->_lastch[y])); + + *ptr = *ch; + } + } + + win->_firstch[y] = minx; + win->_lastch[y] = maxx; + + return OK; +} + +int addchstr(const chtype *ch) +{ + PDC_LOG(("addchstr() - called\n")); + + return waddchnstr(stdscr, ch, -1); +} + +int addchnstr(const chtype *ch, int n) +{ + PDC_LOG(("addchnstr() - called\n")); + + return waddchnstr(stdscr, ch, n); +} + +int waddchstr(WINDOW *win, const chtype *ch) +{ + PDC_LOG(("waddchstr() - called: win=%p\n", win)); + + return waddchnstr(win, ch, -1); +} + +int mvaddchstr(int y, int x, const chtype *ch) +{ + PDC_LOG(("mvaddchstr() - called: y %d x %d\n", y, x)); + + if (move(y, x) == ERR) + return ERR; + + return waddchnstr(stdscr, ch, -1); +} + +int mvaddchnstr(int y, int x, const chtype *ch, int n) +{ + PDC_LOG(("mvaddchnstr() - called: y %d x %d n %d\n", y, x, n)); + + if (move(y, x) == ERR) + return ERR; + + return waddchnstr(stdscr, ch, n); +} + +int mvwaddchstr(WINDOW *win, int y, int x, const chtype *ch) +{ + PDC_LOG(("mvwaddchstr() - called:\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddchnstr(win, ch, -1); +} + +int mvwaddchnstr(WINDOW *win, int y, int x, const chtype *ch, int n) +{ + PDC_LOG(("mvwaddchnstr() - called: y %d x %d n %d \n", y, x, n)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddchnstr(win, ch, n); +} + +#ifdef PDC_WIDE +int wadd_wchnstr(WINDOW *win, const cchar_t *wch, int n) +{ + PDC_LOG(("wadd_wchnstr() - called: win=%p n=%d\n", win, n)); + + return waddchnstr(win, wch, n); +} + +int add_wchstr(const cchar_t *wch) +{ + PDC_LOG(("add_wchstr() - called\n")); + + return wadd_wchnstr(stdscr, wch, -1); +} + +int add_wchnstr(const cchar_t *wch, int n) +{ + PDC_LOG(("add_wchnstr() - called\n")); + + return wadd_wchnstr(stdscr, wch, n); +} + +int wadd_wchstr(WINDOW *win, const cchar_t *wch) +{ + PDC_LOG(("wadd_wchstr() - called: win=%p\n", win)); + + return wadd_wchnstr(win, wch, -1); +} + +int mvadd_wchstr(int y, int x, const cchar_t *wch) +{ + PDC_LOG(("mvadd_wchstr() - called: y %d x %d\n", y, x)); + + if (move(y, x) == ERR) + return ERR; + + return wadd_wchnstr(stdscr, wch, -1); +} + +int mvadd_wchnstr(int y, int x, const cchar_t *wch, int n) +{ + PDC_LOG(("mvadd_wchnstr() - called: y %d x %d n %d\n", y, x, n)); + + if (move(y, x) == ERR) + return ERR; + + return wadd_wchnstr(stdscr, wch, n); +} + +int mvwadd_wchstr(WINDOW *win, int y, int x, const cchar_t *wch) +{ + PDC_LOG(("mvwadd_wchstr() - called:\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wadd_wchnstr(win, wch, -1); +} + +int mvwadd_wchnstr(WINDOW *win, int y, int x, const cchar_t *wch, int n) +{ + PDC_LOG(("mvwadd_wchnstr() - called: y %d x %d n %d \n", y, x, n)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wadd_wchnstr(win, wch, n); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/addstr.c b/Utilities/cmpdcurses/pdcurses/addstr.c new file mode 100644 index 0000000..a7d8539 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/addstr.c @@ -0,0 +1,239 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +addstr +------ + +### Synopsis + + int addstr(const char *str); + int addnstr(const char *str, int n); + int waddstr(WINDOW *win, const char *str); + int waddnstr(WINDOW *win, const char *str, int n); + int mvaddstr(int y, int x, const char *str); + int mvaddnstr(int y, int x, const char *str, int n); + int mvwaddstr(WINDOW *win, int y, int x, const char *str); + int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n); + + int addwstr(const wchar_t *wstr); + int addnwstr(const wchar_t *wstr, int n); + int waddwstr(WINDOW *win, const wchar_t *wstr); + int waddnwstr(WINDOW *win, const wchar_t *wstr, int n); + int mvaddwstr(int y, int x, const wchar_t *wstr); + int mvaddnwstr(int y, int x, const wchar_t *wstr, int n); + int mvwaddwstr(WINDOW *win, int y, int x, const wchar_t *wstr); + int mvwaddnwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n); + +### Description + + These routines write all the characters of the null-terminated string + str or wide-character string wstr to the given window. The + functionality is similar to calling waddch() once for each character + in the string; except that, when PDCurses is built with wide- + character support enabled, the narrow-character functions treat the + string as a multibyte string in the current locale, and convert it. + The routines with n as the last argument write at most n characters; + if n is negative, then the entire string will be added. + +### Return Value + + All functions return OK or ERR. + +### Portability + X/Open ncurses NetBSD + addstr Y Y Y + waddstr Y Y Y + mvaddstr Y Y Y + mvwaddstr Y Y Y + addnstr Y Y Y + waddnstr Y Y Y + mvaddnstr Y Y Y + mvwaddnstr Y Y Y + addwstr Y Y Y + waddwstr Y Y Y + mvaddwstr Y Y Y + mvwaddwstr Y Y Y + addnwstr Y Y Y + waddnwstr Y Y Y + mvaddnwstr Y Y Y + mvwaddnwstr Y Y Y + +**man-end****************************************************************/ + +int waddnstr(WINDOW *win, const char *str, int n) +{ + int i = 0; + + PDC_LOG(("waddnstr() - called: string=\"%s\" n %d \n", str, n)); + + if (!win || !str) + return ERR; + + while (str[i] && (i < n || n < 0)) + { +#ifdef PDC_WIDE + wchar_t wch; + int retval = PDC_mbtowc(&wch, str + i, n >= 0 ? n - i : 6); + + if (retval <= 0) + return OK; + + i += retval; +#else + chtype wch = (unsigned char)(str[i++]); +#endif + if (waddch(win, wch) == ERR) + return ERR; + } + + return OK; +} + +int addstr(const char *str) +{ + PDC_LOG(("addstr() - called: string=\"%s\"\n", str)); + + return waddnstr(stdscr, str, -1); +} + +int addnstr(const char *str, int n) +{ + PDC_LOG(("addnstr() - called: string=\"%s\" n %d \n", str, n)); + + return waddnstr(stdscr, str, n); +} + +int waddstr(WINDOW *win, const char *str) +{ + PDC_LOG(("waddstr() - called: string=\"%s\"\n", str)); + + return waddnstr(win, str, -1); +} + +int mvaddstr(int y, int x, const char *str) +{ + PDC_LOG(("mvaddstr() - called: y %d x %d string=\"%s\"\n", y, x, str)); + + if (move(y, x) == ERR) + return ERR; + + return waddnstr(stdscr, str, -1); +} + +int mvaddnstr(int y, int x, const char *str, int n) +{ + PDC_LOG(("mvaddnstr() - called: y %d x %d string=\"%s\" n %d \n", + y, x, str, n)); + + if (move(y, x) == ERR) + return ERR; + + return waddnstr(stdscr, str, n); +} + +int mvwaddstr(WINDOW *win, int y, int x, const char *str) +{ + PDC_LOG(("mvwaddstr() - called: string=\"%s\"\n", str)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddnstr(win, str, -1); +} + +int mvwaddnstr(WINDOW *win, int y, int x, const char *str, int n) +{ + PDC_LOG(("mvwaddnstr() - called: y %d x %d string=\"%s\" n %d \n", + y, x, str, n)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddnstr(win, str, n); +} + +#ifdef PDC_WIDE +int waddnwstr(WINDOW *win, const wchar_t *wstr, int n) +{ + int i = 0; + + PDC_LOG(("waddnwstr() - called\n")); + + if (!win || !wstr) + return ERR; + + while (wstr[i] && (i < n || n < 0)) + { + chtype wch = wstr[i++]; + + if (waddch(win, wch) == ERR) + return ERR; + } + + return OK; +} + +int addwstr(const wchar_t *wstr) +{ + PDC_LOG(("addwstr() - called\n")); + + return waddnwstr(stdscr, wstr, -1); +} + +int addnwstr(const wchar_t *wstr, int n) +{ + PDC_LOG(("addnwstr() - called\n")); + + return waddnwstr(stdscr, wstr, n); +} + +int waddwstr(WINDOW *win, const wchar_t *wstr) +{ + PDC_LOG(("waddwstr() - called\n")); + + return waddnwstr(win, wstr, -1); +} + +int mvaddwstr(int y, int x, const wchar_t *wstr) +{ + PDC_LOG(("mvaddstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return waddnwstr(stdscr, wstr, -1); +} + +int mvaddnwstr(int y, int x, const wchar_t *wstr, int n) +{ + PDC_LOG(("mvaddnstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return waddnwstr(stdscr, wstr, n); +} + +int mvwaddwstr(WINDOW *win, int y, int x, const wchar_t *wstr) +{ + PDC_LOG(("mvwaddstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddnwstr(win, wstr, -1); +} + +int mvwaddnwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n) +{ + PDC_LOG(("mvwaddnstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return waddnwstr(win, wstr, n); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/attr.c b/Utilities/cmpdcurses/pdcurses/attr.c new file mode 100644 index 0000000..b5907da --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/attr.c @@ -0,0 +1,409 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +attr +---- + +### Synopsis + + int attroff(chtype attrs); + int wattroff(WINDOW *win, chtype attrs); + int attron(chtype attrs); + int wattron(WINDOW *win, chtype attrs); + int attrset(chtype attrs); + int wattrset(WINDOW *win, chtype attrs); + int standend(void); + int wstandend(WINDOW *win); + int standout(void); + int wstandout(WINDOW *win); + + int color_set(short color_pair, void *opts); + int wcolor_set(WINDOW *win, short color_pair, void *opts); + + int attr_get(attr_t *attrs, short *color_pair, void *opts); + int attr_off(attr_t attrs, void *opts); + int attr_on(attr_t attrs, void *opts); + int attr_set(attr_t attrs, short color_pair, void *opts); + int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair, + void *opts); + int wattr_off(WINDOW *win, attr_t attrs, void *opts); + int wattr_on(WINDOW *win, attr_t attrs, void *opts); + int wattr_set(WINDOW *win, attr_t attrs, short color_pair, + void *opts); + + int chgat(int n, attr_t attr, short color, const void *opts); + int mvchgat(int y, int x, int n, attr_t attr, short color, + const void *opts); + int mvwchgat(WINDOW *win, int y, int x, int n, attr_t attr, + short color, const void *opts); + int wchgat(WINDOW *win, int n, attr_t attr, short color, + const void *opts); + + chtype getattrs(WINDOW *win); + + int underend(void); + int wunderend(WINDOW *win); + int underscore(void); + int wunderscore(WINDOW *win); + +### Description + + These functions manipulate the current attributes and/or colors of + the named window. These attributes can be any combination of + A_STANDOUT, A_REVERSE, A_BOLD, A_DIM, A_BLINK, A_UNDERLINE. These + constants are defined in <curses.h> and can be combined with the + bitwise-OR operator (|). + + The current attributes of a window are applied to all chtypes that + are written into the window with waddch(). Attributes are a property + of the chtype, and move with the character through any scrolling or + insert/delete operations. + + wattrset() sets the current attributes of the given window to attrs. + attrset() is the stdscr version. + + wattroff() turns off the named attributes without affecting any other + attributes; wattron() turns them on. + + wcolor_set() sets the window color to the value of color_pair. opts + is unused. + + standout() is the same as attron(A_STANDOUT). standend() is the same + as attrset(A_NORMAL); that is, it turns off all attributes. + + The attr_* and wattr_* functions are intended for use with the WA_* + attributes. In PDCurses, these are the same as A_*, and there is no + difference in bevahior from the chtype-based functions. In all cases, + opts is unused. + + wattr_get() retrieves the attributes and color pair for the specified + window. + + wchgat() sets the color pair and attributes for the next n cells on + the current line of a given window, without changing the existing + text, or alterting the window's attributes. An n of -1 extends the + change to the edge of the window. The changes take effect + immediately. opts is unused. + + wunderscore() turns on the A_UNDERLINE attribute; wunderend() turns + it off. underscore() and underend() are the stdscr versions. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + attroff Y Y Y + wattroff Y Y Y + attron Y Y Y + wattron Y Y Y + attrset Y Y Y + wattrset Y Y Y + standend Y Y Y + wstandend Y Y Y + standout Y Y Y + wstandout Y Y Y + color_set Y Y Y + wcolor_set Y Y Y + attr_get Y Y Y + wattr_get Y Y Y + attr_on Y Y Y + wattr_on Y Y Y + attr_off Y Y Y + wattr_off Y Y Y + attr_set Y Y Y + wattr_set Y Y Y + chgat Y Y Y + wchgat Y Y Y + mvchgat Y Y Y + mvwchgat Y Y Y + getattrs - Y Y + underend - - Y + wunderend - - Y + underscore - - Y + wunderscore - - Y + +**man-end****************************************************************/ + +int wattroff(WINDOW *win, chtype attrs) +{ + PDC_LOG(("wattroff() - called\n")); + + if (!win) + return ERR; + + win->_attrs &= (~attrs & A_ATTRIBUTES); + + return OK; +} + +int attroff(chtype attrs) +{ + PDC_LOG(("attroff() - called\n")); + + return wattroff(stdscr, attrs); +} + +int wattron(WINDOW *win, chtype attrs) +{ + chtype newcolr, oldcolr, newattr, oldattr; + + PDC_LOG(("wattron() - called\n")); + + if (!win) + return ERR; + + if ((win->_attrs & A_COLOR) && (attrs & A_COLOR)) + { + oldcolr = win->_attrs & A_COLOR; + oldattr = win->_attrs ^ oldcolr; + newcolr = attrs & A_COLOR; + newattr = (attrs & A_ATTRIBUTES) ^ newcolr; + newattr |= oldattr; + win->_attrs = newattr | newcolr; + } + else + win->_attrs |= (attrs & A_ATTRIBUTES); + + return OK; +} + +int attron(chtype attrs) +{ + PDC_LOG(("attron() - called\n")); + + return wattron(stdscr, attrs); +} + +int wattrset(WINDOW *win, chtype attrs) +{ + PDC_LOG(("wattrset() - called\n")); + + if (!win) + return ERR; + + win->_attrs = attrs & A_ATTRIBUTES; + + return OK; +} + +int attrset(chtype attrs) +{ + PDC_LOG(("attrset() - called\n")); + + return wattrset(stdscr, attrs); +} + +int standend(void) +{ + PDC_LOG(("standend() - called\n")); + + return wattrset(stdscr, A_NORMAL); +} + +int standout(void) +{ + PDC_LOG(("standout() - called\n")); + + return wattrset(stdscr, A_STANDOUT); +} + +int wstandend(WINDOW *win) +{ + PDC_LOG(("wstandend() - called\n")); + + return wattrset(win, A_NORMAL); +} + +int wstandout(WINDOW *win) +{ + PDC_LOG(("wstandout() - called\n")); + + return wattrset(win, A_STANDOUT); +} + +chtype getattrs(WINDOW *win) +{ + return win ? win->_attrs : 0; +} + +int wcolor_set(WINDOW *win, short color_pair, void *opts) +{ + PDC_LOG(("wcolor_set() - called\n")); + + if (!win) + return ERR; + + win->_attrs = (win->_attrs & ~A_COLOR) | COLOR_PAIR(color_pair); + + return OK; +} + +int color_set(short color_pair, void *opts) +{ + PDC_LOG(("color_set() - called\n")); + + return wcolor_set(stdscr, color_pair, opts); +} + +int wattr_get(WINDOW *win, attr_t *attrs, short *color_pair, void *opts) +{ + PDC_LOG(("wattr_get() - called\n")); + + if (!win) + return ERR; + + if (attrs) + *attrs = win->_attrs & (A_ATTRIBUTES & ~A_COLOR); + + if (color_pair) + *color_pair = PAIR_NUMBER(win->_attrs); + + return OK; +} + +int attr_get(attr_t *attrs, short *color_pair, void *opts) +{ + PDC_LOG(("attr_get() - called\n")); + + return wattr_get(stdscr, attrs, color_pair, opts); +} + +int wattr_off(WINDOW *win, attr_t attrs, void *opts) +{ + PDC_LOG(("wattr_off() - called\n")); + + return wattroff(win, attrs); +} + +int attr_off(attr_t attrs, void *opts) +{ + PDC_LOG(("attr_off() - called\n")); + + return wattroff(stdscr, attrs); +} + +int wattr_on(WINDOW *win, attr_t attrs, void *opts) +{ + PDC_LOG(("wattr_off() - called\n")); + + return wattron(win, attrs); +} + +int attr_on(attr_t attrs, void *opts) +{ + PDC_LOG(("attr_on() - called\n")); + + return wattron(stdscr, attrs); +} + +int wattr_set(WINDOW *win, attr_t attrs, short color_pair, void *opts) +{ + PDC_LOG(("wattr_set() - called\n")); + + if (!win) + return ERR; + + win->_attrs = (attrs & (A_ATTRIBUTES & ~A_COLOR)) | COLOR_PAIR(color_pair); + + return OK; +} + +int attr_set(attr_t attrs, short color_pair, void *opts) +{ + PDC_LOG(("attr_get() - called\n")); + + return wattr_set(stdscr, attrs, color_pair, opts); +} + +int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts) +{ + chtype *dest, newattr; + int startpos, endpos; + + PDC_LOG(("wchgat() - called\n")); + + if (!win) + return ERR; + + newattr = (attr & A_ATTRIBUTES) | COLOR_PAIR(color); + + startpos = win->_curx; + endpos = ((n < 0) ? win->_maxx : min(startpos + n, win->_maxx)) - 1; + dest = win->_y[win->_cury]; + + for (n = startpos; n <= endpos; n++) + dest[n] = (dest[n] & A_CHARTEXT) | newattr; + + n = win->_cury; + + if (startpos < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) + win->_firstch[n] = startpos; + + if (endpos > win->_lastch[n]) + win->_lastch[n] = endpos; + + PDC_sync(win); + + return OK; +} + +int chgat(int n, attr_t attr, short color, const void *opts) +{ + PDC_LOG(("chgat() - called\n")); + + return wchgat(stdscr, n, attr, color, opts); +} + +int mvchgat(int y, int x, int n, attr_t attr, short color, const void *opts) +{ + PDC_LOG(("mvchgat() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wchgat(stdscr, n, attr, color, opts); +} + +int mvwchgat(WINDOW *win, int y, int x, int n, attr_t attr, short color, + const void *opts) +{ + PDC_LOG(("mvwchgat() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wchgat(win, n, attr, color, opts); +} + +int underend(void) +{ + PDC_LOG(("underend() - called\n")); + + return wattroff(stdscr, A_UNDERLINE); +} + +int wunderend(WINDOW *win) +{ + PDC_LOG(("wunderend() - called\n")); + + return wattroff(win, A_UNDERLINE); +} + +int underscore(void) +{ + PDC_LOG(("underscore() - called\n")); + + return wattron(stdscr, A_UNDERLINE); +} + +int wunderscore(WINDOW *win) +{ + PDC_LOG(("wunderscore() - called\n")); + + return wattron(win, A_UNDERLINE); +} diff --git a/Utilities/cmpdcurses/pdcurses/beep.c b/Utilities/cmpdcurses/pdcurses/beep.c new file mode 100644 index 0000000..690c794 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/beep.c @@ -0,0 +1,74 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +beep +---- + +### Synopsis + + int beep(void); + int flash(void); + +### Description + + beep() sounds the audible bell on the terminal, if possible; if not, + it calls flash(). + + flash() "flashes" the screen, by inverting the foreground and + background of every cell, pausing, and then restoring the original + attributes. + +### Return Value + + These functions return ERR if called before initscr(), otherwise OK. + +### Portability + X/Open ncurses NetBSD + beep Y Y Y + flash Y Y Y + +**man-end****************************************************************/ + +int beep(void) +{ + PDC_LOG(("beep() - called\n")); + + if (!SP) + return ERR; + + if (SP->audible) + PDC_beep(); + else + flash(); + + return OK; +} + +int flash(void) +{ + int z, y, x; + + PDC_LOG(("flash() - called\n")); + + if (!curscr) + return ERR; + + /* Reverse each cell; wait; restore the screen */ + + for (z = 0; z < 2; z++) + { + for (y = 0; y < LINES; y++) + for (x = 0; x < COLS; x++) + curscr->_y[y][x] ^= A_REVERSE; + + wrefresh(curscr); + + if (!z) + napms(50); + } + + return OK; +} diff --git a/Utilities/cmpdcurses/pdcurses/bkgd.c b/Utilities/cmpdcurses/pdcurses/bkgd.c new file mode 100644 index 0000000..f576437 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/bkgd.c @@ -0,0 +1,226 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +bkgd +---- + +### Synopsis + + int bkgd(chtype ch); + void bkgdset(chtype ch); + chtype getbkgd(WINDOW *win); + int wbkgd(WINDOW *win, chtype ch); + void wbkgdset(WINDOW *win, chtype ch); + + int bkgrnd(const cchar_t *wch); + void bkgrndset(const cchar_t *wch); + int getbkgrnd(cchar_t *wch); + int wbkgrnd(WINDOW *win, const cchar_t *wch); + void wbkgrndset(WINDOW *win, const cchar_t *wch); + int wgetbkgrnd(WINDOW *win, cchar_t *wch); + +### Description + + bkgdset() and wbkgdset() manipulate the background of a window. The + background is a chtype consisting of any combination of attributes + and a character; it is combined with each chtype added or inserted to + the window by waddch() or winsch(). Only the attribute part is used + to set the background of non-blank characters, while both character + and attributes are used for blank positions. + + bkgd() and wbkgd() not only change the background, but apply it + immediately to every cell in the window. + + wbkgrnd(), wbkgrndset() and wgetbkgrnd() are the "wide-character" + versions of these functions, taking a pointer to a cchar_t instead of + a chtype. However, in PDCurses, cchar_t and chtype are the same. + + The attributes that are defined with the attrset()/attron() set of + functions take precedence over the background attributes if there is + a conflict (e.g., different color pairs). + +### Return Value + + bkgd() and wbkgd() return OK, unless the window is NULL, in which + case they return ERR. + +### Portability + X/Open ncurses NetBSD + bkgd Y Y Y + bkgdset Y Y Y + getbkgd Y Y Y + wbkgd Y Y Y + wbkgdset Y Y Y + bkgrnd Y Y Y + bkgrndset Y Y Y + getbkgrnd Y Y Y + wbkgrnd Y Y Y + wbkgrndset Y Y Y + wgetbkgrnd Y Y Y + +**man-end****************************************************************/ + +int wbkgd(WINDOW *win, chtype ch) +{ + int x, y; + chtype oldcolr, oldch, newcolr, newch, colr, attr; + chtype oldattr = 0, newattr = 0; + chtype *winptr; + + PDC_LOG(("wbkgd() - called\n")); + + if (!win) + return ERR; + + if (win->_bkgd == ch) + return OK; + + oldcolr = win->_bkgd & A_COLOR; + if (oldcolr) + oldattr = (win->_bkgd & A_ATTRIBUTES) ^ oldcolr; + + oldch = win->_bkgd & A_CHARTEXT; + + wbkgdset(win, ch); + + newcolr = win->_bkgd & A_COLOR; + if (newcolr) + newattr = (win->_bkgd & A_ATTRIBUTES) ^ newcolr; + + newch = win->_bkgd & A_CHARTEXT; + + /* what follows is what seems to occur in the System V + implementation of this routine */ + + for (y = 0; y < win->_maxy; y++) + { + for (x = 0; x < win->_maxx; x++) + { + winptr = win->_y[y] + x; + + ch = *winptr; + + /* determine the colors and attributes of the character read + from the window */ + + colr = ch & A_COLOR; + attr = ch & (A_ATTRIBUTES ^ A_COLOR); + + /* if the color is the same as the old background color, + then make it the new background color, otherwise leave it */ + + if (colr == oldcolr) + colr = newcolr; + + /* remove any attributes (non color) from the character that + were part of the old background, then combine the + remaining ones with the new background */ + + attr ^= oldattr; + attr |= newattr; + + /* change character if it is there because it was the old + background character */ + + ch &= A_CHARTEXT; + if (ch == oldch) + ch = newch; + + ch |= (attr | colr); + + *winptr = ch; + + } + } + + touchwin(win); + PDC_sync(win); + return OK; +} + +int bkgd(chtype ch) +{ + PDC_LOG(("bkgd() - called\n")); + + return wbkgd(stdscr, ch); +} + +void wbkgdset(WINDOW *win, chtype ch) +{ + PDC_LOG(("wbkgdset() - called\n")); + + if (win) + { + if (!(ch & A_CHARTEXT)) + ch |= ' '; + + win->_bkgd = ch; + } +} + +void bkgdset(chtype ch) +{ + PDC_LOG(("bkgdset() - called\n")); + + wbkgdset(stdscr, ch); +} + +chtype getbkgd(WINDOW *win) +{ + PDC_LOG(("getbkgd() - called\n")); + + return win ? win->_bkgd : (chtype)ERR; +} + +#ifdef PDC_WIDE +int wbkgrnd(WINDOW *win, const cchar_t *wch) +{ + PDC_LOG(("wbkgrnd() - called\n")); + + return wch ? wbkgd(win, *wch) : ERR; +} + +int bkgrnd(const cchar_t *wch) +{ + PDC_LOG(("bkgrnd() - called\n")); + + return wbkgrnd(stdscr, wch); +} + +void wbkgrndset(WINDOW *win, const cchar_t *wch) +{ + PDC_LOG(("wbkgdset() - called\n")); + + if (wch) + wbkgdset(win, *wch); +} + +void bkgrndset(const cchar_t *wch) +{ + PDC_LOG(("bkgrndset() - called\n")); + + wbkgrndset(stdscr, wch); +} + +int wgetbkgrnd(WINDOW *win, cchar_t *wch) +{ + PDC_LOG(("wgetbkgrnd() - called\n")); + + if (!win || !wch) + return ERR; + + *wch = win->_bkgd; + + return OK; +} + +int getbkgrnd(cchar_t *wch) +{ + PDC_LOG(("getbkgrnd() - called\n")); + + return wgetbkgrnd(stdscr, wch); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/border.c b/Utilities/cmpdcurses/pdcurses/border.c new file mode 100644 index 0000000..62458b6 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/border.c @@ -0,0 +1,414 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +border +------ + +### Synopsis + + int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, + chtype tr, chtype bl, chtype br); + int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, + chtype bs, chtype tl, chtype tr, chtype bl, chtype br); + int box(WINDOW *win, chtype verch, chtype horch); + int hline(chtype ch, int n); + int vline(chtype ch, int n); + int whline(WINDOW *win, chtype ch, int n); + int wvline(WINDOW *win, chtype ch, int n); + int mvhline(int y, int x, chtype ch, int n); + int mvvline(int y, int x, chtype ch, int n); + int mvwhline(WINDOW *win, int y, int x, chtype ch, int n); + int mvwvline(WINDOW *win, int y, int x, chtype ch, int n); + + int border_set(const cchar_t *ls, const cchar_t *rs, + const cchar_t *ts, const cchar_t *bs, + const cchar_t *tl, const cchar_t *tr, + const cchar_t *bl, const cchar_t *br); + int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, + const cchar_t *ts, const cchar_t *bs, + const cchar_t *tl, const cchar_t *tr, + const cchar_t *bl, const cchar_t *br); + int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch); + int hline_set(const cchar_t *wch, int n); + int vline_set(const cchar_t *wch, int n); + int whline_set(WINDOW *win, const cchar_t *wch, int n); + int wvline_set(WINDOW *win, const cchar_t *wch, int n); + int mvhline_set(int y, int x, const cchar_t *wch, int n); + int mvvline_set(int y, int x, const cchar_t *wch, int n); + int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n); + int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n); + +### Description + + border(), wborder(), and box() draw a border around the edge of the + window. If any argument is zero, an appropriate default is used: + + ls left side of border ACS_VLINE + rs right side of border ACS_VLINE + ts top side of border ACS_HLINE + bs bottom side of border ACS_HLINE + tl top left corner of border ACS_ULCORNER + tr top right corner of border ACS_URCORNER + bl bottom left corner of border ACS_LLCORNER + br bottom right corner of border ACS_LRCORNER + + hline() and whline() draw a horizontal line, using ch, starting from + the current cursor position. The cursor position does not change. The + line is at most n characters long, or as many as will fit in the + window. + + vline() and wvline() draw a vertical line, using ch, starting from + the current cursor position. The cursor position does not change. The + line is at most n characters long, or as many as will fit in the + window. + + The *_set functions are the "wide-character" versions, taking + pointers to cchar_t instead of chtype. Note that in PDCurses, chtype + and cchar_t are the same. + +### Return Value + + These functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + border Y Y Y + wborder Y Y Y + box Y Y Y + hline Y Y Y + vline Y Y Y + whline Y Y Y + wvline Y Y Y + mvhline Y Y Y + mvvline Y Y Y + mvwhline Y Y Y + mvwvline Y Y Y + border_set Y Y Y + wborder_set Y Y Y + box_set Y Y Y + hline_set Y Y Y + vline_set Y Y Y + whline_set Y Y Y + wvline_set Y Y Y + mvhline_set Y Y Y + mvvline_set Y Y Y + mvwhline_set Y Y Y + mvwvline_set Y Y Y + +**man-end****************************************************************/ + +/* _attr_passthru() -- Takes a single chtype 'ch' and checks if the + current attribute of window 'win', as set by wattrset(), and/or the + current background of win, as set by wbkgd(), should by combined with + it. Attributes set explicitly in ch take precedence. */ + +static chtype _attr_passthru(WINDOW *win, chtype ch) +{ + chtype attr; + + /* If the incoming character doesn't have its own attribute, then + use the current attributes for the window. If the incoming + character has attributes, but not a color component, OR the + attributes to the current attributes for the window. If the + incoming character has a color component, use only the attributes + from the incoming character. */ + + attr = ch & A_ATTRIBUTES; + if (!(attr & A_COLOR)) + attr |= win->_attrs; + + /* wrs (4/10/93) -- Apply the same sort of logic for the window + background, in that it only takes precedence if other color + attributes are not there. */ + + if (!(attr & A_COLOR)) + attr |= win->_bkgd & A_ATTRIBUTES; + else + attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR); + + ch = (ch & A_CHARTEXT) | attr; + + return ch; +} + +int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs, + chtype tl, chtype tr, chtype bl, chtype br) +{ + int i, ymax, xmax; + + PDC_LOG(("wborder() - called\n")); + + if (!win) + return ERR; + + ymax = win->_maxy - 1; + xmax = win->_maxx - 1; + + ls = _attr_passthru(win, ls ? ls : ACS_VLINE); + rs = _attr_passthru(win, rs ? rs : ACS_VLINE); + ts = _attr_passthru(win, ts ? ts : ACS_HLINE); + bs = _attr_passthru(win, bs ? bs : ACS_HLINE); + tl = _attr_passthru(win, tl ? tl : ACS_ULCORNER); + tr = _attr_passthru(win, tr ? tr : ACS_URCORNER); + bl = _attr_passthru(win, bl ? bl : ACS_LLCORNER); + br = _attr_passthru(win, br ? br : ACS_LRCORNER); + + for (i = 1; i < xmax; i++) + { + win->_y[0][i] = ts; + win->_y[ymax][i] = bs; + } + + for (i = 1; i < ymax; i++) + { + win->_y[i][0] = ls; + win->_y[i][xmax] = rs; + } + + win->_y[0][0] = tl; + win->_y[0][xmax] = tr; + win->_y[ymax][0] = bl; + win->_y[ymax][xmax] = br; + + for (i = 0; i <= ymax; i++) + { + win->_firstch[i] = 0; + win->_lastch[i] = xmax; + } + + PDC_sync(win); + + return OK; +} + +int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, + chtype tr, chtype bl, chtype br) +{ + PDC_LOG(("border() - called\n")); + + return wborder(stdscr, ls, rs, ts, bs, tl, tr, bl, br); +} + +int box(WINDOW *win, chtype verch, chtype horch) +{ + PDC_LOG(("box() - called\n")); + + return wborder(win, verch, verch, horch, horch, 0, 0, 0, 0); +} + +int whline(WINDOW *win, chtype ch, int n) +{ + chtype *dest; + int startpos, endpos; + + PDC_LOG(("whline() - called\n")); + + if (!win || n < 1) + return ERR; + + startpos = win->_curx; + endpos = min(startpos + n, win->_maxx) - 1; + dest = win->_y[win->_cury]; + ch = _attr_passthru(win, ch ? ch : ACS_HLINE); + + for (n = startpos; n <= endpos; n++) + dest[n] = ch; + + n = win->_cury; + + if (startpos < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) + win->_firstch[n] = startpos; + + if (endpos > win->_lastch[n]) + win->_lastch[n] = endpos; + + PDC_sync(win); + + return OK; +} + +int hline(chtype ch, int n) +{ + PDC_LOG(("hline() - called\n")); + + return whline(stdscr, ch, n); +} + +int mvhline(int y, int x, chtype ch, int n) +{ + PDC_LOG(("mvhline() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return whline(stdscr, ch, n); +} + +int mvwhline(WINDOW *win, int y, int x, chtype ch, int n) +{ + PDC_LOG(("mvwhline() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return whline(win, ch, n); +} + +int wvline(WINDOW *win, chtype ch, int n) +{ + int endpos, x; + + PDC_LOG(("wvline() - called\n")); + + if (!win || n < 1) + return ERR; + + endpos = min(win->_cury + n, win->_maxy); + x = win->_curx; + + ch = _attr_passthru(win, ch ? ch : ACS_VLINE); + + for (n = win->_cury; n < endpos; n++) + { + win->_y[n][x] = ch; + + if (x < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) + win->_firstch[n] = x; + + if (x > win->_lastch[n]) + win->_lastch[n] = x; + } + + PDC_sync(win); + + return OK; +} + +int vline(chtype ch, int n) +{ + PDC_LOG(("vline() - called\n")); + + return wvline(stdscr, ch, n); +} + +int mvvline(int y, int x, chtype ch, int n) +{ + PDC_LOG(("mvvline() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wvline(stdscr, ch, n); +} + +int mvwvline(WINDOW *win, int y, int x, chtype ch, int n) +{ + PDC_LOG(("mvwvline() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wvline(win, ch, n); +} + +#ifdef PDC_WIDE +int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, + const cchar_t *ts, const cchar_t *bs, const cchar_t *tl, + const cchar_t *tr, const cchar_t *bl, const cchar_t *br) +{ + PDC_LOG(("wborder_set() - called\n")); + + return wborder(win, ls ? *ls : 0, rs ? *rs : 0, ts ? *ts : 0, + bs ? *bs : 0, tl ? *tl : 0, tr ? *tr : 0, + bl ? *bl : 0, br ? *br : 0); +} + +int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts, + const cchar_t *bs, const cchar_t *tl, const cchar_t *tr, + const cchar_t *bl, const cchar_t *br) +{ + PDC_LOG(("border_set() - called\n")); + + return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br); +} + +int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch) +{ + PDC_LOG(("box_set() - called\n")); + + return wborder_set(win, verch, verch, horch, horch, + (const cchar_t *)NULL, (const cchar_t *)NULL, + (const cchar_t *)NULL, (const cchar_t *)NULL); +} + +int whline_set(WINDOW *win, const cchar_t *wch, int n) +{ + PDC_LOG(("whline_set() - called\n")); + + return wch ? whline(win, *wch, n) : ERR; +} + +int hline_set(const cchar_t *wch, int n) +{ + PDC_LOG(("hline_set() - called\n")); + + return whline_set(stdscr, wch, n); +} + +int mvhline_set(int y, int x, const cchar_t *wch, int n) +{ + PDC_LOG(("mvhline_set() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return whline_set(stdscr, wch, n); +} + +int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) +{ + PDC_LOG(("mvwhline_set() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return whline_set(win, wch, n); +} + +int wvline_set(WINDOW *win, const cchar_t *wch, int n) +{ + PDC_LOG(("wvline_set() - called\n")); + + return wch ? wvline(win, *wch, n) : ERR; +} + +int vline_set(const cchar_t *wch, int n) +{ + PDC_LOG(("vline_set() - called\n")); + + return wvline_set(stdscr, wch, n); +} + +int mvvline_set(int y, int x, const cchar_t *wch, int n) +{ + PDC_LOG(("mvvline_set() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wvline_set(stdscr, wch, n); +} + +int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) +{ + PDC_LOG(("mvwvline_set() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wvline_set(win, wch, n); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/clear.c b/Utilities/cmpdcurses/pdcurses/clear.c new file mode 100644 index 0000000..50ff7ad --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/clear.c @@ -0,0 +1,159 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +clear +----- + +### Synopsis + + int clear(void); + int wclear(WINDOW *win); + int erase(void); + int werase(WINDOW *win); + int clrtobot(void); + int wclrtobot(WINDOW *win); + int clrtoeol(void); + int wclrtoeol(WINDOW *win); + +### Description + + erase() and werase() copy blanks (i.e. the background chtype) to + every cell of the window. + + clear() and wclear() are similar to erase() and werase(), but they + also call clearok() to ensure that the the window is cleared on the + next wrefresh(). + + clrtobot() and wclrtobot() clear the window from the current cursor + position to the end of the window. + + clrtoeol() and wclrtoeol() clear the window from the current cursor + position to the end of the current line. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + clear Y Y Y + wclear Y Y Y + erase Y Y Y + werase Y Y Y + clrtobot Y Y Y + wclrtobot Y Y Y + clrtoeol Y Y Y + wclrtoeol Y Y Y + +**man-end****************************************************************/ + +int wclrtoeol(WINDOW *win) +{ + int x, y, minx; + chtype blank, *ptr; + + PDC_LOG(("wclrtoeol() - called: Row: %d Col: %d\n", + win->_cury, win->_curx)); + + if (!win) + return ERR; + + y = win->_cury; + x = win->_curx; + + /* wrs (4/10/93) account for window background */ + + blank = win->_bkgd; + + for (minx = x, ptr = &win->_y[y][x]; minx < win->_maxx; minx++, ptr++) + *ptr = blank; + + if (x < win->_firstch[y] || win->_firstch[y] == _NO_CHANGE) + win->_firstch[y] = x; + + win->_lastch[y] = win->_maxx - 1; + + PDC_sync(win); + return OK; +} + +int clrtoeol(void) +{ + PDC_LOG(("clrtoeol() - called\n")); + + return wclrtoeol(stdscr); +} + +int wclrtobot(WINDOW *win) +{ + int savey, savex; + + PDC_LOG(("wclrtobot() - called\n")); + + if (!win) + return ERR; + + savey = win->_cury; + savex = win->_curx; + + /* should this involve scrolling region somehow ? */ + + if (win->_cury + 1 < win->_maxy) + { + win->_curx = 0; + win->_cury++; + for (; win->_maxy > win->_cury; win->_cury++) + wclrtoeol(win); + win->_cury = savey; + win->_curx = savex; + } + wclrtoeol(win); + + PDC_sync(win); + return OK; +} + +int clrtobot(void) +{ + PDC_LOG(("clrtobot() - called\n")); + + return wclrtobot(stdscr); +} + +int werase(WINDOW *win) +{ + PDC_LOG(("werase() - called\n")); + + if (wmove(win, 0, 0) == ERR) + return ERR; + + return wclrtobot(win); +} + +int erase(void) +{ + PDC_LOG(("erase() - called\n")); + + return werase(stdscr); +} + +int wclear(WINDOW *win) +{ + PDC_LOG(("wclear() - called\n")); + + if (!win) + return ERR; + + win->_clear = TRUE; + return werase(win); +} + +int clear(void) +{ + PDC_LOG(("clear() - called\n")); + + return wclear(stdscr); +} diff --git a/Utilities/cmpdcurses/pdcurses/color.c b/Utilities/cmpdcurses/pdcurses/color.c new file mode 100644 index 0000000..7d4df24 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/color.c @@ -0,0 +1,362 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +color +----- + +### Synopsis + + bool has_colors(void); + int start_color(void); + int init_pair(short pair, short fg, short bg); + int pair_content(short pair, short *fg, short *bg); + bool can_change_color(void); + int init_color(short color, short red, short green, short blue); + int color_content(short color, short *red, short *green, short *blue); + + int alloc_pair(int fg, int bg); + int assume_default_colors(int f, int b); + int find_pair(int fg, int bg); + int free_pair(int pair); + int use_default_colors(void); + + int PDC_set_line_color(short color); + +### Description + + To use these routines, first, call start_color(). Colors are always + used in pairs, referred to as color-pairs. A color-pair is created by + init_pair(), and consists of a foreground color and a background + color. After initialization, COLOR_PAIR(n) can be used like any other + video attribute. + + has_colors() reports whether the terminal supports color. + + start_color() initializes eight basic colors (black, red, green, + yellow, blue, magenta, cyan, and white), and two global variables: + COLORS and COLOR_PAIRS (respectively defining the maximum number of + colors and color-pairs the terminal is capable of displaying). + + init_pair() changes the definition of a color-pair. It takes three + arguments: the number of the color-pair to be redefined, and the new + values of the foreground and background colors. The pair number must + be between 0 and COLOR_PAIRS - 1, inclusive. The foreground and + background must be between 0 and COLORS - 1, inclusive. If the color + pair was previously initialized, the screen is refreshed, and all + occurrences of that color-pair are changed to the new definition. + + pair_content() is used to determine what the colors of a given color- + pair consist of. + + can_change_color() indicates if the terminal has the capability to + change the definition of its colors. + + init_color() is used to redefine a color, if possible. Each of the + components -- red, green, and blue -- is specified in a range from 0 + to 1000, inclusive. + + color_content() reports the current definition of a color in the same + format as used by init_color(). + + assume_default_colors() and use_default_colors() emulate the ncurses + extensions of the same names. assume_default_colors(f, b) is + essentially the same as init_pair(0, f, b) (which isn't allowed); it + redefines the default colors. use_default_colors() allows the use of + -1 as a foreground or background color with init_pair(), and calls + assume_default_colors(-1, -1); -1 represents the foreground or + background color that the terminal had at startup. If the environment + variable PDC_ORIGINAL_COLORS is set at the time start_color() is + called, that's equivalent to calling use_default_colors(). + + alloc_pair(), find_pair() and free_pair() are also from ncurses. + free_pair() marks a pair as unused; find_pair() returns an existing + pair with the specified foreground and background colors, if one + exists. And alloc_pair() returns such a pair whether or not it was + previously set, overwriting the oldest initialized pair if there are + no free pairs. + + PDC_set_line_color() is used to set the color, globally, for the + color of the lines drawn for the attributes: A_UNDERLINE, A_LEFT and + A_RIGHT. A value of -1 (the default) indicates that the current + foreground color should be used. + + NOTE: COLOR_PAIR() and PAIR_NUMBER() are implemented as macros. + +### Return Value + + Most functions return OK on success and ERR on error. has_colors() + and can_change_colors() return TRUE or FALSE. alloc_pair() and + find_pair() return a pair number, or -1 on error. + +### Portability + X/Open ncurses NetBSD + has_colors Y Y Y + start_color Y Y Y + init_pair Y Y Y + pair_content Y Y Y + can_change_color Y Y Y + init_color Y Y Y + color_content Y Y Y + alloc_pair - Y - + assume_default_colors - Y Y + find_pair - Y - + free_pair - Y - + use_default_colors - Y Y + PDC_set_line_color - - - + +**man-end****************************************************************/ + +#include <stdlib.h> +#include <string.h> + +int COLORS = 0; +int COLOR_PAIRS = PDC_COLOR_PAIRS; + +static bool default_colors = FALSE; +static short first_col = 0; +static int allocnum = 0; + +int start_color(void) +{ + PDC_LOG(("start_color() - called\n")); + + if (!SP || SP->mono) + return ERR; + + SP->color_started = TRUE; + + PDC_set_blink(FALSE); /* Also sets COLORS */ + + if (!default_colors && SP->orig_attr && getenv("PDC_ORIGINAL_COLORS")) + default_colors = TRUE; + + PDC_init_atrtab(); + + return OK; +} + +static void _normalize(short *fg, short *bg) +{ + if (*fg == -1) + *fg = SP->orig_attr ? SP->orig_fore : COLOR_WHITE; + + if (*bg == -1) + *bg = SP->orig_attr ? SP->orig_back : COLOR_BLACK; +} + +static void _init_pair_core(short pair, short fg, short bg) +{ + PDC_PAIR *p = SP->atrtab + pair; + + _normalize(&fg, &bg); + + /* To allow the PDC_PRESERVE_SCREEN option to work, we only reset + curscr if this call to init_pair() alters a color pair created by + the user. */ + + if (p->set) + { + if (p->f != fg || p->b != bg) + curscr->_clear = TRUE; + } + + p->f = fg; + p->b = bg; + p->count = allocnum++; + p->set = TRUE; +} + +int init_pair(short pair, short fg, short bg) +{ + PDC_LOG(("init_pair() - called: pair %d fg %d bg %d\n", pair, fg, bg)); + + if (!SP || !SP->color_started || pair < 1 || pair >= COLOR_PAIRS || + fg < first_col || fg >= COLORS || bg < first_col || bg >= COLORS) + return ERR; + + _init_pair_core(pair, fg, bg); + + return OK; +} + +bool has_colors(void) +{ + PDC_LOG(("has_colors() - called\n")); + + return SP ? !(SP->mono) : FALSE; +} + +int init_color(short color, short red, short green, short blue) +{ + PDC_LOG(("init_color() - called\n")); + + if (!SP || color < 0 || color >= COLORS || !PDC_can_change_color() || + red < -1 || red > 1000 || green < -1 || green > 1000 || + blue < -1 || blue > 1000) + return ERR; + + SP->dirty = TRUE; + + return PDC_init_color(color, red, green, blue); +} + +int color_content(short color, short *red, short *green, short *blue) +{ + PDC_LOG(("color_content() - called\n")); + + if (color < 0 || color >= COLORS || !red || !green || !blue) + return ERR; + + if (PDC_can_change_color()) + return PDC_color_content(color, red, green, blue); + else + { + /* Simulated values for platforms that don't support palette + changing */ + + short maxval = (color & 8) ? 1000 : 680; + + *red = (color & COLOR_RED) ? maxval : 0; + *green = (color & COLOR_GREEN) ? maxval : 0; + *blue = (color & COLOR_BLUE) ? maxval : 0; + + return OK; + } +} + +bool can_change_color(void) +{ + PDC_LOG(("can_change_color() - called\n")); + + return PDC_can_change_color(); +} + +int pair_content(short pair, short *fg, short *bg) +{ + PDC_LOG(("pair_content() - called\n")); + + if (pair < 0 || pair >= COLOR_PAIRS || !fg || !bg) + return ERR; + + *fg = SP->atrtab[pair].f; + *bg = SP->atrtab[pair].b; + + return OK; +} + +int assume_default_colors(int f, int b) +{ + PDC_LOG(("assume_default_colors() - called: f %d b %d\n", f, b)); + + if (f < -1 || f >= COLORS || b < -1 || b >= COLORS) + return ERR; + + if (SP->color_started) + _init_pair_core(0, f, b); + + return OK; +} + +int use_default_colors(void) +{ + PDC_LOG(("use_default_colors() - called\n")); + + default_colors = TRUE; + first_col = -1; + + return assume_default_colors(-1, -1); +} + +int PDC_set_line_color(short color) +{ + PDC_LOG(("PDC_set_line_color() - called: %d\n", color)); + + if (!SP || color < -1 || color >= COLORS) + return ERR; + + SP->line_color = color; + + return OK; +} + +void PDC_init_atrtab(void) +{ + PDC_PAIR *p = SP->atrtab; + short i, fg, bg; + + if (SP->color_started && !default_colors) + { + fg = COLOR_WHITE; + bg = COLOR_BLACK; + } + else + fg = bg = -1; + + _normalize(&fg, &bg); + + for (i = 0; i < PDC_COLOR_PAIRS; i++) + { + p[i].f = fg; + p[i].b = bg; + p[i].set = FALSE; + } +} + +int free_pair(int pair) +{ + if (pair < 1 || pair >= PDC_COLOR_PAIRS || !(SP->atrtab[pair].set)) + return ERR; + + SP->atrtab[pair].set = FALSE; + return OK; +} + +int find_pair(int fg, int bg) +{ + int i; + PDC_PAIR *p = SP->atrtab; + + for (i = 0; i < PDC_COLOR_PAIRS; i++) + if (p[i].set && p[i].f == fg && p[i].b == bg) + return i; + + return -1; +} + +static int _find_oldest() +{ + int i, lowind = 0, lowval = 0; + PDC_PAIR *p = SP->atrtab; + + for (i = 1; i < PDC_COLOR_PAIRS; i++) + { + if (!p[i].set) + return i; + + if (!lowval || (p[i].count < lowval)) + { + lowind = i; + lowval = p[i].count; + } + } + + return lowind; +} + +int alloc_pair(int fg, int bg) +{ + int i = find_pair(fg, bg); + + if (-1 == i) + { + i = _find_oldest(); + + if (ERR == init_pair(i, fg, bg)) + return -1; + } + + return i; +} diff --git a/Utilities/cmpdcurses/pdcurses/debug.c b/Utilities/cmpdcurses/pdcurses/debug.c new file mode 100644 index 0000000..6444886 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/debug.c @@ -0,0 +1,106 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +debug +----- + +### Synopsis + + void traceon(void); + void traceoff(void); + void PDC_debug(const char *, ...); + +### Description + + traceon() and traceoff() toggle the recording of debugging + information to the file "trace". Although not standard, similar + functions are in some other curses implementations. + + PDC_debug() is the function that writes to the file, based on whether + traceon() has been called. It's used from the PDC_LOG() macro. + + The environment variable PDC_TRACE_FLUSH controls whether the trace + file contents are fflushed after each write. The default is not. Set + it to enable this (may affect performance). + +### Portability + X/Open ncurses NetBSD + traceon - - - + traceoff - - - + PDC_debug - - - + +**man-end****************************************************************/ + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> + +static bool want_fflush = FALSE; + +void PDC_debug(const char *fmt, ...) +{ + va_list args; + char hms[9]; + time_t now; + + if (!SP || !SP->dbfp) + return; + + time(&now); + strftime(hms, 9, "%H:%M:%S", localtime(&now)); + fprintf(SP->dbfp, "At: %8.8ld - %s ", (long) clock(), hms); + + va_start(args, fmt); + vfprintf(SP->dbfp, fmt, args); + va_end(args); + + /* If you are crashing and losing debugging information, enable this + by setting the environment variable PDC_TRACE_FLUSH. This may + impact performance. */ + + if (want_fflush) + fflush(SP->dbfp); + + /* If with PDC_TRACE_FLUSH enabled you are still losing logging in + crashes, you may need to add a platform-dependent mechanism to + flush the OS buffers as well (such as fsync() on POSIX) -- but + expect terrible performance. */ +} + +void traceon(void) +{ + if (!SP) + return; + + if (SP->dbfp) + fclose(SP->dbfp); + + /* open debug log file append */ + SP->dbfp = fopen("trace", "a"); + if (!SP->dbfp) + { + fprintf(stderr, "PDC_debug(): Unable to open debug log file\n"); + return; + } + + if (getenv("PDC_TRACE_FLUSH")) + want_fflush = TRUE; + + PDC_LOG(("traceon() - called\n")); +} + +void traceoff(void) +{ + if (!SP || !SP->dbfp) + return; + + PDC_LOG(("traceoff() - called\n")); + + fclose(SP->dbfp); + SP->dbfp = NULL; + want_fflush = FALSE; +} diff --git a/Utilities/cmpdcurses/pdcurses/delch.c b/Utilities/cmpdcurses/pdcurses/delch.c new file mode 100644 index 0000000..970a5a8 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/delch.c @@ -0,0 +1,96 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +delch +----- + +### Synopsis + + int delch(void); + int wdelch(WINDOW *win); + int mvdelch(int y, int x); + int mvwdelch(WINDOW *win, int y, int x); + +### Description + + The character under the cursor in the window is deleted. All + characters to the right on the same line are moved to the left one + position and the last character on the line is filled with a blank. + The cursor position does not change (after moving to y, x if + coordinates are specified). + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + delch Y Y Y + wdelch Y Y Y + mvdelch Y Y Y + mvwdelch Y Y Y + +**man-end****************************************************************/ + +#include <string.h> + +int wdelch(WINDOW *win) +{ + int y, x, maxx; + chtype *temp1; + + PDC_LOG(("wdelch() - called\n")); + + if (!win) + return ERR; + + y = win->_cury; + x = win->_curx; + maxx = win->_maxx - 1; + temp1 = &win->_y[y][x]; + + memmove(temp1, temp1 + 1, (maxx - x) * sizeof(chtype)); + + /* wrs (4/10/93) account for window background */ + + win->_y[y][maxx] = win->_bkgd; + + win->_lastch[y] = maxx; + + if ((win->_firstch[y] == _NO_CHANGE) || (win->_firstch[y] > x)) + win->_firstch[y] = x; + + PDC_sync(win); + + return OK; +} + +int delch(void) +{ + PDC_LOG(("delch() - called\n")); + + return wdelch(stdscr); +} + +int mvdelch(int y, int x) +{ + PDC_LOG(("mvdelch() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wdelch(stdscr); +} + +int mvwdelch(WINDOW *win, int y, int x) +{ + PDC_LOG(("mvwdelch() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wdelch(win); +} diff --git a/Utilities/cmpdcurses/pdcurses/deleteln.c b/Utilities/cmpdcurses/pdcurses/deleteln.c new file mode 100644 index 0000000..8e7563f --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/deleteln.c @@ -0,0 +1,211 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +deleteln +-------- + +### Synopsis + + int deleteln(void); + int wdeleteln(WINDOW *win); + int insdelln(int n); + int winsdelln(WINDOW *win, int n); + int insertln(void); + int winsertln(WINDOW *win); + + int mvdeleteln(int y, int x); + int mvwdeleteln(WINDOW *win, int y, int x); + int mvinsertln(int y, int x); + int mvwinsertln(WINDOW *win, int y, int x); + +### Description + + With the deleteln() and wdeleteln() functions, the line under the + cursor in the window is deleted. All lines below the current line are + moved up one line. The bottom line of the window is cleared. The + cursor position does not change. + + With the insertln() and winsertn() functions, a blank line is + inserted above the current line and the bottom line is lost. + + mvdeleteln(), mvwdeleteln(), mvinsertln() and mvwinsertln() allow + moving the cursor and inserting/deleting in one call. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + deleteln Y Y Y + wdeleteln Y Y Y + mvdeleteln - - - + mvwdeleteln - - - + insdelln Y Y Y + winsdelln Y Y Y + insertln Y Y Y + winsertln Y Y Y + mvinsertln - - - + mvwinsertln - - - + +**man-end****************************************************************/ + +int wdeleteln(WINDOW *win) +{ + chtype blank, *temp, *ptr; + int y; + + PDC_LOG(("wdeleteln() - called\n")); + + if (!win) + return ERR; + + /* wrs (4/10/93) account for window background */ + + blank = win->_bkgd; + + temp = win->_y[win->_cury]; + + for (y = win->_cury; y < win->_bmarg; y++) + { + win->_y[y] = win->_y[y + 1]; + win->_firstch[y] = 0; + win->_lastch[y] = win->_maxx - 1; + } + + for (ptr = temp; (ptr - temp < win->_maxx); ptr++) + *ptr = blank; /* make a blank line */ + + if (win->_cury <= win->_bmarg) + { + win->_firstch[win->_bmarg] = 0; + win->_lastch[win->_bmarg] = win->_maxx - 1; + win->_y[win->_bmarg] = temp; + } + + return OK; +} + +int deleteln(void) +{ + PDC_LOG(("deleteln() - called\n")); + + return wdeleteln(stdscr); +} + +int mvdeleteln(int y, int x) +{ + PDC_LOG(("mvdeleteln() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wdeleteln(stdscr); +} + +int mvwdeleteln(WINDOW *win, int y, int x) +{ + PDC_LOG(("mvwdeleteln() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wdeleteln(win); +} + +int winsdelln(WINDOW *win, int n) +{ + int i; + + PDC_LOG(("winsdelln() - called\n")); + + if (!win) + return ERR; + + if (n > 0) + { + for (i = 0; i < n; i++) + if (winsertln(win) == ERR) + return ERR; + } + else if (n < 0) + { + n = -n; + for (i = 0; i < n; i++) + if (wdeleteln(win) == ERR) + return ERR; + } + + return OK; +} + +int insdelln(int n) +{ + PDC_LOG(("insdelln() - called\n")); + + return winsdelln(stdscr, n); +} + +int winsertln(WINDOW *win) +{ + chtype blank, *temp, *end; + int y; + + PDC_LOG(("winsertln() - called\n")); + + if (!win) + return ERR; + + /* wrs (4/10/93) account for window background */ + + blank = win->_bkgd; + + temp = win->_y[win->_maxy - 1]; + + for (y = win->_maxy - 1; y > win->_cury; y--) + { + win->_y[y] = win->_y[y - 1]; + win->_firstch[y] = 0; + win->_lastch[y] = win->_maxx - 1; + } + + win->_y[win->_cury] = temp; + + for (end = &temp[win->_maxx - 1]; temp <= end; temp++) + *temp = blank; + + win->_firstch[win->_cury] = 0; + win->_lastch[win->_cury] = win->_maxx - 1; + + return OK; +} + +int insertln(void) +{ + PDC_LOG(("insertln() - called\n")); + + return winsertln(stdscr); +} + +int mvinsertln(int y, int x) +{ + PDC_LOG(("mvinsertln() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return winsertln(stdscr); +} + +int mvwinsertln(WINDOW *win, int y, int x) +{ + PDC_LOG(("mvwinsertln() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winsertln(win); +} diff --git a/Utilities/cmpdcurses/pdcurses/getch.c b/Utilities/cmpdcurses/pdcurses/getch.c new file mode 100644 index 0000000..58a44c2 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/getch.c @@ -0,0 +1,589 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +getch +----- + +### Synopsis + + int getch(void); + int wgetch(WINDOW *win); + int mvgetch(int y, int x); + int mvwgetch(WINDOW *win, int y, int x); + int ungetch(int ch); + int flushinp(void); + + int get_wch(wint_t *wch); + int wget_wch(WINDOW *win, wint_t *wch); + int mvget_wch(int y, int x, wint_t *wch); + int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch); + int unget_wch(const wchar_t wch); + + unsigned long PDC_get_key_modifiers(void); + int PDC_return_key_modifiers(bool flag); + +### Description + + With the getch(), wgetch(), mvgetch(), and mvwgetch() functions, a + character is read from the terminal associated with the window. In + nodelay mode, if there is no input waiting, the value ERR is + returned. In delay mode, the program will hang until the system + passes text through to the program. Depending on the setting of + cbreak(), this will be after one character or after the first + newline. Unless noecho() has been set, the character will also be + echoed into the designated window. + + If keypad() is TRUE, and a function key is pressed, the token for + that function key will be returned instead of the raw characters. + Possible function keys are defined in <curses.h> with integers + beginning with 0401, whose names begin with KEY_. + + If nodelay(win, TRUE) has been called on the window and no input is + waiting, the value ERR is returned. + + ungetch() places ch back onto the input queue to be returned by the + next call to wgetch(). + + flushinp() throws away any type-ahead that has been typed by the user + and has not yet been read by the program. + + wget_wch() is the wide-character version of wgetch(), available when + PDCurses is built with the PDC_WIDE option. It takes a pointer to a + wint_t rather than returning the key as an int, and instead returns + KEY_CODE_YES if the key is a function key. Otherwise, it returns OK + or ERR. It's important to check for KEY_CODE_YES, since regular wide + characters can have the same values as function key codes. + + unget_wch() puts a wide character on the input queue. + + PDC_get_key_modifiers() returns the keyboard modifiers (shift, + control, alt, numlock) effective at the time of the last getch() + call. Use the macros PDC_KEY_MODIFIER_* to determine which + modifier(s) were set. PDC_return_key_modifiers() tells getch() to + return modifier keys pressed alone as keystrokes (KEY_ALT_L, etc.). + These may not work on all platforms. + + NOTE: getch() and ungetch() are implemented as macros, to avoid + conflict with many DOS compiler's runtime libraries. + +### Return Value + + These functions return ERR or the value of the character, meta + character or function key token. + +### Portability + X/Open ncurses NetBSD + getch Y Y Y + wgetch Y Y Y + mvgetch Y Y Y + mvwgetch Y Y Y + ungetch Y Y Y + flushinp Y Y Y + get_wch Y Y Y + wget_wch Y Y Y + mvget_wch Y Y Y + mvwget_wch Y Y Y + unget_wch Y Y Y + PDC_get_key_modifiers - - - + +**man-end****************************************************************/ + +#include <stdlib.h> + +static int _get_box(int *y_start, int *y_end, int *x_start, int *x_end) +{ + int start, end; + + if (SP->sel_start < SP->sel_end) + { + start = SP->sel_start; + end = SP->sel_end; + } + else + { + start = SP->sel_end; + end = SP->sel_start; + } + + *y_start = start / COLS; + *x_start = start % COLS; + + *y_end = end / COLS; + *x_end = end % COLS; + + return (end - start) + (*y_end - *y_start); +} + +static void _highlight(void) +{ + int i, j, y_start, y_end, x_start, x_end; + + if (-1 == SP->sel_start) + return; + + _get_box(&y_start, &y_end, &x_start, &x_end); + + for (j = y_start; j <= y_end; j++) + for (i = (j == y_start ? x_start : 0); + i < (j == y_end ? x_end : COLS); i++) + curscr->_y[j][i] ^= A_REVERSE; + + wrefresh(curscr); +} + +static void _copy(void) +{ +#ifdef PDC_WIDE + wchar_t *wtmp; +# define TMP wtmp +# define MASK A_CHARTEXT +#else +# define TMP tmp +# define MASK 0xff +#endif + char *tmp; + long pos; + int i, j, y_start, y_end, x_start, x_end, len; + + if (-1 == SP->sel_start) + return; + + len = _get_box(&y_start, &y_end, &x_start, &x_end); + + if (!len) + return; + +#ifdef PDC_WIDE + wtmp = malloc((len + 1) * sizeof(wchar_t)); + len *= 3; +#endif + tmp = malloc(len + 1); + + for (j = y_start, pos = 0; j <= y_end; j++) + { + for (i = (j == y_start ? x_start : 0); + i < (j == y_end ? x_end : COLS); i++) + TMP[pos++] = curscr->_y[j][i] & MASK; + + while (y_start != y_end && pos > 0 && TMP[pos - 1] == 32) + pos--; + + if (j < y_end) + TMP[pos++] = 10; + } + TMP[pos] = 0; + +#ifdef PDC_WIDE + pos = PDC_wcstombs(tmp, wtmp, len); +#endif + + PDC_setclipboard(tmp, pos); + free(tmp); +#ifdef PDC_WIDE + free(wtmp); +#endif +} + +static int _paste(void) +{ +#ifdef PDC_WIDE + wchar_t *wpaste; +# define PASTE wpaste +#else +# define PASTE paste +#endif + char *paste; + long len, newmax; + int key; + + key = PDC_getclipboard(&paste, &len); + if (PDC_CLIP_SUCCESS != key || !len) + return -1; + +#ifdef PDC_WIDE + wpaste = malloc(len * sizeof(wchar_t)); + len = PDC_mbstowcs(wpaste, paste, len); +#endif + newmax = len + SP->c_ungind; + if (newmax > SP->c_ungmax) + { + SP->c_ungch = realloc(SP->c_ungch, newmax * sizeof(int)); + if (!SP->c_ungch) + return -1; + SP->c_ungmax = newmax; + } + while (len > 1) + PDC_ungetch(PASTE[--len]); + key = *PASTE; +#ifdef PDC_WIDE + free(wpaste); +#endif + PDC_freeclipboard(paste); + SP->key_modifiers = 0; + + return key; +} + +static int _mouse_key(void) +{ + int i, key = KEY_MOUSE, changes = SP->mouse_status.changes; + unsigned long mbe = SP->_trap_mbe; + + /* Selection highlighting? */ + + if ((!mbe || SP->mouse_status.button[0] & BUTTON_SHIFT) && changes & 1) + { + i = SP->mouse_status.y * COLS + SP->mouse_status.x; + switch (SP->mouse_status.button[0] & BUTTON_ACTION_MASK) + { + case BUTTON_PRESSED: + _highlight(); + SP->sel_start = SP->sel_end = i; + return -1; + case BUTTON_MOVED: + _highlight(); + SP->sel_end = i; + _highlight(); + return -1; + case BUTTON_RELEASED: + _copy(); + return -1; + } + } + else if ((!mbe || SP->mouse_status.button[1] & BUTTON_SHIFT) && + changes & 2 && (SP->mouse_status.button[1] & + BUTTON_ACTION_MASK) == BUTTON_CLICKED) + { + SP->key_code = FALSE; + return _paste(); + } + + /* Filter unwanted mouse events */ + + for (i = 0; i < 3; i++) + { + if (changes & (1 << i)) + { + int shf = i * 5; + short button = SP->mouse_status.button[i] & BUTTON_ACTION_MASK; + + if ( (!(mbe & (BUTTON1_PRESSED << shf)) && + (button == BUTTON_PRESSED)) + + || (!(mbe & (BUTTON1_CLICKED << shf)) && + (button == BUTTON_CLICKED)) + + || (!(mbe & (BUTTON1_DOUBLE_CLICKED << shf)) && + (button == BUTTON_DOUBLE_CLICKED)) + + || (!(mbe & (BUTTON1_MOVED << shf)) && + (button == BUTTON_MOVED)) + + || (!(mbe & (BUTTON1_RELEASED << shf)) && + (button == BUTTON_RELEASED)) + ) + SP->mouse_status.changes ^= (1 << i); + } + } + + if (changes & PDC_MOUSE_MOVED) + { + if (!(mbe & (BUTTON1_MOVED|BUTTON2_MOVED|BUTTON3_MOVED))) + SP->mouse_status.changes ^= PDC_MOUSE_MOVED; + } + + if (changes & (PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN)) + { + if (!(mbe & MOUSE_WHEEL_SCROLL)) + SP->mouse_status.changes &= + ~(PDC_MOUSE_WHEEL_UP|PDC_MOUSE_WHEEL_DOWN); + } + + if (!changes) + return -1; + + /* Check for click in slk area */ + + i = PDC_mouse_in_slk(SP->mouse_status.y, SP->mouse_status.x); + + if (i) + { + if (SP->mouse_status.button[0] & (BUTTON_PRESSED|BUTTON_CLICKED)) + key = KEY_F(i); + else + key = -1; + } + + return key; +} + +int wgetch(WINDOW *win) +{ + int key, waitcount; + + PDC_LOG(("wgetch() - called\n")); + + if (!win || !SP) + return ERR; + + waitcount = 0; + + /* set the number of 1/20th second napms() calls */ + + if (SP->delaytenths) + waitcount = 2 * SP->delaytenths; + else + if (win->_delayms) + { + /* Can't really do millisecond intervals, so delay in + 1/20ths of a second (50ms) */ + + waitcount = win->_delayms / 50; + if (!waitcount) + waitcount = 1; + } + + /* refresh window when wgetch is called if there have been changes + to it and it is not a pad */ + + if (!(win->_flags & _PAD) && ((!win->_leaveit && + (win->_begx + win->_curx != SP->curscol || + win->_begy + win->_cury != SP->cursrow)) || is_wintouched(win))) + wrefresh(win); + + /* if ungotten char exists, remove and return it */ + + if (SP->c_ungind) + return SP->c_ungch[--(SP->c_ungind)]; + + /* if normal and data in buffer */ + + if ((!SP->raw_inp && !SP->cbreak) && (SP->c_gindex < SP->c_pindex)) + return SP->c_buffer[SP->c_gindex++]; + + /* prepare to buffer data */ + + SP->c_pindex = 0; + SP->c_gindex = 0; + + /* to get here, no keys are buffered. go and get one. */ + + for (;;) /* loop for any buffering */ + { + /* is there a keystroke ready? */ + + if (!PDC_check_key()) + { + /* if not, handle timeout() and halfdelay() */ + + if (SP->delaytenths || win->_delayms) + { + if (!waitcount) + return ERR; + + waitcount--; + } + else + if (win->_nodelay) + return ERR; + + napms(50); /* sleep for 1/20th second */ + continue; /* then check again */ + } + + /* if there is, fetch it */ + + key = PDC_get_key(); + + /* copy or paste? */ + + if (SP->key_modifiers & PDC_KEY_MODIFIER_SHIFT) + { + if (0x03 == key) + { + _copy(); + continue; + } + else if (0x16 == key) + key = _paste(); + } + + /* filter mouse events; translate mouse clicks in the slk + area to function keys */ + + if (SP->key_code && key == KEY_MOUSE) + key = _mouse_key(); + + /* filter special keys if not in keypad mode */ + + if (SP->key_code && !win->_use_keypad) + key = -1; + + /* unwanted key? loop back */ + + if (key == -1) + continue; + + _highlight(); + SP->sel_start = SP->sel_end = -1; + + /* translate CR */ + + if (key == '\r' && SP->autocr && !SP->raw_inp) + key = '\n'; + + /* if echo is enabled */ + + if (SP->echo && !SP->key_code) + { + waddch(win, key); + wrefresh(win); + } + + /* if no buffering */ + + if (SP->raw_inp || SP->cbreak) + return key; + + /* if no overflow, put data in buffer */ + + if (key == '\b') + { + if (SP->c_pindex > SP->c_gindex) + SP->c_pindex--; + } + else + if (SP->c_pindex < _INBUFSIZ - 2) + SP->c_buffer[SP->c_pindex++] = key; + + /* if we got a line */ + + if (key == '\n' || key == '\r') + return SP->c_buffer[SP->c_gindex++]; + } +} + +int mvgetch(int y, int x) +{ + PDC_LOG(("mvgetch() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wgetch(stdscr); +} + +int mvwgetch(WINDOW *win, int y, int x) +{ + PDC_LOG(("mvwgetch() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wgetch(win); +} + +int PDC_ungetch(int ch) +{ + PDC_LOG(("ungetch() - called\n")); + + if (SP->c_ungind >= SP->c_ungmax) /* pushback stack full */ + return ERR; + + SP->c_ungch[SP->c_ungind++] = ch; + + return OK; +} + +int flushinp(void) +{ + PDC_LOG(("flushinp() - called\n")); + + if (!SP) + return ERR; + + PDC_flushinp(); + + SP->c_gindex = 1; /* set indices to kill buffer */ + SP->c_pindex = 0; + SP->c_ungind = 0; /* clear SP->c_ungch array */ + + return OK; +} + +unsigned long PDC_get_key_modifiers(void) +{ + PDC_LOG(("PDC_get_key_modifiers() - called\n")); + + if (!SP) + return ERR; + + return SP->key_modifiers; +} + +int PDC_return_key_modifiers(bool flag) +{ + PDC_LOG(("PDC_return_key_modifiers() - called\n")); + + if (!SP) + return ERR; + + SP->return_key_modifiers = flag; + return PDC_modifiers_set(); +} + +#ifdef PDC_WIDE +int wget_wch(WINDOW *win, wint_t *wch) +{ + int key; + + PDC_LOG(("wget_wch() - called\n")); + + if (!wch) + return ERR; + + key = wgetch(win); + + if (key == ERR) + return ERR; + + *wch = key; + + return SP->key_code ? KEY_CODE_YES : OK; +} + +int get_wch(wint_t *wch) +{ + PDC_LOG(("get_wch() - called\n")); + + return wget_wch(stdscr, wch); +} + +int mvget_wch(int y, int x, wint_t *wch) +{ + PDC_LOG(("mvget_wch() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wget_wch(stdscr, wch); +} + +int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch) +{ + PDC_LOG(("mvwget_wch() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wget_wch(win, wch); +} + +int unget_wch(const wchar_t wch) +{ + return PDC_ungetch(wch); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/getstr.c b/Utilities/cmpdcurses/pdcurses/getstr.c new file mode 100644 index 0000000..603769f --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/getstr.c @@ -0,0 +1,473 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +getstr +------ + +### Synopsis + + int getstr(char *str); + int wgetstr(WINDOW *win, char *str); + int mvgetstr(int y, int x, char *str); + int mvwgetstr(WINDOW *win, int y, int x, char *str); + int getnstr(char *str, int n); + int wgetnstr(WINDOW *win, char *str, int n); + int mvgetnstr(int y, int x, char *str, int n); + int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n); + + int get_wstr(wint_t *wstr); + int wget_wstr(WINDOW *win, wint_t *wstr); + int mvget_wstr(int y, int x, wint_t *wstr); + int mvwget_wstr(WINDOW *win, int, int, wint_t *wstr); + int getn_wstr(wint_t *wstr, int n); + int wgetn_wstr(WINDOW *win, wint_t *wstr, int n); + int mvgetn_wstr(int y, int x, wint_t *wstr, int n); + int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n); + +### Description + + These routines call wgetch() repeatedly to build a string, + interpreting erase and kill characters along the way, until a newline + or carriage return is received. When PDCurses is built with wide- + character support enabled, the narrow-character functions convert the + wgetch()'d values into a multibyte string in the current locale + before returning it. The resulting string is placed in the area + pointed to by *str. The routines with n as the last argument read at + most n characters. + + Note that there's no way to know how long the buffer passed to + wgetstr() is, so use wgetnstr() to avoid buffer overflows. + +### Return Value + + These functions return ERR on failure or any other value on success. + +### Portability + X/Open ncurses NetBSD + getstr Y Y Y + wgetstr Y Y Y + mvgetstr Y Y Y + mvwgetstr Y Y Y + getnstr Y Y Y + wgetnstr Y Y Y + mvgetnstr Y Y Y + mvwgetnstr Y Y Y + get_wstr Y Y Y + wget_wstr Y Y Y + mvget_wstr Y Y Y + mvwget_wstr Y Y Y + getn_wstr Y Y Y + wgetn_wstr Y Y Y + mvgetn_wstr Y Y Y + mvwgetn_wstr Y Y Y + +**man-end****************************************************************/ + +#define MAXLINE 255 + +int wgetnstr(WINDOW *win, char *str, int n) +{ +#ifdef PDC_WIDE + wchar_t wstr[MAXLINE + 1]; + + if (n < 0 || n > MAXLINE) + n = MAXLINE; + + if (wgetn_wstr(win, (wint_t *)wstr, n) == ERR) + return ERR; + + return PDC_wcstombs(str, wstr, n); +#else + int ch, i, num, x, chars; + char *p; + bool stop, oldecho, oldcbreak, oldnodelay; + + PDC_LOG(("wgetnstr() - called\n")); + + if (!win || !str) + return ERR; + + chars = 0; + p = str; + stop = FALSE; + + x = win->_curx; + + oldcbreak = SP->cbreak; /* remember states */ + oldecho = SP->echo; + oldnodelay = win->_nodelay; + + SP->echo = FALSE; /* we do echo ourselves */ + cbreak(); /* ensure each key is returned immediately */ + win->_nodelay = FALSE; /* don't return -1 */ + + wrefresh(win); + + while (!stop) + { + ch = wgetch(win); + + switch (ch) + { + + case '\t': + ch = ' '; + num = TABSIZE - (win->_curx - x) % TABSIZE; + for (i = 0; i < num; i++) + { + if (chars < n) + { + if (oldecho) + waddch(win, ch); + *p++ = ch; + ++chars; + } + else + beep(); + } + break; + + case _ECHAR: /* CTRL-H -- Delete character */ + if (p > str) + { + if (oldecho) + waddstr(win, "\b \b"); + ch = (unsigned char)(*--p); + if ((ch < ' ') && (oldecho)) + waddstr(win, "\b \b"); + chars--; + } + break; + + case _DLCHAR: /* CTRL-U -- Delete line */ + while (p > str) + { + if (oldecho) + waddstr(win, "\b \b"); + ch = (unsigned char)(*--p); + if ((ch < ' ') && (oldecho)) + waddstr(win, "\b \b"); + } + chars = 0; + break; + + case _DWCHAR: /* CTRL-W -- Delete word */ + + while ((p > str) && (*(p - 1) == ' ')) + { + if (oldecho) + waddstr(win, "\b \b"); + + --p; /* remove space */ + chars--; + } + while ((p > str) && (*(p - 1) != ' ')) + { + if (oldecho) + waddstr(win, "\b \b"); + + ch = (unsigned char)(*--p); + if ((ch < ' ') && (oldecho)) + waddstr(win, "\b \b"); + chars--; + } + break; + + case '\n': + case '\r': + stop = TRUE; + if (oldecho) + waddch(win, '\n'); + break; + + default: + if (chars < n) + { + if (!SP->key_code && ch < 0x100) + { + *p++ = ch; + if (oldecho) + waddch(win, ch); + chars++; + } + } + else + beep(); + + break; + + } + + wrefresh(win); + } + + *p = '\0'; + + SP->echo = oldecho; /* restore old settings */ + SP->cbreak = oldcbreak; + win->_nodelay = oldnodelay; + + return OK; +#endif +} + +int getstr(char *str) +{ + PDC_LOG(("getstr() - called\n")); + + return wgetnstr(stdscr, str, MAXLINE); +} + +int wgetstr(WINDOW *win, char *str) +{ + PDC_LOG(("wgetstr() - called\n")); + + return wgetnstr(win, str, MAXLINE); +} + +int mvgetstr(int y, int x, char *str) +{ + PDC_LOG(("mvgetstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wgetnstr(stdscr, str, MAXLINE); +} + +int mvwgetstr(WINDOW *win, int y, int x, char *str) +{ + PDC_LOG(("mvwgetstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wgetnstr(win, str, MAXLINE); +} + +int getnstr(char *str, int n) +{ + PDC_LOG(("getnstr() - called\n")); + + return wgetnstr(stdscr, str, n); +} + +int mvgetnstr(int y, int x, char *str, int n) +{ + PDC_LOG(("mvgetnstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wgetnstr(stdscr, str, n); +} + +int mvwgetnstr(WINDOW *win, int y, int x, char *str, int n) +{ + PDC_LOG(("mvwgetnstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wgetnstr(win, str, n); +} + +#ifdef PDC_WIDE +int wgetn_wstr(WINDOW *win, wint_t *wstr, int n) +{ + int ch, i, num, x, chars; + wint_t *p; + bool stop, oldecho, oldcbreak, oldnodelay; + + PDC_LOG(("wgetn_wstr() - called\n")); + + if (!win || !wstr) + return ERR; + + chars = 0; + p = wstr; + stop = FALSE; + + x = win->_curx; + + oldcbreak = SP->cbreak; /* remember states */ + oldecho = SP->echo; + oldnodelay = win->_nodelay; + + SP->echo = FALSE; /* we do echo ourselves */ + cbreak(); /* ensure each key is returned immediately */ + win->_nodelay = FALSE; /* don't return -1 */ + + wrefresh(win); + + while (!stop) + { + ch = wgetch(win); + + switch (ch) + { + + case '\t': + ch = ' '; + num = TABSIZE - (win->_curx - x) % TABSIZE; + for (i = 0; i < num; i++) + { + if (chars < n) + { + if (oldecho) + waddch(win, ch); + *p++ = ch; + ++chars; + } + else + beep(); + } + break; + + case _ECHAR: /* CTRL-H -- Delete character */ + if (p > wstr) + { + if (oldecho) + waddstr(win, "\b \b"); + ch = *--p; + if ((ch < ' ') && (oldecho)) + waddstr(win, "\b \b"); + chars--; + } + break; + + case _DLCHAR: /* CTRL-U -- Delete line */ + while (p > wstr) + { + if (oldecho) + waddstr(win, "\b \b"); + ch = *--p; + if ((ch < ' ') && (oldecho)) + waddstr(win, "\b \b"); + } + chars = 0; + break; + + case _DWCHAR: /* CTRL-W -- Delete word */ + + while ((p > wstr) && (*(p - 1) == ' ')) + { + if (oldecho) + waddstr(win, "\b \b"); + + --p; /* remove space */ + chars--; + } + while ((p > wstr) && (*(p - 1) != ' ')) + { + if (oldecho) + waddstr(win, "\b \b"); + + ch = *--p; + if ((ch < ' ') && (oldecho)) + waddstr(win, "\b \b"); + chars--; + } + break; + + case '\n': + case '\r': + stop = TRUE; + if (oldecho) + waddch(win, '\n'); + break; + + default: + if (chars < n) + { + if (!SP->key_code) + { + *p++ = ch; + if (oldecho) + waddch(win, ch); + chars++; + } + } + else + beep(); + + break; + + } + + wrefresh(win); + } + + *p = '\0'; + + SP->echo = oldecho; /* restore old settings */ + SP->cbreak = oldcbreak; + win->_nodelay = oldnodelay; + + return OK; +} + +int get_wstr(wint_t *wstr) +{ + PDC_LOG(("get_wstr() - called\n")); + + return wgetn_wstr(stdscr, wstr, MAXLINE); +} + +int wget_wstr(WINDOW *win, wint_t *wstr) +{ + PDC_LOG(("wget_wstr() - called\n")); + + return wgetn_wstr(win, wstr, MAXLINE); +} + +int mvget_wstr(int y, int x, wint_t *wstr) +{ + PDC_LOG(("mvget_wstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wgetn_wstr(stdscr, wstr, MAXLINE); +} + +int mvwget_wstr(WINDOW *win, int y, int x, wint_t *wstr) +{ + PDC_LOG(("mvwget_wstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wgetn_wstr(win, wstr, MAXLINE); +} + +int getn_wstr(wint_t *wstr, int n) +{ + PDC_LOG(("getn_wstr() - called\n")); + + return wgetn_wstr(stdscr, wstr, n); +} + +int mvgetn_wstr(int y, int x, wint_t *wstr, int n) +{ + PDC_LOG(("mvgetn_wstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wgetn_wstr(stdscr, wstr, n); +} + +int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n) +{ + PDC_LOG(("mvwgetn_wstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wgetn_wstr(win, wstr, n); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/getyx.c b/Utilities/cmpdcurses/pdcurses/getyx.c new file mode 100644 index 0000000..9400076 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/getyx.c @@ -0,0 +1,142 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +getyx +----- + +### Synopsis + + void getyx(WINDOW *win, int y, int x); + void getparyx(WINDOW *win, int y, int x); + void getbegyx(WINDOW *win, int y, int x); + void getmaxyx(WINDOW *win, int y, int x); + + void getsyx(int y, int x); + void setsyx(int y, int x); + + int getbegy(WINDOW *win); + int getbegx(WINDOW *win); + int getcury(WINDOW *win); + int getcurx(WINDOW *win); + int getpary(WINDOW *win); + int getparx(WINDOW *win); + int getmaxy(WINDOW *win); + int getmaxx(WINDOW *win); + +### Description + + The getyx() macro (defined in curses.h -- the prototypes here are + merely illustrative) puts the current cursor position of the + specified window into y and x. getbegyx() and getmaxyx() return the + starting coordinates and size of the specified window, respectively. + getparyx() returns the starting coordinates of the parent's window, + if the specified window is a subwindow; otherwise it sets y and x to + -1. These are all macros. + + getsyx() gets the coordinates of the virtual screen cursor, and + stores them in y and x. If leaveok() is TRUE, it returns -1, -1. If + lines have been removed with ripoffline(), then getsyx() includes + these lines in its count; so, the returned y and x values should only + be used with setsyx(). + + setsyx() sets the virtual screen cursor to the y, x coordinates. If + either y or x is -1, leaveok() is set TRUE, else it's set FALSE. + + getsyx() and setsyx() are meant to be used by a library routine that + manipulates curses windows without altering the position of the + cursor. Note that getsyx() is defined only as a macro. + + getbegy(), getbegx(), getcurx(), getcury(), getmaxy(), getmaxx(), + getpary(), and getparx() return the appropriate coordinate or size + values, or ERR in the case of a NULL window. + +### Portability + X/Open ncurses NetBSD + getyx Y Y Y + getparyx Y Y Y + getbegyx Y Y Y + getmaxyx Y Y Y + getsyx - Y Y + setsyx - Y Y + getbegy - Y Y + getbegx - Y Y + getcury - Y Y + getcurx - Y Y + getpary - Y Y + getparx - Y Y + getmaxy - Y Y + getmaxx - Y Y + +**man-end****************************************************************/ + +int getbegy(WINDOW *win) +{ + PDC_LOG(("getbegy() - called\n")); + + return win ? win->_begy : ERR; +} + +int getbegx(WINDOW *win) +{ + PDC_LOG(("getbegx() - called\n")); + + return win ? win->_begx : ERR; +} + +int getcury(WINDOW *win) +{ + PDC_LOG(("getcury() - called\n")); + + return win ? win->_cury : ERR; +} + +int getcurx(WINDOW *win) +{ + PDC_LOG(("getcurx() - called\n")); + + return win ? win->_curx : ERR; +} + +int getpary(WINDOW *win) +{ + PDC_LOG(("getpary() - called\n")); + + return win ? win->_pary : ERR; +} + +int getparx(WINDOW *win) +{ + PDC_LOG(("getparx() - called\n")); + + return win ? win->_parx : ERR; +} + +int getmaxy(WINDOW *win) +{ + PDC_LOG(("getmaxy() - called\n")); + + return win ? win->_maxy : ERR; +} + +int getmaxx(WINDOW *win) +{ + PDC_LOG(("getmaxx() - called\n")); + + return win ? win->_maxx : ERR; +} + +void setsyx(int y, int x) +{ + PDC_LOG(("setsyx() - called\n")); + + if (curscr) + { + curscr->_leaveit = y == -1 || x == -1; + + if (!curscr->_leaveit) + wmove(curscr, y, x); + } +} diff --git a/Utilities/cmpdcurses/pdcurses/inch.c b/Utilities/cmpdcurses/pdcurses/inch.c new file mode 100644 index 0000000..e3275a8 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/inch.c @@ -0,0 +1,126 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +inch +---- + +### Synopsis + + chtype inch(void); + chtype winch(WINDOW *win); + chtype mvinch(int y, int x); + chtype mvwinch(WINDOW *win, int y, int x); + + int in_wch(cchar_t *wcval); + int win_wch(WINDOW *win, cchar_t *wcval); + int mvin_wch(int y, int x, cchar_t *wcval); + int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval); + +### Description + + The inch() functions retrieve the character and attribute from the + current or specified window position, in the form of a chtype. If a + NULL window is specified, (chtype)ERR is returned. + + The in_wch() functions are the wide-character versions; instead of + returning a chtype, they store a cchar_t at the address specified by + wcval, and return OK or ERR. (No value is stored when ERR is + returned.) Note that in PDCurses, chtype and cchar_t are the same. + +### Portability + X/Open ncurses NetBSD + inch Y Y Y + winch Y Y Y + mvinch Y Y Y + mvwinch Y Y Y + in_wch Y Y Y + win_wch Y Y Y + mvin_wch Y Y Y + mvwin_wch Y Y Y + +**man-end****************************************************************/ + +chtype winch(WINDOW *win) +{ + PDC_LOG(("winch() - called\n")); + + if (!win) + return (chtype)ERR; + + return win->_y[win->_cury][win->_curx]; +} + +chtype inch(void) +{ + PDC_LOG(("inch() - called\n")); + + return winch(stdscr); +} + +chtype mvinch(int y, int x) +{ + PDC_LOG(("mvinch() - called\n")); + + if (move(y, x) == ERR) + return (chtype)ERR; + + return stdscr->_y[stdscr->_cury][stdscr->_curx]; +} + +chtype mvwinch(WINDOW *win, int y, int x) +{ + PDC_LOG(("mvwinch() - called\n")); + + if (wmove(win, y, x) == ERR) + return (chtype)ERR; + + return win->_y[win->_cury][win->_curx]; +} + +#ifdef PDC_WIDE +int win_wch(WINDOW *win, cchar_t *wcval) +{ + PDC_LOG(("win_wch() - called\n")); + + if (!win || !wcval) + return ERR; + + *wcval = win->_y[win->_cury][win->_curx]; + + return OK; +} + +int in_wch(cchar_t *wcval) +{ + PDC_LOG(("in_wch() - called\n")); + + return win_wch(stdscr, wcval); +} + +int mvin_wch(int y, int x, cchar_t *wcval) +{ + PDC_LOG(("mvin_wch() - called\n")); + + if (!wcval || (move(y, x) == ERR)) + return ERR; + + *wcval = stdscr->_y[stdscr->_cury][stdscr->_curx]; + + return OK; +} + +int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval) +{ + PDC_LOG(("mvwin_wch() - called\n")); + + if (!wcval || (wmove(win, y, x) == ERR)) + return ERR; + + *wcval = win->_y[win->_cury][win->_curx]; + + return OK; +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/inchstr.c b/Utilities/cmpdcurses/pdcurses/inchstr.c new file mode 100644 index 0000000..97a0083 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/inchstr.c @@ -0,0 +1,213 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +inchstr +------- + +### Synopsis + + int inchstr(chtype *ch); + int inchnstr(chtype *ch, int n); + int winchstr(WINDOW *win, chtype *ch); + int winchnstr(WINDOW *win, chtype *ch, int n); + int mvinchstr(int y, int x, chtype *ch); + int mvinchnstr(int y, int x, chtype *ch, int n); + int mvwinchstr(WINDOW *, int y, int x, chtype *ch); + int mvwinchnstr(WINDOW *, int y, int x, chtype *ch, int n); + + int in_wchstr(cchar_t *wch); + int in_wchnstr(cchar_t *wch, int n); + int win_wchstr(WINDOW *win, cchar_t *wch); + int win_wchnstr(WINDOW *win, cchar_t *wch, int n); + int mvin_wchstr(int y, int x, cchar_t *wch); + int mvin_wchnstr(int y, int x, cchar_t *wch, int n); + int mvwin_wchstr(WINDOW *win, int y, int x, cchar_t *wch); + int mvwin_wchnstr(WINDOW *win, int y, int x, cchar_t *wch, int n); + +### Description + + These routines read a chtype or cchar_t string from the window, + starting at the current or specified position, and ending at the + right margin, or after n elements, whichever is less. + +### Return Value + + All functions return the number of elements read, or ERR on error. + +### Portability + X/Open ncurses NetBSD + inchstr Y Y Y + winchstr Y Y Y + mvinchstr Y Y Y + mvwinchstr Y Y Y + inchnstr Y Y Y + winchnstr Y Y Y + mvinchnstr Y Y Y + mvwinchnstr Y Y Y + in_wchstr Y Y Y + win_wchstr Y Y Y + mvin_wchstr Y Y Y + mvwin_wchstr Y Y Y + in_wchnstr Y Y Y + win_wchnstr Y Y Y + mvin_wchnstr Y Y Y + mvwin_wchnstr Y Y Y + +**man-end****************************************************************/ + +int winchnstr(WINDOW *win, chtype *ch, int n) +{ + chtype *src; + int i; + + PDC_LOG(("winchnstr() - called\n")); + + if (!win || !ch || n < 0) + return ERR; + + if ((win->_curx + n) > win->_maxx) + n = win->_maxx - win->_curx; + + src = win->_y[win->_cury] + win->_curx; + + for (i = 0; i < n; i++) + *ch++ = *src++; + + *ch = (chtype)0; + + return OK; +} + +int inchstr(chtype *ch) +{ + PDC_LOG(("inchstr() - called\n")); + + return winchnstr(stdscr, ch, stdscr->_maxx - stdscr->_curx); +} + +int winchstr(WINDOW *win, chtype *ch) +{ + PDC_LOG(("winchstr() - called\n")); + + return winchnstr(win, ch, win->_maxx - win->_curx); +} + +int mvinchstr(int y, int x, chtype *ch) +{ + PDC_LOG(("mvinchstr() - called: y %d x %d\n", y, x)); + + if (move(y, x) == ERR) + return ERR; + + return winchnstr(stdscr, ch, stdscr->_maxx - stdscr->_curx); +} + +int mvwinchstr(WINDOW *win, int y, int x, chtype *ch) +{ + PDC_LOG(("mvwinchstr() - called:\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winchnstr(win, ch, win->_maxx - win->_curx); +} + +int inchnstr(chtype *ch, int n) +{ + PDC_LOG(("inchnstr() - called\n")); + + return winchnstr(stdscr, ch, n); +} + +int mvinchnstr(int y, int x, chtype *ch, int n) +{ + PDC_LOG(("mvinchnstr() - called: y %d x %d n %d\n", y, x, n)); + + if (move(y, x) == ERR) + return ERR; + + return winchnstr(stdscr, ch, n); +} + +int mvwinchnstr(WINDOW *win, int y, int x, chtype *ch, int n) +{ + PDC_LOG(("mvwinchnstr() - called: y %d x %d n %d \n", y, x, n)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winchnstr(win, ch, n); +} + +#ifdef PDC_WIDE +int win_wchnstr(WINDOW *win, cchar_t *wch, int n) +{ + PDC_LOG(("win_wchnstr() - called\n")); + + return winchnstr(win, wch, n); +} + +int in_wchstr(cchar_t *wch) +{ + PDC_LOG(("in_wchstr() - called\n")); + + return win_wchnstr(stdscr, wch, stdscr->_maxx - stdscr->_curx); +} + +int win_wchstr(WINDOW *win, cchar_t *wch) +{ + PDC_LOG(("win_wchstr() - called\n")); + + return win_wchnstr(win, wch, win->_maxx - win->_curx); +} + +int mvin_wchstr(int y, int x, cchar_t *wch) +{ + PDC_LOG(("mvin_wchstr() - called: y %d x %d\n", y, x)); + + if (move(y, x) == ERR) + return ERR; + + return win_wchnstr(stdscr, wch, stdscr->_maxx - stdscr->_curx); +} + +int mvwin_wchstr(WINDOW *win, int y, int x, cchar_t *wch) +{ + PDC_LOG(("mvwin_wchstr() - called:\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return win_wchnstr(win, wch, win->_maxx - win->_curx); +} + +int in_wchnstr(cchar_t *wch, int n) +{ + PDC_LOG(("in_wchnstr() - called\n")); + + return win_wchnstr(stdscr, wch, n); +} + +int mvin_wchnstr(int y, int x, cchar_t *wch, int n) +{ + PDC_LOG(("mvin_wchnstr() - called: y %d x %d n %d\n", y, x, n)); + + if (move(y, x) == ERR) + return ERR; + + return win_wchnstr(stdscr, wch, n); +} + +int mvwin_wchnstr(WINDOW *win, int y, int x, cchar_t *wch, int n) +{ + PDC_LOG(("mvwinchnstr() - called: y %d x %d n %d \n", y, x, n)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return win_wchnstr(win, wch, n); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/initscr.c b/Utilities/cmpdcurses/pdcurses/initscr.c new file mode 100644 index 0000000..e9a62ac --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/initscr.c @@ -0,0 +1,431 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +initscr +------- + +### Synopsis + + WINDOW *initscr(void); + WINDOW *Xinitscr(int argc, char **argv); + int endwin(void); + bool isendwin(void); + SCREEN *newterm(const char *type, FILE *outfd, FILE *infd); + SCREEN *set_term(SCREEN *new); + void delscreen(SCREEN *sp); + + int resize_term(int nlines, int ncols); + bool is_termresized(void); + const char *curses_version(void); + void PDC_get_version(PDC_VERSION *ver); + + int set_tabsize(int tabsize); + +### Description + + initscr() should be the first curses routine called. It will + initialize all curses data structures, and arrange that the first + call to refresh() will clear the screen. In case of error, initscr() + will write a message to standard error and end the program. + + endwin() should be called before exiting or escaping from curses mode + temporarily. It will restore tty modes, move the cursor to the lower + left corner of the screen and reset the terminal into the proper + non-visual mode. To resume curses after a temporary escape, call + refresh() or doupdate(). + + isendwin() returns TRUE if endwin() has been called without a + subsequent refresh, unless SP is NULL. + + In some implementations of curses, newterm() allows the use of + multiple terminals. Here, it's just an alternative interface for + initscr(). It always returns SP, or NULL. + + delscreen() frees the memory allocated by newterm() or initscr(), + since it's not freed by endwin(). This function is usually not + needed. In PDCurses, the parameter must be the value of SP, and + delscreen() sets SP to NULL. + + set_term() does nothing meaningful in PDCurses, but is included for + compatibility with other curses implementations. + + resize_term() is effectively two functions: When called with nonzero + values for nlines and ncols, it attempts to resize the screen to the + given size. When called with (0, 0), it merely adjusts the internal + structures to match the current size after the screen is resized by + the user. On the currently supported platforms, SDL, Windows console, + and X11 allow user resizing, while DOS, OS/2, SDL and Windows console + allow programmatic resizing. If you want to support user resizing, + you should check for getch() returning KEY_RESIZE, and/or call + is_termresized() at appropriate times; if either condition occurs, + call resize_term(0, 0). Then, with either user or programmatic + resizing, you'll have to resize any windows you've created, as + appropriate; resize_term() only handles stdscr and curscr. + + is_termresized() returns TRUE if the curses screen has been resized + by the user, and a call to resize_term() is needed. Checking for + KEY_RESIZE is generally preferable, unless you're not handling the + keyboard. + + curses_version() returns a string describing the version of PDCurses. + + PDC_get_version() fills a PDC_VERSION structure provided by the user + with more detailed version info (see curses.h). + + set_tabsize() sets the tab interval, stored in TABSIZE. + +### Return Value + + All functions return NULL on error, except endwin(), which always + returns OK, and resize_term(), which returns either OK or ERR. + +### Portability + X/Open ncurses NetBSD + initscr Y Y Y + endwin Y Y Y + isendwin Y Y Y + newterm Y Y Y + set_term Y Y Y + delscreen Y Y Y + resize_term - Y Y + set_tabsize - Y Y + curses_version - Y - + is_termresized - - - + +**man-end****************************************************************/ + +#include <stdlib.h> + +char ttytype[128]; + +const char *_curses_notice = "PDCurses " PDC_VERDOT " - " __DATE__; + +SCREEN *SP = (SCREEN*)NULL; /* curses variables */ +WINDOW *curscr = (WINDOW *)NULL; /* the current screen image */ +WINDOW *stdscr = (WINDOW *)NULL; /* the default screen window */ + +int LINES = 0; /* current terminal height */ +int COLS = 0; /* current terminal width */ +int TABSIZE = 8; + +MOUSE_STATUS Mouse_status; + +extern RIPPEDOFFLINE linesripped[5]; +extern char linesrippedoff; + +WINDOW *initscr(void) +{ + int i; + + PDC_LOG(("initscr() - called\n")); + + if (SP && SP->alive) + return NULL; + + SP = calloc(1, sizeof(SCREEN)); + if (!SP) + return NULL; + + if (PDC_scr_open() == ERR) + { + fprintf(stderr, "initscr(): Unable to create SP\n"); + exit(8); + } + + SP->autocr = TRUE; /* cr -> lf by default */ + SP->raw_out = FALSE; /* tty I/O modes */ + SP->raw_inp = FALSE; /* tty I/O modes */ + SP->cbreak = TRUE; + SP->key_modifiers = 0L; + SP->return_key_modifiers = FALSE; + SP->echo = TRUE; + SP->visibility = 1; + SP->resized = FALSE; + SP->_trap_mbe = 0L; + SP->linesrippedoff = 0; + SP->linesrippedoffontop = 0; + SP->delaytenths = 0; + SP->line_color = -1; + SP->lastscr = (WINDOW *)NULL; + SP->dbfp = NULL; + SP->color_started = FALSE; + SP->dirty = FALSE; + SP->sel_start = -1; + SP->sel_end = -1; + + SP->orig_cursor = PDC_get_cursor_mode(); + + LINES = SP->lines = PDC_get_rows(); + COLS = SP->cols = PDC_get_columns(); + + if (LINES < 2 || COLS < 2) + { + fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n", + LINES, COLS); + exit(4); + } + + curscr = newwin(LINES, COLS, 0, 0); + if (!curscr) + { + fprintf(stderr, "initscr(): Unable to create curscr.\n"); + exit(2); + } + + SP->lastscr = newwin(LINES, COLS, 0, 0); + if (!SP->lastscr) + { + fprintf(stderr, "initscr(): Unable to create SP->lastscr.\n"); + exit(2); + } + + wattrset(SP->lastscr, (chtype)(-1)); + werase(SP->lastscr); + + PDC_slk_initialize(); + LINES -= SP->slklines; + + /* We have to sort out ripped off lines here, and reduce the height + of stdscr by the number of lines ripped off */ + + for (i = 0; i < linesrippedoff; i++) + { + if (linesripped[i].line < 0) + (*linesripped[i].init)(newwin(1, COLS, LINES - 1, 0), COLS); + else + (*linesripped[i].init)(newwin(1, COLS, + SP->linesrippedoffontop++, 0), COLS); + + SP->linesrippedoff++; + LINES--; + } + + linesrippedoff = 0; + + stdscr = newwin(LINES, COLS, SP->linesrippedoffontop, 0); + if (!stdscr) + { + fprintf(stderr, "initscr(): Unable to create stdscr.\n"); + exit(1); + } + + wclrtobot(stdscr); + + /* If preserving the existing screen, don't allow a screen clear */ + + if (SP->_preserve) + { + untouchwin(curscr); + untouchwin(stdscr); + stdscr->_clear = FALSE; + curscr->_clear = FALSE; + } + else + curscr->_clear = TRUE; + + SP->atrtab = calloc(PDC_COLOR_PAIRS, sizeof(PDC_PAIR)); + if (!SP->atrtab) + return NULL; + PDC_init_atrtab(); /* set up default colors */ + + MOUSE_X_POS = MOUSE_Y_POS = -1; + BUTTON_STATUS(1) = BUTTON_RELEASED; + BUTTON_STATUS(2) = BUTTON_RELEASED; + BUTTON_STATUS(3) = BUTTON_RELEASED; + Mouse_status.changes = 0; + + SP->alive = TRUE; + + def_shell_mode(); + + sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname()); + + SP->c_buffer = malloc(_INBUFSIZ * sizeof(int)); + if (!SP->c_buffer) + return NULL; + SP->c_pindex = 0; + SP->c_gindex = 1; + + SP->c_ungch = malloc(NUNGETCH * sizeof(int)); + if (!SP->c_ungch) + return NULL; + SP->c_ungind = 0; + SP->c_ungmax = NUNGETCH; + + return stdscr; +} + +#ifdef XCURSES +WINDOW *Xinitscr(int argc, char **argv) +{ + PDC_LOG(("Xinitscr() - called\n")); + + PDC_set_args(argc, argv); + return initscr(); +} +#endif + +int endwin(void) +{ + PDC_LOG(("endwin() - called\n")); + + /* Allow temporary exit from curses using endwin() */ + + def_prog_mode(); + PDC_scr_close(); + + SP->alive = FALSE; + + return OK; +} + +bool isendwin(void) +{ + PDC_LOG(("isendwin() - called\n")); + + return SP ? !(SP->alive) : FALSE; +} + +SCREEN *newterm(const char *type, FILE *outfd, FILE *infd) +{ + PDC_LOG(("newterm() - called\n")); + + return initscr() ? SP : NULL; +} + +SCREEN *set_term(SCREEN *new) +{ + PDC_LOG(("set_term() - called\n")); + + /* We only support one screen */ + + return (new == SP) ? SP : NULL; +} + +void delscreen(SCREEN *sp) +{ + PDC_LOG(("delscreen() - called\n")); + + if (!SP || sp != SP) + return; + + free(SP->c_ungch); + free(SP->c_buffer); + free(SP->atrtab); + + PDC_slk_free(); /* free the soft label keys, if needed */ + + delwin(stdscr); + delwin(curscr); + delwin(SP->lastscr); + stdscr = (WINDOW *)NULL; + curscr = (WINDOW *)NULL; + SP->lastscr = (WINDOW *)NULL; + + SP->alive = FALSE; + + PDC_scr_free(); + + free(SP); + SP = (SCREEN *)NULL; +} + +int resize_term(int nlines, int ncols) +{ + PDC_LOG(("resize_term() - called: nlines %d\n", nlines)); + + if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR) + return ERR; + + SP->resized = FALSE; + + SP->lines = PDC_get_rows(); + LINES = SP->lines - SP->linesrippedoff - SP->slklines; + SP->cols = COLS = PDC_get_columns(); + + if (SP->cursrow >= SP->lines) + SP->cursrow = SP->lines - 1; + if (SP->curscol >= SP->cols) + SP->curscol = SP->cols - 1; + + if (wresize(curscr, SP->lines, SP->cols) == ERR || + wresize(stdscr, LINES, COLS) == ERR || + wresize(SP->lastscr, SP->lines, SP->cols) == ERR) + return ERR; + + werase(SP->lastscr); + curscr->_clear = TRUE; + + if (SP->slk_winptr) + { + if (wresize(SP->slk_winptr, SP->slklines, COLS) == ERR) + return ERR; + + wmove(SP->slk_winptr, 0, 0); + wclrtobot(SP->slk_winptr); + PDC_slk_initialize(); + slk_noutrefresh(); + } + + touchwin(stdscr); + wnoutrefresh(stdscr); + + return OK; +} + +bool is_termresized(void) +{ + PDC_LOG(("is_termresized() - called\n")); + + return SP->resized; +} + +const char *curses_version(void) +{ + return _curses_notice; +} + +void PDC_get_version(PDC_VERSION *ver) +{ + if (!ver) + return; + + ver->flags = 0 +#ifdef PDCDEBUG + | PDC_VFLAG_DEBUG +#endif +#ifdef PDC_WIDE + | PDC_VFLAG_WIDE +#endif +#ifdef PDC_FORCE_UTF8 + | PDC_VFLAG_UTF8 +#endif +#ifdef PDC_DLL_BUILD + | PDC_VFLAG_DLL +#endif +#ifdef PDC_RGB + | PDC_VFLAG_RGB +#endif + ; + + ver->build = PDC_BUILD; + ver->major = PDC_VER_MAJOR; + ver->minor = PDC_VER_MINOR; + ver->csize = sizeof(chtype); + ver->bsize = sizeof(bool); +} + +int set_tabsize(int tabsize) +{ + PDC_LOG(("set_tabsize() - called: tabsize %d\n", tabsize)); + + if (tabsize < 1) + return ERR; + + TABSIZE = tabsize; + + return OK; +} diff --git a/Utilities/cmpdcurses/pdcurses/inopts.c b/Utilities/cmpdcurses/pdcurses/inopts.c new file mode 100644 index 0000000..e38bb53 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/inopts.c @@ -0,0 +1,368 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +inopts +------ + +### Synopsis + + int cbreak(void); + int nocbreak(void); + int echo(void); + int noecho(void); + int halfdelay(int tenths); + int intrflush(WINDOW *win, bool bf); + int keypad(WINDOW *win, bool bf); + int meta(WINDOW *win, bool bf); + int nl(void); + int nonl(void); + int nodelay(WINDOW *win, bool bf); + int notimeout(WINDOW *win, bool bf); + int raw(void); + int noraw(void); + void noqiflush(void); + void qiflush(void); + void timeout(int delay); + void wtimeout(WINDOW *win, int delay); + int typeahead(int fildes); + + int crmode(void); + int nocrmode(void); + + bool is_keypad(const WINDOW *win); + +### Description + + cbreak() and nocbreak() toggle cbreak mode. In cbreak mode, + characters typed by the user are made available immediately, and + erase/kill character processing is not performed. In nocbreak mode, + typed characters are buffered until a newline or carriage return. + Interrupt and flow control characters are unaffected by this mode. + PDCurses always starts in cbreak mode. + + echo() and noecho() control whether typed characters are echoed by + the input routine. Initially, input characters are echoed. Subsequent + calls to echo() and noecho() do not flush type-ahead. + + halfdelay() is similar to cbreak(), but allows for a time limit to be + specified, in tenths of a second. This causes getch() to block for + that period before returning ERR if no key has been received. tenths + must be between 1 and 255. + + keypad() controls whether getch() returns function/special keys as + single key codes (e.g., the left arrow key as KEY_LEFT). Per X/Open, + the default for keypad mode is OFF. You'll probably want it on. With + keypad mode off, if a special key is pressed, getch() does nothing or + returns ERR. + + nodelay() controls whether wgetch() is a non-blocking call. If the + option is enabled, and no input is ready, wgetch() will return ERR. + If disabled, wgetch() will hang until input is ready. + + nl() enables the translation of a carriage return into a newline on + input. nonl() disables this. Initially, the translation does occur. + + raw() and noraw() toggle raw mode. Raw mode is similar to cbreak + mode, in that characters typed are immediately passed through to the + user program. The difference is that in raw mode, the INTR, QUIT, + SUSP, and STOP characters are passed through without being + interpreted, and without generating a signal. + + In PDCurses, the meta() function sets raw mode on or off. + + timeout() and wtimeout() set blocking or non-blocking reads for the + specified window. If the delay is negative, a blocking read is used; + if zero, then non-blocking reads are done -- if no input is waiting, + ERR is returned immediately. If the delay is positive, the read + blocks for the delay period; if the period expires, ERR is returned. + The delay is given in milliseconds, but this is rounded down to 50ms + (1/20th sec) intervals, with a minimum of one interval if a postive + delay is given; i.e., 1-99 will wait 50ms, 100-149 will wait 100ms, + etc. + + intrflush(), notimeout(), noqiflush(), qiflush() and typeahead() do + nothing in PDCurses, but are included for compatibility with other + curses implementations. + + crmode() and nocrmode() are archaic equivalents to cbreak() and + nocbreak(), respectively. + + is_keypad() reports whether the specified window is in keypad mode. + +### Return Value + + All functions except is_keypad() and the void functions return OK on + success and ERR on error. + +### Portability + X/Open ncurses NetBSD + cbreak Y Y Y + nocbreak Y Y Y + echo Y Y Y + noecho Y Y Y + halfdelay Y Y Y + intrflush Y Y Y + keypad Y Y Y + meta Y Y Y + nl Y Y Y + nonl Y Y Y + nodelay Y Y Y + notimeout Y Y Y + raw Y Y Y + noraw Y Y Y + noqiflush Y Y Y + qiflush Y Y Y + timeout Y Y Y + wtimeout Y Y Y + typeahead Y Y Y + crmode Y Y Y + nocrmode Y Y Y + is_keypad - Y Y + +**man-end****************************************************************/ + +int cbreak(void) +{ + PDC_LOG(("cbreak() - called\n")); + + if (!SP) + return ERR; + + SP->cbreak = TRUE; + + return OK; +} + +int nocbreak(void) +{ + PDC_LOG(("nocbreak() - called\n")); + + if (!SP) + return ERR; + + SP->cbreak = FALSE; + SP->delaytenths = 0; + + return OK; +} + +int echo(void) +{ + PDC_LOG(("echo() - called\n")); + + if (!SP) + return ERR; + + SP->echo = TRUE; + + return OK; +} + +int noecho(void) +{ + PDC_LOG(("noecho() - called\n")); + + if (!SP) + return ERR; + + SP->echo = FALSE; + + return OK; +} + +int halfdelay(int tenths) +{ + PDC_LOG(("halfdelay() - called\n")); + + if (!SP || tenths < 1 || tenths > 255) + return ERR; + + SP->delaytenths = tenths; + + return OK; +} + +int intrflush(WINDOW *win, bool bf) +{ + PDC_LOG(("intrflush() - called\n")); + + return OK; +} + +int keypad(WINDOW *win, bool bf) +{ + PDC_LOG(("keypad() - called\n")); + + if (!win) + return ERR; + + win->_use_keypad = bf; + + return OK; +} + +int meta(WINDOW *win, bool bf) +{ + PDC_LOG(("meta() - called\n")); + + if (!SP) + return ERR; + + SP->raw_inp = bf; + + return OK; +} + +int nl(void) +{ + PDC_LOG(("nl() - called\n")); + + if (!SP) + return ERR; + + SP->autocr = TRUE; + + return OK; +} + +int nonl(void) +{ + PDC_LOG(("nonl() - called\n")); + + if (!SP) + return ERR; + + SP->autocr = FALSE; + + return OK; +} + +int nodelay(WINDOW *win, bool flag) +{ + PDC_LOG(("nodelay() - called\n")); + + if (!win) + return ERR; + + win->_nodelay = flag; + + return OK; +} + +int notimeout(WINDOW *win, bool flag) +{ + PDC_LOG(("notimeout() - called\n")); + + return OK; +} + +int raw(void) +{ + PDC_LOG(("raw() - called\n")); + + if (!SP) + return ERR; + + PDC_set_keyboard_binary(TRUE); + SP->raw_inp = TRUE; + + return OK; +} + +int noraw(void) +{ + PDC_LOG(("noraw() - called\n")); + + if (!SP) + return ERR; + + PDC_set_keyboard_binary(FALSE); + SP->raw_inp = FALSE; + + return OK; +} + +void noqiflush(void) +{ + PDC_LOG(("noqiflush() - called\n")); +} + +void qiflush(void) +{ + PDC_LOG(("qiflush() - called\n")); +} + +int typeahead(int fildes) +{ + PDC_LOG(("typeahead() - called\n")); + + return OK; +} + +void wtimeout(WINDOW *win, int delay) +{ + PDC_LOG(("wtimeout() - called\n")); + + if (!win) + return; + + if (delay < 0) + { + /* This causes a blocking read on the window, so turn on delay + mode */ + + win->_nodelay = FALSE; + win->_delayms = 0; + } + else if (!delay) + { + /* This causes a non-blocking read on the window, so turn off + delay mode */ + + win->_nodelay = TRUE; + win->_delayms = 0; + } + else + { + /* This causes the read on the window to delay for the number of + milliseconds. Also forces the window into non-blocking read + mode */ + + /*win->_nodelay = TRUE;*/ + win->_delayms = delay; + } +} + +void timeout(int delay) +{ + PDC_LOG(("timeout() - called\n")); + + wtimeout(stdscr, delay); +} + +int crmode(void) +{ + PDC_LOG(("crmode() - called\n")); + + return cbreak(); +} + +int nocrmode(void) +{ + PDC_LOG(("nocrmode() - called\n")); + + return nocbreak(); +} + +bool is_keypad(const WINDOW *win) +{ + PDC_LOG(("is_keypad() - called\n")); + + if (!win) + return FALSE; + + return win->_use_keypad; +} diff --git a/Utilities/cmpdcurses/pdcurses/insch.c b/Utilities/cmpdcurses/pdcurses/insch.c new file mode 100644 index 0000000..da6cb2d --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/insch.c @@ -0,0 +1,270 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +insch +----- + +### Synopsis + + int insch(chtype ch); + int winsch(WINDOW *win, chtype ch); + int mvinsch(int y, int x, chtype ch); + int mvwinsch(WINDOW *win, int y, int x, chtype ch); + + int insrawch(chtype ch); + int winsrawch(WINDOW *win, chtype ch); + int mvinsrawch(int y, int x, chtype ch); + int mvwinsrawch(WINDOW *win, int y, int x, chtype ch); + + int ins_wch(const cchar_t *wch); + int wins_wch(WINDOW *win, const cchar_t *wch); + int mvins_wch(int y, int x, const cchar_t *wch); + int mvwins_wch(WINDOW *win, int y, int x, const cchar_t *wch); + +### Description + + The insch() functions insert a chtype into the window at the current + or specified cursor position. The cursor is NOT advanced. A newline + is equivalent to clrtoeol(); tabs are expanded; other control + characters are converted as with unctrl(). + + The ins_wch() functions are the wide-character equivalents, taking + cchar_t pointers rather than chtypes. + + Video attributes can be combined with a character by ORing them into + the parameter. Text, including attributes, can be copied from one + place to another using inch() and insch(). + + insrawch() etc. are PDCurses-specific wrappers for insch() etc. that + disable the translation of control characters. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + insch Y Y Y + winsch Y Y Y + mvinsch Y Y Y + mvwinsch Y Y Y + ins_wch Y Y Y + wins_wch Y Y Y + mvins_wch Y Y Y + mvwins_wch Y Y Y + insrawch - - - + winsrawch - - - + +**man-end****************************************************************/ + +#include <string.h> + +int winsch(WINDOW *win, chtype ch) +{ + int x, y; + chtype attr; + bool xlat; + + PDC_LOG(("winsch() - called: win=%p ch=%x (text=%c attr=0x%x)\n", + win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES)); + + if (!win) + return ERR; + + x = win->_curx; + y = win->_cury; + + if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0) + return ERR; + + xlat = !SP->raw_out && !(ch & A_ALTCHARSET); + attr = ch & A_ATTRIBUTES; + ch &= A_CHARTEXT; + + if (xlat && (ch < ' ' || ch == 0x7f)) + { + int x2; + + switch (ch) + { + case '\t': + for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++) + { + if (winsch(win, attr | ' ') == ERR) + return ERR; + } + return OK; + + case '\n': + wclrtoeol(win); + break; + + case 0x7f: + if (winsch(win, attr | '?') == ERR) + return ERR; + + return winsch(win, attr | '^'); + + default: + /* handle control chars */ + + if (winsch(win, attr | (ch + '@')) == ERR) + return ERR; + + return winsch(win, attr | '^'); + } + } + else + { + int maxx; + chtype *temp; + + /* If the incoming character doesn't have its own attribute, + then use the current attributes for the window. If it has + attributes but not a color component, OR the attributes to + the current attributes for the window. If it has a color + component, use the attributes solely from the incoming + character. */ + + if (!(attr & A_COLOR)) + attr |= win->_attrs; + + /* wrs (4/10/93): Apply the same sort of logic for the window + background, in that it only takes precedence if other color + attributes are not there and that the background character + will only print if the printing character is blank. */ + + if (!(attr & A_COLOR)) + attr |= win->_bkgd & A_ATTRIBUTES; + else + attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR); + + if (ch == ' ') + ch = win->_bkgd & A_CHARTEXT; + + /* Add the attribute back into the character. */ + + ch |= attr; + + maxx = win->_maxx; + temp = &win->_y[y][x]; + + memmove(temp + 1, temp, (maxx - x - 1) * sizeof(chtype)); + + win->_lastch[y] = maxx - 1; + + if ((win->_firstch[y] == _NO_CHANGE) || (win->_firstch[y] > x)) + win->_firstch[y] = x; + + *temp = ch; + } + + PDC_sync(win); + + return OK; +} + +int insch(chtype ch) +{ + PDC_LOG(("insch() - called\n")); + + return winsch(stdscr, ch); +} + +int mvinsch(int y, int x, chtype ch) +{ + PDC_LOG(("mvinsch() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return winsch(stdscr, ch); +} + +int mvwinsch(WINDOW *win, int y, int x, chtype ch) +{ + PDC_LOG(("mvwinsch() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winsch(win, ch); +} + +int winsrawch(WINDOW *win, chtype ch) +{ + PDC_LOG(("winsrawch() - called: win=%p ch=%x " + "(char=%c attr=0x%x)\n", win, ch, + ch & A_CHARTEXT, ch & A_ATTRIBUTES)); + + if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f) + ch |= A_ALTCHARSET; + + return winsch(win, ch); +} + +int insrawch(chtype ch) +{ + PDC_LOG(("insrawch() - called\n")); + + return winsrawch(stdscr, ch); +} + +int mvinsrawch(int y, int x, chtype ch) +{ + PDC_LOG(("mvinsrawch() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return winsrawch(stdscr, ch); +} + +int mvwinsrawch(WINDOW *win, int y, int x, chtype ch) +{ + PDC_LOG(("mvwinsrawch() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winsrawch(win, ch); +} + +#ifdef PDC_WIDE +int wins_wch(WINDOW *win, const cchar_t *wch) +{ + PDC_LOG(("wins_wch() - called\n")); + + return wch ? winsch(win, *wch) : ERR; +} + +int ins_wch(const cchar_t *wch) +{ + PDC_LOG(("ins_wch() - called\n")); + + return wins_wch(stdscr, wch); +} + +int mvins_wch(int y, int x, const cchar_t *wch) +{ + PDC_LOG(("mvins_wch() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wins_wch(stdscr, wch); +} + +int mvwins_wch(WINDOW *win, int y, int x, const cchar_t *wch) +{ + PDC_LOG(("mvwins_wch() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wins_wch(win, wch); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/insstr.c b/Utilities/cmpdcurses/pdcurses/insstr.c new file mode 100644 index 0000000..2e2cfb7 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/insstr.c @@ -0,0 +1,263 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +insstr +------ + +### Synopsis + + int insstr(const char *str); + int insnstr(const char *str, int n); + int winsstr(WINDOW *win, const char *str); + int winsnstr(WINDOW *win, const char *str, int n); + int mvinsstr(int y, int x, const char *str); + int mvinsnstr(int y, int x, const char *str, int n); + int mvwinsstr(WINDOW *win, int y, int x, const char *str); + int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n); + + int ins_wstr(const wchar_t *wstr); + int ins_nwstr(const wchar_t *wstr, int n); + int wins_wstr(WINDOW *win, const wchar_t *wstr); + int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n); + int mvins_wstr(int y, int x, const wchar_t *wstr); + int mvins_nwstr(int y, int x, const wchar_t *wstr, int n); + int mvwins_wstr(WINDOW *win, int y, int x, const wchar_t *wstr); + int mvwins_nwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n); + +### Description + + The insstr() functions insert a character string into a window at the + current cursor position, by repeatedly calling winsch(). When + PDCurses is built with wide-character support enabled, the narrow- + character functions treat the string as a multibyte string in the + current locale, and convert it first. All characters to the right of + the cursor are moved to the right, with the possibility of the + rightmost characters on the line being lost. The cursor position + does not change (after moving to y, x, if specified). The routines + with n as the last argument insert at most n characters; if n is + negative, then the entire string is inserted. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + insstr Y Y Y + winsstr Y Y Y + mvinsstr Y Y Y + mvwinsstr Y Y Y + insnstr Y Y Y + winsnstr Y Y Y + mvinsnstr Y Y Y + mvwinsnstr Y Y Y + ins_wstr Y Y Y + wins_wstr Y Y Y + mvins_wstr Y Y Y + mvwins_wstr Y Y Y + ins_nwstr Y Y Y + wins_nwstr Y Y Y + mvins_nwstr Y Y Y + mvwins_nwstr Y Y Y + +**man-end****************************************************************/ + +#include <string.h> + +int winsnstr(WINDOW *win, const char *str, int n) +{ +#ifdef PDC_WIDE + wchar_t wstr[513], *p; + int i; +#endif + int len; + + PDC_LOG(("winsnstr() - called: string=\"%s\" n %d \n", str, n)); + + if (!win || !str) + return ERR; + + len = strlen(str); + + if (n < 0 || n > len) + n = len; + +#ifdef PDC_WIDE + if (n > 512) + n = 512; + + p = wstr; + i = 0; + + while (str[i] && i < n) + { + int retval = PDC_mbtowc(p, str + i, n - i); + + if (retval <= 0) + break; + p++; + i += retval; + } + + while (p > wstr) + if (winsch(win, *--p) == ERR) +#else + while (n) + if (winsch(win, (unsigned char)(str[--n])) == ERR) +#endif + return ERR; + + return OK; +} + +int insstr(const char *str) +{ + PDC_LOG(("insstr() - called: string=\"%s\"\n", str)); + + return winsnstr(stdscr, str, -1); +} + +int winsstr(WINDOW *win, const char *str) +{ + PDC_LOG(("winsstr() - called: string=\"%s\"\n", str)); + + return winsnstr(win, str, -1); +} + +int mvinsstr(int y, int x, const char *str) +{ + PDC_LOG(("mvinsstr() - called: y %d x %d string=\"%s\"\n", y, x, str)); + + if (move(y, x) == ERR) + return ERR; + + return winsnstr(stdscr, str, -1); +} + +int mvwinsstr(WINDOW *win, int y, int x, const char *str) +{ + PDC_LOG(("mvwinsstr() - called: string=\"%s\"\n", str)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winsnstr(win, str, -1); +} + +int insnstr(const char *str, int n) +{ + PDC_LOG(("insnstr() - called: string=\"%s\" n %d \n", str, n)); + + return winsnstr(stdscr, str, n); +} + +int mvinsnstr(int y, int x, const char *str, int n) +{ + PDC_LOG(("mvinsnstr() - called: y %d x %d string=\"%s\" n %d \n", + y, x, str, n)); + + if (move(y, x) == ERR) + return ERR; + + return winsnstr(stdscr, str, n); +} + +int mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n) +{ + PDC_LOG(("mvwinsnstr() - called: y %d x %d string=\"%s\" n %d \n", + y, x, str, n)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winsnstr(win, str, n); +} + +#ifdef PDC_WIDE +int wins_nwstr(WINDOW *win, const wchar_t *wstr, int n) +{ + const wchar_t *p; + int len; + + PDC_LOG(("wins_nwstr() - called\n")); + + if (!win || !wstr) + return ERR; + + for (len = 0, p = wstr; *p; p++) + len++; + + if (n < 0 || n > len) + n = len; + + while (n) + if (winsch(win, wstr[--n]) == ERR) + return ERR; + + return OK; +} + +int ins_wstr(const wchar_t *wstr) +{ + PDC_LOG(("ins_wstr() - called\n")); + + return wins_nwstr(stdscr, wstr, -1); +} + +int wins_wstr(WINDOW *win, const wchar_t *wstr) +{ + PDC_LOG(("wins_wstr() - called\n")); + + return wins_nwstr(win, wstr, -1); +} + +int mvins_wstr(int y, int x, const wchar_t *wstr) +{ + PDC_LOG(("mvins_wstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wins_nwstr(stdscr, wstr, -1); +} + +int mvwins_wstr(WINDOW *win, int y, int x, const wchar_t *wstr) +{ + PDC_LOG(("mvwinsstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wins_nwstr(win, wstr, -1); +} + +int ins_nwstr(const wchar_t *wstr, int n) +{ + PDC_LOG(("ins_nwstr() - called\n")); + + return wins_nwstr(stdscr, wstr, n); +} + +int mvins_nwstr(int y, int x, const wchar_t *wstr, int n) +{ + PDC_LOG(("mvinsnstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return wins_nwstr(stdscr, wstr, n); +} + +int mvwins_nwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n) +{ + PDC_LOG(("mvwinsnstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return wins_nwstr(win, wstr, n); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/instr.c b/Utilities/cmpdcurses/pdcurses/instr.c new file mode 100644 index 0000000..bd8dbf9 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/instr.c @@ -0,0 +1,245 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +instr +----- + +### Synopsis + + int instr(char *str); + int innstr(char *str, int n); + int winstr(WINDOW *win, char *str); + int winnstr(WINDOW *win, char *str, int n); + int mvinstr(int y, int x, char *str); + int mvinnstr(int y, int x, char *str, int n); + int mvwinstr(WINDOW *win, int y, int x, char *str); + int mvwinnstr(WINDOW *win, int y, int x, char *str, int n); + + int inwstr(wchar_t *wstr); + int innwstr(wchar_t *wstr, int n); + int winwstr(WINDOW *win, wchar_t *wstr); + int winnwstr(WINDOW *win, wchar_t *wstr, int n); + int mvinwstr(int y, int x, wchar_t *wstr); + int mvinnwstr(int y, int x, wchar_t *wstr, int n); + int mvwinwstr(WINDOW *win, int y, int x, wchar_t *wstr); + int mvwinnwstr(WINDOW *win, int y, int x, wchar_t *wstr, int n); + +### Description + + These functions take characters (or wide characters) from the current + or specified position in the window, and return them as a string in + str (or wstr). Attributes are ignored. The functions with n as the + last argument return a string at most n characters long. + +### Return Value + + Upon successful completion, innstr(), mvinnstr(), mvwinnstr() and + winnstr() return the number of characters actually read into the + string; instr(), mvinstr(), mvwinstr() and winstr() return OK. + Otherwise, all these functions return ERR. + +### Portability + X/Open ncurses NetBSD + instr Y Y Y + winstr Y Y Y + mvinstr Y Y Y + mvwinstr Y Y Y + innstr Y Y Y + winnstr Y Y Y + mvinnstr Y Y Y + mvwinnstr Y Y Y + inwstr Y Y Y + winwstr Y Y Y + mvinwstr Y Y Y + mvwinwstr Y Y Y + innwstr Y Y Y + winnwstr Y Y Y + mvinnwstr Y Y Y + mvwinnwstr Y Y Y + +**man-end****************************************************************/ + +int winnstr(WINDOW *win, char *str, int n) +{ +#ifdef PDC_WIDE + wchar_t wstr[513]; + + if (n < 0 || n > 512) + n = 512; + + if (winnwstr(win, wstr, n) == ERR) + return ERR; + + return PDC_wcstombs(str, wstr, n); +#else + chtype *src; + int i; + + PDC_LOG(("winnstr() - called: n %d \n", n)); + + if (!win || !str) + return ERR; + + if (n < 0 || (win->_curx + n) > win->_maxx) + n = win->_maxx - win->_curx; + + src = win->_y[win->_cury] + win->_curx; + + for (i = 0; i < n; i++) + str[i] = src[i] & A_CHARTEXT; + + str[i] = '\0'; + + return i; +#endif +} + +int instr(char *str) +{ + PDC_LOG(("instr() - called: string=\"%s\"\n", str)); + + return (ERR == winnstr(stdscr, str, stdscr->_maxx)) ? ERR : OK; +} + +int winstr(WINDOW *win, char *str) +{ + PDC_LOG(("winstr() - called: \n")); + + return (ERR == winnstr(win, str, win->_maxx)) ? ERR : OK; +} + +int mvinstr(int y, int x, char *str) +{ + PDC_LOG(("mvinstr() - called: y %d x %d \n", y, x)); + + if (move(y, x) == ERR) + return ERR; + + return (ERR == winnstr(stdscr, str, stdscr->_maxx)) ? ERR : OK; +} + +int mvwinstr(WINDOW *win, int y, int x, char *str) +{ + PDC_LOG(("mvwinstr() - called: y %d x %d \n", y, x)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return (ERR == winnstr(win, str, win->_maxx)) ? ERR : OK; +} + +int innstr(char *str, int n) +{ + PDC_LOG(("innstr() - called: n %d \n", n)); + + return winnstr(stdscr, str, n); +} + +int mvinnstr(int y, int x, char *str, int n) +{ + PDC_LOG(("mvinnstr() - called: y %d x %d n %d \n", y, x, n)); + + if (move(y, x) == ERR) + return ERR; + + return winnstr(stdscr, str, n); +} + +int mvwinnstr(WINDOW *win, int y, int x, char *str, int n) +{ + PDC_LOG(("mvwinnstr() - called: y %d x %d n %d \n", y, x, n)); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winnstr(win, str, n); +} + +#ifdef PDC_WIDE +int winnwstr(WINDOW *win, wchar_t *wstr, int n) +{ + chtype *src; + int i; + + PDC_LOG(("winnstr() - called: n %d \n", n)); + + if (!win || !wstr) + return ERR; + + if (n < 0 || (win->_curx + n) > win->_maxx) + n = win->_maxx - win->_curx; + + src = win->_y[win->_cury] + win->_curx; + + for (i = 0; i < n; i++) + wstr[i] = src[i] & A_CHARTEXT; + + wstr[i] = L'\0'; + + return i; +} + +int inwstr(wchar_t *wstr) +{ + PDC_LOG(("inwstr() - called\n")); + + return (ERR == winnwstr(stdscr, wstr, stdscr->_maxx)) ? ERR : OK; +} + +int winwstr(WINDOW *win, wchar_t *wstr) +{ + PDC_LOG(("winwstr() - called\n")); + + return (ERR == winnwstr(win, wstr, win->_maxx)) ? ERR : OK; +} + +int mvinwstr(int y, int x, wchar_t *wstr) +{ + PDC_LOG(("mvinwstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return (ERR == winnwstr(stdscr, wstr, stdscr->_maxx)) ? ERR : OK; +} + +int mvwinwstr(WINDOW *win, int y, int x, wchar_t *wstr) +{ + PDC_LOG(("mvwinstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return (ERR == winnwstr(win, wstr, win->_maxx)) ? ERR : OK; +} + +int innwstr(wchar_t *wstr, int n) +{ + PDC_LOG(("innwstr() - called\n")); + + return winnwstr(stdscr, wstr, n); +} + +int mvinnwstr(int y, int x, wchar_t *wstr, int n) +{ + PDC_LOG(("mvinnstr() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + return winnwstr(stdscr, wstr, n); +} + +int mvwinnwstr(WINDOW *win, int y, int x, wchar_t *wstr, int n) +{ + PDC_LOG(("mvwinnwstr() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + return winnwstr(win, wstr, n); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/kernel.c b/Utilities/cmpdcurses/pdcurses/kernel.c new file mode 100644 index 0000000..81915e7 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/kernel.c @@ -0,0 +1,297 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +kernel +------ + +### Synopsis + + int def_prog_mode(void); + int def_shell_mode(void); + int reset_prog_mode(void); + int reset_shell_mode(void); + int resetty(void); + int savetty(void); + int ripoffline(int line, int (*init)(WINDOW *, int)); + int curs_set(int visibility); + int napms(int ms); + + int draino(int ms); + int resetterm(void); + int fixterm(void); + int saveterm(void); + +### Description + + def_prog_mode() and def_shell_mode() save the current terminal modes + as the "program" (in curses) or "shell" (not in curses) state for use + by the reset_prog_mode() and reset_shell_mode() functions. This is + done automatically by initscr(). + + reset_prog_mode() and reset_shell_mode() restore the terminal to + "program" (in curses) or "shell" (not in curses) state. These are + done automatically by endwin() and doupdate() after an endwin(), so + they would normally not be called before these functions. + + savetty() and resetty() save and restore the state of the terminal + modes. savetty() saves the current state in a buffer, and resetty() + restores the state to what it was at the last call to savetty(). + + curs_set() alters the appearance of the cursor. A visibility of 0 + makes it disappear; 1 makes it appear "normal" (usually an underline) + and 2 makes it "highly visible" (usually a block). + + ripoffline() reduces the size of stdscr by one line. If the "line" + parameter is positive, the line is removed from the top of the + screen; if negative, from the bottom. Up to 5 lines can be ripped off + stdscr by calling ripoffline() repeatedly. The function argument, + init, is called from within initscr() or newterm(), so ripoffline() + must be called before either of these functions. The init function + receives a pointer to a one-line WINDOW, and the width of the window. + Calling ripoffline() with a NULL init function pointer is an error. + + napms() suspends the program for the specified number of + milliseconds. draino() is an archaic equivalent. Note that since + napms() attempts to give up a time slice and yield control back to + the OS, all times are approximate. (In DOS, the delay is actually + rounded down to 50ms (1/20th sec) intervals, with a minimum of one + interval; i.e., 1-99 will wait 50ms, 100-149 will wait 100ms, etc.) + 0 returns immediately. + + resetterm(), fixterm() and saveterm() are archaic equivalents for + reset_shell_mode(), reset_prog_mode() and def_prog_mode(), + respectively. + +### Return Value + + All functions return OK on success and ERR on error, except + curs_set(), which returns the previous visibility. + +### Portability + X/Open ncurses NetBSD + def_prog_mode Y Y Y + def_shell_mode Y Y Y + reset_prog_mode Y Y Y + reset_shell_mode Y Y Y + resetty Y Y Y + savetty Y Y Y + ripoffline Y Y Y + curs_set Y Y Y + napms Y Y Y + fixterm - Y - + resetterm - Y - + saveterm - Y - + draino - - - + +**man-end****************************************************************/ + +#include <string.h> + +RIPPEDOFFLINE linesripped[5]; +char linesrippedoff = 0; + +static struct cttyset +{ + bool been_set; + SCREEN saved; +} ctty[3]; + +enum { PDC_SH_TTY, PDC_PR_TTY, PDC_SAVE_TTY }; + +static void _save_mode(int i) +{ + ctty[i].been_set = TRUE; + + memcpy(&(ctty[i].saved), SP, sizeof(SCREEN)); + + PDC_save_screen_mode(i); +} + +static int _restore_mode(int i) +{ + if (ctty[i].been_set == TRUE) + { + memcpy(SP, &(ctty[i].saved), sizeof(SCREEN)); + + if (ctty[i].saved.raw_out) + raw(); + + PDC_restore_screen_mode(i); + + if ((LINES != ctty[i].saved.lines) || + (COLS != ctty[i].saved.cols)) + resize_term(ctty[i].saved.lines, ctty[i].saved.cols); + + PDC_curs_set(ctty[i].saved.visibility); + + PDC_gotoyx(ctty[i].saved.cursrow, ctty[i].saved.curscol); + } + + return ctty[i].been_set ? OK : ERR; +} + +int def_prog_mode(void) +{ + PDC_LOG(("def_prog_mode() - called\n")); + + if (!SP) + return ERR; + + _save_mode(PDC_PR_TTY); + + return OK; +} + +int def_shell_mode(void) +{ + PDC_LOG(("def_shell_mode() - called\n")); + + if (!SP) + return ERR; + + _save_mode(PDC_SH_TTY); + + return OK; +} + +int reset_prog_mode(void) +{ + PDC_LOG(("reset_prog_mode() - called\n")); + + if (!SP) + return ERR; + + _restore_mode(PDC_PR_TTY); + PDC_reset_prog_mode(); + + return OK; +} + +int reset_shell_mode(void) +{ + PDC_LOG(("reset_shell_mode() - called\n")); + + if (!SP) + return ERR; + + _restore_mode(PDC_SH_TTY); + PDC_reset_shell_mode(); + + return OK; +} + +int resetty(void) +{ + PDC_LOG(("resetty() - called\n")); + + if (!SP) + return ERR; + + return _restore_mode(PDC_SAVE_TTY); +} + +int savetty(void) +{ + PDC_LOG(("savetty() - called\n")); + + if (!SP) + return ERR; + + _save_mode(PDC_SAVE_TTY); + + return OK; +} + +int curs_set(int visibility) +{ + int ret_vis; + + PDC_LOG(("curs_set() - called: visibility=%d\n", visibility)); + + if (!SP || visibility < 0 || visibility > 2) + return ERR; + + ret_vis = PDC_curs_set(visibility); + + /* If the cursor is changing from invisible to visible, update + its position */ + + if (visibility && !ret_vis) + PDC_gotoyx(SP->cursrow, SP->curscol); + + return ret_vis; +} + +int napms(int ms) +{ + PDC_LOG(("napms() - called: ms=%d\n", ms)); + + if (!SP) + return ERR; + + if (SP->dirty) + { + int curs_state = SP->visibility; + bool leave_state = is_leaveok(curscr); + + SP->dirty = FALSE; + + leaveok(curscr, TRUE); + + wrefresh(curscr); + + leaveok(curscr, leave_state); + curs_set(curs_state); + } + + if (ms) + PDC_napms(ms); + + return OK; +} + +int ripoffline(int line, int (*init)(WINDOW *, int)) +{ + PDC_LOG(("ripoffline() - called: line=%d\n", line)); + + if (linesrippedoff < 5 && line && init) + { + linesripped[(int)linesrippedoff].line = line; + linesripped[(int)linesrippedoff++].init = init; + + return OK; + } + + return ERR; +} + +int draino(int ms) +{ + PDC_LOG(("draino() - called\n")); + + return napms(ms); +} + +int resetterm(void) +{ + PDC_LOG(("resetterm() - called\n")); + + return reset_shell_mode(); +} + +int fixterm(void) +{ + PDC_LOG(("fixterm() - called\n")); + + return reset_prog_mode(); +} + +int saveterm(void) +{ + PDC_LOG(("saveterm() - called\n")); + + return def_prog_mode(); +} diff --git a/Utilities/cmpdcurses/pdcurses/keyname.c b/Utilities/cmpdcurses/pdcurses/keyname.c new file mode 100644 index 0000000..44e8dd4 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/keyname.c @@ -0,0 +1,129 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +keyname +------- + +### Synopsis + + char *keyname(int key); + + char *key_name(wchar_t c); + + bool has_key(int key); + +### Description + + keyname() returns a string corresponding to the argument key. key may + be any key returned by wgetch(). + + key_name() is the wide-character version. It takes a wchar_t + parameter, but still returns a char *. + + has_key() returns TRUE for recognized keys, FALSE otherwise. This + function is an ncurses extension. + +### Portability + X/Open ncurses NetBSD + keyname Y Y Y + key_name Y Y Y + has_key - Y Y + +**man-end****************************************************************/ + +#include <string.h> + +static const char *names[] = +{ + "KEY_BREAK", "KEY_DOWN", "KEY_UP", "KEY_LEFT", "KEY_RIGHT", + "KEY_HOME", "KEY_BACKSPACE", "KEY_F0", "KEY_F(1)", "KEY_F(2)", + "KEY_F(3)", "KEY_F(4)", "KEY_F(5)", "KEY_F(6)", "KEY_F(7)", + "KEY_F(8)", "KEY_F(9)", "KEY_F(10)", "KEY_F(11)", "KEY_F(12)", + "KEY_F(13)", "KEY_F(14)", "KEY_F(15)", "KEY_F(16)", "KEY_F(17)", + "KEY_F(18)", "KEY_F(19)", "KEY_F(20)", "KEY_F(21)", "KEY_F(22)", + "KEY_F(23)", "KEY_F(24)", "KEY_F(25)", "KEY_F(26)", "KEY_F(27)", + "KEY_F(28)", "KEY_F(29)", "KEY_F(30)", "KEY_F(31)", "KEY_F(32)", + "KEY_F(33)", "KEY_F(34)", "KEY_F(35)", "KEY_F(36)", "KEY_F(37)", + "KEY_F(38)", "KEY_F(39)", "KEY_F(40)", "KEY_F(41)", "KEY_F(42)", + "KEY_F(43)", "KEY_F(44)", "KEY_F(45)", "KEY_F(46)", "KEY_F(47)", + "KEY_F(48)", "KEY_F(49)", "KEY_F(50)", "KEY_F(51)", "KEY_F(52)", + "KEY_F(53)", "KEY_F(54)", "KEY_F(55)", "KEY_F(56)", "KEY_F(57)", + "KEY_F(58)", "KEY_F(59)", "KEY_F(60)", "KEY_F(61)", "KEY_F(62)", + "KEY_F(63)", "KEY_DL", "KEY_IL", "KEY_DC", "KEY_IC", "KEY_EIC", + "KEY_CLEAR", "KEY_EOS", "KEY_EOL", "KEY_SF", "KEY_SR", "KEY_NPAGE", + "KEY_PPAGE", "KEY_STAB", "KEY_CTAB", "KEY_CATAB", "KEY_ENTER", + "KEY_SRESET", "KEY_RESET", "KEY_PRINT", "KEY_LL", "KEY_ABORT", + "KEY_SHELP", "KEY_LHELP", "KEY_BTAB", "KEY_BEG", "KEY_CANCEL", + "KEY_CLOSE", "KEY_COMMAND", "KEY_COPY", "KEY_CREATE", "KEY_END", + "KEY_EXIT", "KEY_FIND", "KEY_HELP", "KEY_MARK", "KEY_MESSAGE", + "KEY_MOVE", "KEY_NEXT", "KEY_OPEN", "KEY_OPTIONS", "KEY_PREVIOUS", + "KEY_REDO", "KEY_REFERENCE", "KEY_REFRESH", "KEY_REPLACE", + "KEY_RESTART", "KEY_RESUME", "KEY_SAVE", "KEY_SBEG", "KEY_SCANCEL", + "KEY_SCOMMAND", "KEY_SCOPY", "KEY_SCREATE", "KEY_SDC", "KEY_SDL", + "KEY_SELECT", "KEY_SEND", "KEY_SEOL", "KEY_SEXIT", "KEY_SFIND", + "KEY_SHOME", "KEY_SIC", "UNKNOWN KEY", "KEY_SLEFT", "KEY_SMESSAGE", + "KEY_SMOVE", "KEY_SNEXT", "KEY_SOPTIONS", "KEY_SPREVIOUS", + "KEY_SPRINT", "KEY_SREDO", "KEY_SREPLACE", "KEY_SRIGHT", + "KEY_SRSUME", "KEY_SSAVE", "KEY_SSUSPEND", "KEY_SUNDO", + "KEY_SUSPEND", "KEY_UNDO", "ALT_0", "ALT_1", "ALT_2", "ALT_3", + "ALT_4", "ALT_5", "ALT_6", "ALT_7", "ALT_8", "ALT_9", "ALT_A", + "ALT_B", "ALT_C", "ALT_D", "ALT_E", "ALT_F", "ALT_G", "ALT_H", + "ALT_I", "ALT_J", "ALT_K", "ALT_L", "ALT_M", "ALT_N", "ALT_O", + "ALT_P", "ALT_Q", "ALT_R", "ALT_S", "ALT_T", "ALT_U", "ALT_V", + "ALT_W", "ALT_X", "ALT_Y", "ALT_Z", "CTL_LEFT", "CTL_RIGHT", + "CTL_PGUP", "CTL_PGDN", "CTL_HOME", "CTL_END", "KEY_A1", "KEY_A2", + "KEY_A3", "KEY_B1", "KEY_B2", "KEY_B3", "KEY_C1", "KEY_C2", + "KEY_C3", "PADSLASH", "PADENTER", "CTL_PADENTER", "ALT_PADENTER", + "PADSTOP", "PADSTAR", "PADMINUS", "PADPLUS", "CTL_PADSTOP", + "CTL_PADCENTER", "CTL_PADPLUS", "CTL_PADMINUS", "CTL_PADSLASH", + "CTL_PADSTAR", "ALT_PADPLUS", "ALT_PADMINUS", "ALT_PADSLASH", + "ALT_PADSTAR", "ALT_PADSTOP", "CTL_INS", "ALT_DEL", "ALT_INS", + "CTL_UP", "CTL_DOWN", "CTL_TAB", "ALT_TAB", "ALT_MINUS", + "ALT_EQUAL", "ALT_HOME", "ALT_PGUP", "ALT_PGDN", "ALT_END", + "ALT_UP", "ALT_DOWN", "ALT_RIGHT", "ALT_LEFT", "ALT_ENTER", + "ALT_ESC", "ALT_BQUOTE", "ALT_LBRACKET", "ALT_RBRACKET", + "ALT_SEMICOLON", "ALT_FQUOTE", "ALT_COMMA", "ALT_STOP", + "ALT_FSLASH", "ALT_BKSP", "CTL_BKSP", "PAD0", "CTL_PAD0", + "CTL_PAD1", "CTL_PAD2", "CTL_PAD3", "CTL_PAD4", "CTL_PAD5", + "CTL_PAD6", "CTL_PAD7","CTL_PAD8", "CTL_PAD9", "ALT_PAD0", + "ALT_PAD1", "ALT_PAD2", "ALT_PAD3", "ALT_PAD4", "ALT_PAD5", + "ALT_PAD6", "ALT_PAD7", "ALT_PAD8", "ALT_PAD9", "CTL_DEL", + "ALT_BSLASH", "CTL_ENTER", "SHF_PADENTER", "SHF_PADSLASH", + "SHF_PADSTAR", "SHF_PADPLUS", "SHF_PADMINUS", "SHF_UP", "SHF_DOWN", + "SHF_IC", "SHF_DC", "KEY_MOUSE", "KEY_SHIFT_L", "KEY_SHIFT_R", + "KEY_CONTROL_L", "KEY_CONTROL_R", "KEY_ALT_L", "KEY_ALT_R", + "KEY_RESIZE", "KEY_SUP", "KEY_SDOWN" +}; + +char *keyname(int key) +{ + static char _keyname[14]; + + /* Key names must be in exactly the same order as in curses.h */ + + PDC_LOG(("keyname() - called: key %d\n", key)); + + strcpy(_keyname, ((key >= 0) && (key < 0x80)) ? unctrl((chtype)key) : + has_key(key) ? names[key - KEY_MIN] : "UNKNOWN KEY"); + + return _keyname; +} + +bool has_key(int key) +{ + PDC_LOG(("has_key() - called: key %d\n", key)); + + return (key >= KEY_MIN && key <= KEY_MAX); +} + +#ifdef PDC_WIDE +char *key_name(wchar_t c) +{ + PDC_LOG(("key_name() - called\n")); + + return keyname((int)c); +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/mouse.c b/Utilities/cmpdcurses/pdcurses/mouse.c new file mode 100644 index 0000000..d2e8619 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/mouse.c @@ -0,0 +1,421 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +mouse +----- + +### Synopsis + + int mouse_set(mmask_t mbe); + int mouse_on(mmask_t mbe); + int mouse_off(mmask_t mbe); + int request_mouse_pos(void); + void wmouse_position(WINDOW *win, int *y, int *x); + mmask_t getmouse(void); + + int mouseinterval(int wait); + bool wenclose(const WINDOW *win, int y, int x); + bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen); + bool mouse_trafo(int *y, int *x, bool to_screen); + mmask_t mousemask(mmask_t mask, mmask_t *oldmask); + int nc_getmouse(MEVENT *event); + int ungetmouse(MEVENT *event); + bool has_mouse(void); + +### Description + + As of PDCurses 3.0, there are two separate mouse interfaces: the + classic interface, which is based on the undocumented Sys V mouse + functions; and an ncurses-compatible interface. Both are active at + all times, and you can mix and match functions from each, though it's + not recommended. The ncurses interface is essentially an emulation + layer built on top of the classic interface; it's here to allow + easier porting of ncurses apps. + + The classic interface: mouse_set(), mouse_on(), mouse_off(), + request_mouse_pos(), wmouse_position(), and getmouse(). An + application using this interface would start by calling mouse_set() + or mouse_on() with a non-zero value, often ALL_MOUSE_EVENTS. Then it + would check for a KEY_MOUSE return from getch(). If found, it would + call request_mouse_pos() to get the current mouse status. + + mouse_set(), mouse_on() and mouse_off() are analagous to attrset(), + attron() and attroff(). These functions set the mouse button events + to trap. The button masks used in these functions are defined in + curses.h and can be or'ed together. They are the group of masks + starting with BUTTON1_RELEASED. + + request_mouse_pos() requests curses to fill in the Mouse_status + structure with the current state of the mouse. + + wmouse_position() determines if the current mouse position is within + the window passed as an argument. If the mouse is outside the current + window, -1 is returned in the y and x arguments; otherwise the y and + x coordinates of the mouse (relative to the top left corner of the + window) are returned in y and x. + + getmouse() returns the current status of the trapped mouse buttons as + set by mouse_set() or mouse_on(). + + The ncurses interface: mouseinterval(), wenclose(), wmouse_trafo(), + mouse_trafo(), mousemask(), nc_getmouse(), ungetmouse() and + has_mouse(). A typical application using this interface would start + by calling mousemask() with a non-zero value, often ALL_MOUSE_EVENTS. + Then it would check for a KEY_MOUSE return from getch(). If found, it + would call nc_getmouse() to get the current mouse status. + + mouseinterval() sets the timeout for a mouse click. On all current + platforms, PDCurses receives mouse button press and release events, + but must synthesize click events. It does this by checking whether a + release event is queued up after a press event. If it gets a press + event, and there are no more events waiting, it will wait for the + timeout interval, then check again for a release. A press followed by + a release is reported as BUTTON_CLICKED; otherwise it's passed + through as BUTTON_PRESSED. The default timeout is 150ms; valid values + are 0 (no clicks reported) through 1000ms. In x11, the timeout can + also be set via the clickPeriod resource. The return value from + mouseinterval() is the old timeout. To check the old value without + setting a new one, call it with a parameter of -1. Note that although + there's no classic equivalent for this function (apart from the + clickPeriod resource), the value set applies in both interfaces. + + wenclose() reports whether the given screen-relative y, x coordinates + fall within the given window. + + wmouse_trafo() converts between screen-relative and window-relative + coordinates. A to_screen parameter of TRUE means to convert from + window to screen; otherwise the reverse. The function returns FALSE + if the coordinates aren't within the window, or if any of the + parameters are NULL. The coordinates have been converted when the + function returns TRUE. + + mouse_trafo() is the stdscr version of wmouse_trafo(). + + mousemask() is nearly equivalent to mouse_set(), but instead of + OK/ERR, it returns the value of the mask after setting it. (This + isn't necessarily the same value passed in, since the mask could be + altered on some platforms.) And if the second parameter is a non-null + pointer, mousemask() stores the previous mask value there. Also, + since the ncurses interface doesn't work with PDCurses' BUTTON_MOVED + events, mousemask() filters them out. + + nc_getmouse() returns the current mouse status in an MEVENT struct. + This is equivalent to ncurses' getmouse(), renamed to avoid conflict + with PDCurses' getmouse(). But if you define PDC_NCMOUSE before + including curses.h, it defines getmouse() to nc_getmouse(), along + with a few other redefintions needed for compatibility with ncurses + code. nc_getmouse() calls request_mouse_pos(), which (not getmouse()) + is the classic equivalent. + + ungetmouse() is the mouse equivalent of ungetch(). However, PDCurses + doesn't maintain a queue of mouse events; only one can be pushed + back, and it can overwrite or be overwritten by real mouse events. + + has_mouse() reports whether the mouse is available at all on the + current platform. + +### Portability + X/Open ncurses NetBSD + mouse_set - - - + mouse_on - - - + mouse_off - - - + request_mouse_pos - - - + wmouse_position - - - + getmouse - * - + mouseinterval - Y - + wenclose - Y - + wmouse_trafo - Y - + mouse_trafo - Y - + mousemask - Y - + nc_getmouse - * - + ungetmouse - Y - + has_mouse - Y - + + * See above, under Description + +**man-end****************************************************************/ + +#include <string.h> + +static bool ungot = FALSE; + +int mouse_set(mmask_t mbe) +{ + PDC_LOG(("mouse_set() - called: event %x\n", mbe)); + + if (!SP) + return ERR; + + SP->_trap_mbe = mbe; + return PDC_mouse_set(); +} + +int mouse_on(mmask_t mbe) +{ + PDC_LOG(("mouse_on() - called: event %x\n", mbe)); + + if (!SP) + return ERR; + + SP->_trap_mbe |= mbe; + return PDC_mouse_set(); +} + +int mouse_off(mmask_t mbe) +{ + PDC_LOG(("mouse_off() - called: event %x\n", mbe)); + + if (!SP) + return ERR; + + SP->_trap_mbe &= ~mbe; + return PDC_mouse_set(); +} + +int request_mouse_pos(void) +{ + PDC_LOG(("request_mouse_pos() - called\n")); + + Mouse_status = SP->mouse_status; + + return OK; +} + +void wmouse_position(WINDOW *win, int *y, int *x) +{ + PDC_LOG(("wmouse_position() - called\n")); + + if (win && wenclose(win, MOUSE_Y_POS, MOUSE_X_POS)) + { + if (y) + *y = MOUSE_Y_POS - win->_begy; + if (x) + *x = MOUSE_X_POS - win->_begx; + } + else + { + if (y) + *y = -1; + if (x) + *x = -1; + } +} + +mmask_t getmouse(void) +{ + PDC_LOG(("getmouse() - called\n")); + + return SP ? SP->_trap_mbe : (mmask_t)0; +} + +/* ncurses mouse interface */ + +int mouseinterval(int wait) +{ + int old_wait; + + PDC_LOG(("mouseinterval() - called: %d\n", wait)); + + if (!SP) + return ERR; + + old_wait = SP->mouse_wait; + + if (wait >= 0 && wait <= 1000) + SP->mouse_wait = wait; + + return old_wait; +} + +bool wenclose(const WINDOW *win, int y, int x) +{ + PDC_LOG(("wenclose() - called: %p %d %d\n", win, y, x)); + + return (win && y >= win->_begy && y < win->_begy + win->_maxy + && x >= win->_begx && x < win->_begx + win->_maxx); +} + +bool wmouse_trafo(const WINDOW *win, int *y, int *x, bool to_screen) +{ + int newy, newx; + + PDC_LOG(("wmouse_trafo() - called\n")); + + if (!win || !y || !x) + return FALSE; + + newy = *y; + newx = *x; + + if (to_screen) + { + newy += win->_begy; + newx += win->_begx; + + if (!wenclose(win, newy, newx)) + return FALSE; + } + else + { + if (wenclose(win, newy, newx)) + { + newy -= win->_begy; + newx -= win->_begx; + } + else + return FALSE; + } + + *y = newy; + *x = newx; + + return TRUE; +} + +bool mouse_trafo(int *y, int *x, bool to_screen) +{ + PDC_LOG(("mouse_trafo() - called\n")); + + return wmouse_trafo(stdscr, y, x, to_screen); +} + +mmask_t mousemask(mmask_t mask, mmask_t *oldmask) +{ + PDC_LOG(("mousemask() - called\n")); + + if (!SP) + return (mmask_t)0; + + if (oldmask) + *oldmask = SP->_trap_mbe; + + /* The ncurses interface doesn't work with our move events, so + filter them here */ + + mask &= ~(BUTTON1_MOVED | BUTTON2_MOVED | BUTTON3_MOVED); + + mouse_set(mask); + + return SP->_trap_mbe; +} + +int nc_getmouse(MEVENT *event) +{ + int i; + mmask_t bstate = 0; + + PDC_LOG(("nc_getmouse() - called\n")); + + if (!event || !SP) + return ERR; + + ungot = FALSE; + + request_mouse_pos(); + + event->id = 0; + + event->x = Mouse_status.x; + event->y = Mouse_status.y; + event->z = 0; + + for (i = 0; i < 3; i++) + { + if (Mouse_status.changes & (1 << i)) + { + int shf = i * 5; + short button = Mouse_status.button[i] & BUTTON_ACTION_MASK; + + if (button == BUTTON_RELEASED) + bstate |= (BUTTON1_RELEASED << shf); + else if (button == BUTTON_PRESSED) + bstate |= (BUTTON1_PRESSED << shf); + else if (button == BUTTON_CLICKED) + bstate |= (BUTTON1_CLICKED << shf); + else if (button == BUTTON_DOUBLE_CLICKED) + bstate |= (BUTTON1_DOUBLE_CLICKED << shf); + + button = Mouse_status.button[i] & BUTTON_MODIFIER_MASK; + + if (button & PDC_BUTTON_SHIFT) + bstate |= BUTTON_MODIFIER_SHIFT; + if (button & PDC_BUTTON_CONTROL) + bstate |= BUTTON_MODIFIER_CONTROL; + if (button & PDC_BUTTON_ALT) + bstate |= BUTTON_MODIFIER_ALT; + } + } + + if (MOUSE_WHEEL_UP) + bstate |= BUTTON4_PRESSED; + else if (MOUSE_WHEEL_DOWN) + bstate |= BUTTON5_PRESSED; + + /* extra filter pass -- mainly for button modifiers */ + + event->bstate = bstate & SP->_trap_mbe; + + return OK; +} + +int ungetmouse(MEVENT *event) +{ + int i; + mmask_t bstate; + + PDC_LOG(("ungetmouse() - called\n")); + + if (!event || ungot) + return ERR; + + ungot = TRUE; + + SP->mouse_status.x = event->x; + SP->mouse_status.y = event->y; + + SP->mouse_status.changes = 0; + bstate = event->bstate; + + for (i = 0; i < 3; i++) + { + int shf = i * 5; + short button = 0; + + if (bstate & ((BUTTON1_RELEASED | BUTTON1_PRESSED | + BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED) << shf)) + { + SP->mouse_status.changes |= 1 << i; + + if (bstate & (BUTTON1_PRESSED << shf)) + button = BUTTON_PRESSED; + if (bstate & (BUTTON1_CLICKED << shf)) + button = BUTTON_CLICKED; + if (bstate & (BUTTON1_DOUBLE_CLICKED << shf)) + button = BUTTON_DOUBLE_CLICKED; + + if (bstate & BUTTON_MODIFIER_SHIFT) + button |= PDC_BUTTON_SHIFT; + if (bstate & BUTTON_MODIFIER_CONTROL) + button |= PDC_BUTTON_CONTROL; + if (bstate & BUTTON_MODIFIER_ALT) + button |= PDC_BUTTON_ALT; + } + + SP->mouse_status.button[i] = button; + } + + if (bstate & BUTTON4_PRESSED) + SP->mouse_status.changes |= PDC_MOUSE_WHEEL_UP; + else if (bstate & BUTTON5_PRESSED) + SP->mouse_status.changes |= PDC_MOUSE_WHEEL_DOWN; + + return PDC_ungetch(KEY_MOUSE); +} + +bool has_mouse(void) +{ + return PDC_has_mouse(); +} diff --git a/Utilities/cmpdcurses/pdcurses/move.c b/Utilities/cmpdcurses/pdcurses/move.c new file mode 100644 index 0000000..05f4aaa --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/move.c @@ -0,0 +1,77 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +move +---- + +### Synopsis + + int move(int y, int x); + int mvcur(int oldrow, int oldcol, int newrow, int newcol); + int wmove(WINDOW *win, int y, int x); + +### Description + + move() and wmove() move the cursor associated with the window to the + given location. This does not move the physical cursor of the + terminal until refresh() is called. The position specified is + relative to the upper left corner of the window, which is (0,0). + + mvcur() moves the physical cursor without updating any window cursor + positions. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + move Y Y Y + mvcur Y Y Y + wmove Y Y Y + +**man-end****************************************************************/ + +int move(int y, int x) +{ + PDC_LOG(("move() - called: y=%d x=%d\n", y, x)); + + if (!stdscr || x < 0 || y < 0 || x >= stdscr->_maxx || y >= stdscr->_maxy) + return ERR; + + stdscr->_curx = x; + stdscr->_cury = y; + + return OK; +} + +int mvcur(int oldrow, int oldcol, int newrow, int newcol) +{ + PDC_LOG(("mvcur() - called: oldrow %d oldcol %d newrow %d newcol %d\n", + oldrow, oldcol, newrow, newcol)); + + if (!SP || newrow < 0 || newrow >= LINES || newcol < 0 || newcol >= COLS) + return ERR; + + PDC_gotoyx(newrow, newcol); + SP->cursrow = newrow; + SP->curscol = newcol; + + return OK; +} + +int wmove(WINDOW *win, int y, int x) +{ + PDC_LOG(("wmove() - called: y=%d x=%d\n", y, x)); + + if (!win || x < 0 || y < 0 || x >= win->_maxx || y >= win->_maxy) + return ERR; + + win->_curx = x; + win->_cury = y; + + return OK; +} diff --git a/Utilities/cmpdcurses/pdcurses/outopts.c b/Utilities/cmpdcurses/pdcurses/outopts.c new file mode 100644 index 0000000..f13715a --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/outopts.c @@ -0,0 +1,175 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +outopts +------- + +### Synopsis + + int clearok(WINDOW *win, bool bf); + int idlok(WINDOW *win, bool bf); + void idcok(WINDOW *win, bool bf); + void immedok(WINDOW *win, bool bf); + int leaveok(WINDOW *win, bool bf); + int setscrreg(int top, int bot); + int wsetscrreg(WINDOW *win, int top, int bot); + int scrollok(WINDOW *win, bool bf); + + int raw_output(bool bf); + + bool is_leaveok(const WINDOW *win); + +### Description + + With clearok(), if bf is TRUE, the next call to wrefresh() with this + window will clear the screen completely and redraw the entire screen. + + immedok(), called with a second argument of TRUE, causes an automatic + wrefresh() every time a change is made to the specified window. + + Normally, the hardware cursor is left at the location of the window + being refreshed. leaveok() allows the cursor to be left wherever the + update happens to leave it. It's useful for applications where the + cursor is not used, since it reduces the need for cursor motions. If + possible, the cursor is made invisible when this option is enabled. + + wsetscrreg() sets a scrolling region in a window; "top" and "bot" are + the line numbers for the top and bottom margins. If this option and + scrollok() are enabled, any attempt to move off the bottom margin + will cause all lines in the scrolling region to scroll up one line. + setscrreg() is the stdscr version. + + idlok() and idcok() do nothing in PDCurses, but are provided for + compatibility with other curses implementations. + + raw_output() enables the output of raw characters using the standard + *add* and *ins* curses functions (that is, it disables translation of + control characters). + + is_leaveok() reports whether the specified window is in leaveok mode. + +### Return Value + + All functions except is_leaveok() return OK on success and ERR on + error. + +### Portability + X/Open ncurses NetBSD + clearok Y Y Y + idlok Y Y Y + idcok Y Y Y + immedok Y Y Y + leaveok Y Y Y + setscrreg Y Y Y + wsetscrreg Y Y Y + scrollok Y Y Y + is_leaveok - Y Y + raw_output - - - + +**man-end****************************************************************/ + +int clearok(WINDOW *win, bool bf) +{ + PDC_LOG(("clearok() - called\n")); + + if (!win) + return ERR; + + win->_clear = bf; + + return OK; +} + +int idlok(WINDOW *win, bool bf) +{ + PDC_LOG(("idlok() - called\n")); + + return OK; +} + +void idcok(WINDOW *win, bool bf) +{ + PDC_LOG(("idcok() - called\n")); +} + +void immedok(WINDOW *win, bool bf) +{ + PDC_LOG(("immedok() - called\n")); + + if (win) + win->_immed = bf; +} + +int leaveok(WINDOW *win, bool bf) +{ + PDC_LOG(("leaveok() - called\n")); + + if (!win) + return ERR; + + win->_leaveit = bf; + + curs_set(!bf); + + return OK; +} + +int setscrreg(int top, int bottom) +{ + PDC_LOG(("setscrreg() - called: top %d bottom %d\n", top, bottom)); + + return wsetscrreg(stdscr, top, bottom); +} + +int wsetscrreg(WINDOW *win, int top, int bottom) +{ + PDC_LOG(("wsetscrreg() - called: top %d bottom %d\n", top, bottom)); + + if (win && 0 <= top && top <= win->_cury && + win->_cury <= bottom && bottom < win->_maxy) + { + win->_tmarg = top; + win->_bmarg = bottom; + + return OK; + } + else + return ERR; +} + +int scrollok(WINDOW *win, bool bf) +{ + PDC_LOG(("scrollok() - called\n")); + + if (!win) + return ERR; + + win->_scroll = bf; + + return OK; +} + +int raw_output(bool bf) +{ + PDC_LOG(("raw_output() - called\n")); + + if (!SP) + return ERR; + + SP->raw_out = bf; + + return OK; +} + +bool is_leaveok(const WINDOW *win) +{ + PDC_LOG(("is_leaveok() - called\n")); + + if (!win) + return FALSE; + + return win->_leaveit; +} diff --git a/Utilities/cmpdcurses/pdcurses/overlay.c b/Utilities/cmpdcurses/pdcurses/overlay.c new file mode 100644 index 0000000..5bcc627 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/overlay.c @@ -0,0 +1,214 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +overlay +------- + +### Synopsis + + int overlay(const WINDOW *src_w, WINDOW *dst_w) + int overwrite(const WINDOW *src_w, WINDOW *dst_w) + int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, + int src_tc, int dst_tr, int dst_tc, int dst_br, + int dst_bc, int _overlay) + +### Description + + overlay() and overwrite() copy all the text from src_w into dst_w. + The windows need not be the same size. Those characters in the source + window that intersect with the destination window are copied, so that + the characters appear in the same physical position on the screen. + The difference between the two functions is that overlay() is non- + destructive (blanks are not copied) while overwrite() is destructive + (blanks are copied). + + copywin() is similar, but doesn't require that the two windows + overlap. The arguments src_tc and src_tr specify the top left corner + of the region to be copied. dst_tc, dst_tr, dst_br, and dst_bc + specify the region within the destination window to copy to. The + argument "overlay", if TRUE, indicates that the copy is done non- + destructively (as in overlay()); blanks in the source window are not + copied to the destination window. When overlay is FALSE, blanks are + copied. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + overlay Y Y Y + overwrite Y Y Y + copywin Y Y Y + +**man-end****************************************************************/ + +/* Thanks to Andreas Otte <venn@@uni-paderborn.de> for the + corrected overlay()/overwrite() behavior. */ + +static int _copy_win(const WINDOW *src_w, WINDOW *dst_w, int src_tr, + int src_tc, int src_br, int src_bc, int dst_tr, + int dst_tc, bool _overlay) +{ + int col, line, y1, fc, *minchng, *maxchng; + chtype *w1ptr, *w2ptr; + + int lc = 0; + int xdiff = src_bc - src_tc; + int ydiff = src_br - src_tr; + + if (!src_w || !dst_w) + return ERR; + + minchng = dst_w->_firstch; + maxchng = dst_w->_lastch; + + for (y1 = 0; y1 < dst_tr; y1++) + { + minchng++; + maxchng++; + } + + for (line = 0; line < ydiff; line++) + { + w1ptr = src_w->_y[line + src_tr] + src_tc; + w2ptr = dst_w->_y[line + dst_tr] + dst_tc; + + fc = _NO_CHANGE; + + for (col = 0; col < xdiff; col++) + { + if ((*w1ptr) != (*w2ptr) && + !((*w1ptr & A_CHARTEXT) == ' ' && _overlay)) + { + *w2ptr = *w1ptr; + + if (fc == _NO_CHANGE) + fc = col + dst_tc; + + lc = col + dst_tc; + } + + w1ptr++; + w2ptr++; + } + + if (*minchng == _NO_CHANGE) + { + *minchng = fc; + *maxchng = lc; + } + else if (fc != _NO_CHANGE) + { + if (fc < *minchng) + *minchng = fc; + if (lc > *maxchng) + *maxchng = lc; + } + + minchng++; + maxchng++; + } + + return OK; +} + +int _copy_overlap(const WINDOW *src_w, WINDOW *dst_w, bool overlay) +{ + int first_line, first_col, last_line, last_col; + int src_start_x, src_start_y, dst_start_x, dst_start_y; + int xdiff, ydiff; + + if (!src_w || !dst_w) + return ERR; + + first_col = max(dst_w->_begx, src_w->_begx); + first_line = max(dst_w->_begy, src_w->_begy); + + last_col = min(src_w->_begx + src_w->_maxx, dst_w->_begx + dst_w->_maxx); + last_line = min(src_w->_begy + src_w->_maxy, dst_w->_begy + dst_w->_maxy); + + /* determine the overlapping region of the two windows in real + coordinates */ + + /* if no overlapping region, do nothing */ + + if ((last_col < first_col) || (last_line < first_line)) + return OK; + + /* size of overlapping region */ + + xdiff = last_col - first_col; + ydiff = last_line - first_line; + + if (src_w->_begx <= dst_w->_begx) + { + src_start_x = dst_w->_begx - src_w->_begx; + dst_start_x = 0; + } + else + { + dst_start_x = src_w->_begx - dst_w->_begx; + src_start_x = 0; + } + + if (src_w->_begy <= dst_w->_begy) + { + src_start_y = dst_w->_begy - src_w->_begy; + dst_start_y = 0; + } + else + { + dst_start_y = src_w->_begy - dst_w->_begy; + src_start_y = 0; + } + + return _copy_win(src_w, dst_w, src_start_y, src_start_x, + src_start_y + ydiff, src_start_x + xdiff, + dst_start_y, dst_start_x, overlay); +} + +int overlay(const WINDOW *src_w, WINDOW *dst_w) +{ + PDC_LOG(("overlay() - called\n")); + + return _copy_overlap(src_w, dst_w, TRUE); +} + +int overwrite(const WINDOW *src_w, WINDOW *dst_w) +{ + PDC_LOG(("overwrite() - called\n")); + + return _copy_overlap(src_w, dst_w, FALSE); +} + +int copywin(const WINDOW *src_w, WINDOW *dst_w, int src_tr, int src_tc, + int dst_tr, int dst_tc, int dst_br, int dst_bc, int _overlay) +{ + int src_end_x, src_end_y; + int src_rows, src_cols, dst_rows, dst_cols; + int min_rows, min_cols; + + PDC_LOG(("copywin() - called\n")); + + if (!src_w || !dst_w || dst_w == curscr || dst_br >= dst_w->_maxy + || dst_bc >= dst_w->_maxx || dst_tr < 0 || dst_tc < 0) + return ERR; + + src_rows = src_w->_maxy - src_tr; + src_cols = src_w->_maxx - src_tc; + dst_rows = dst_br - dst_tr + 1; + dst_cols = dst_bc - dst_tc + 1; + + min_rows = min(src_rows, dst_rows); + min_cols = min(src_cols, dst_cols); + + src_end_y = src_tr + min_rows; + src_end_x = src_tc + min_cols; + + return _copy_win(src_w, dst_w, src_tr, src_tc, src_end_y, src_end_x, + dst_tr, dst_tc, _overlay); +} diff --git a/Utilities/cmpdcurses/pdcurses/pad.c b/Utilities/cmpdcurses/pdcurses/pad.c new file mode 100644 index 0000000..da8e968 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/pad.c @@ -0,0 +1,280 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +pad +--- + +### Synopsis + + WINDOW *newpad(int nlines, int ncols); + WINDOW *subpad(WINDOW *orig, int nlines, int ncols, + int begy, int begx); + int prefresh(WINDOW *win, int py, int px, int sy1, int sx1, + int sy2, int sx2); + int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, + int sy2, int sx2); + int pechochar(WINDOW *pad, chtype ch); + int pecho_wchar(WINDOW *pad, const cchar_t *wch); + + bool is_pad(const WINDOW *pad); + +### Description + + A pad is a special kind of window, which is not restricted by the + screen size, and is not necessarily associated with a particular part + of the screen. You can use a pad when you need a large window, and + only a part of the window will be on the screen at one time. Pads are + not refreshed automatically (e.g., from scrolling or echoing of + input). You can't call wrefresh() with a pad as an argument; use + prefresh() or pnoutrefresh() instead. Note that these routines + require additional parameters to specify the part of the pad to be + displayed, and the location to use on the screen. + + newpad() creates a new pad data structure. + + subpad() creates a new sub-pad within a pad, at position (begy, + begx), with dimensions of nlines lines and ncols columns. This + position is relative to the pad, and not to the screen as with + subwin. Changes to either the parent pad or sub-pad will affect both. + When using sub-pads, you may need to call touchwin() before calling + prefresh(). + + pnoutrefresh() copies the specified pad to the virtual screen. + + prefresh() calls pnoutrefresh(), followed by doupdate(). + + These routines are analogous to wnoutrefresh() and wrefresh(). (py, + px) specifies the upper left corner of the part of the pad to be + displayed; (sy1, sx1) and (sy2, sx2) describe the screen rectangle + that will contain the selected part of the pad. + + pechochar() is functionally equivalent to addch() followed by a call + to prefresh(), with the last-used coordinates and dimensions. + pecho_wchar() is the wide-character version. + + is_pad() reports whether the specified window is a pad. + +### Return Value + + All functions except is_pad() return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + newpad Y Y Y + subpad Y Y Y + prefresh Y Y Y + pnoutrefresh Y Y Y + pechochar Y Y Y + pecho_wchar Y Y Y + is_pad - Y Y + +**man-end****************************************************************/ + +#include <string.h> + +/* save values for pechochar() */ + +static int save_pminrow, save_pmincol; +static int save_sminrow, save_smincol, save_smaxrow, save_smaxcol; + +WINDOW *newpad(int nlines, int ncols) +{ + WINDOW *win; + + PDC_LOG(("newpad() - called: lines=%d cols=%d\n", nlines, ncols)); + + win = PDC_makenew(nlines, ncols, 0, 0); + if (win) + win = PDC_makelines(win); + + if (!win) + return (WINDOW *)NULL; + + werase(win); + + win->_flags = _PAD; + + /* save default values in case pechochar() is the first call to + prefresh(). */ + + save_pminrow = 0; + save_pmincol = 0; + save_sminrow = 0; + save_smincol = 0; + save_smaxrow = min(LINES, nlines) - 1; + save_smaxcol = min(COLS, ncols) - 1; + + return win; +} + +WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx) +{ + WINDOW *win; + int i; + + PDC_LOG(("subpad() - called: lines=%d cols=%d begy=%d begx=%d\n", + nlines, ncols, begy, begx)); + + if (!orig || !(orig->_flags & _PAD)) + return (WINDOW *)NULL; + + /* make sure window fits inside the original one */ + + if (begy < 0 || begx < 0 || + (begy + nlines) > orig->_maxy || + (begx + ncols) > orig->_maxx) + return (WINDOW *)NULL; + + if (!nlines) + nlines = orig->_maxy - begy; + + if (!ncols) + ncols = orig->_maxx - begx; + + win = PDC_makenew(nlines, ncols, begy, begx); + if (!win) + return (WINDOW *)NULL; + + /* initialize window variables */ + + win->_attrs = orig->_attrs; + win->_leaveit = orig->_leaveit; + win->_scroll = orig->_scroll; + win->_nodelay = orig->_nodelay; + win->_use_keypad = orig->_use_keypad; + win->_parent = orig; + + for (i = 0; i < nlines; i++) + win->_y[i] = orig->_y[begy + i] + begx; + + win->_flags = _SUBPAD; + + /* save default values in case pechochar() is the first call + to prefresh(). */ + + save_pminrow = 0; + save_pmincol = 0; + save_sminrow = 0; + save_smincol = 0; + save_smaxrow = min(LINES, nlines) - 1; + save_smaxcol = min(COLS, ncols) - 1; + + return win; +} + +int prefresh(WINDOW *win, int py, int px, int sy1, int sx1, int sy2, int sx2) +{ + PDC_LOG(("prefresh() - called\n")); + + if (pnoutrefresh(win, py, px, sy1, sx1, sy2, sx2) == ERR) + return ERR; + + doupdate(); + return OK; +} + +int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2) +{ + int num_cols; + int sline; + int pline; + + PDC_LOG(("pnoutrefresh() - called\n")); + + if (py < 0) + py = 0; + if (px < 0) + px = 0; + if (sy1 < 0) + sy1 = 0; + if (sx1 < 0) + sx1 = 0; + + if ((!w || !(w->_flags & (_PAD|_SUBPAD)) || + (sy2 >= LINES) || (sx2 >= COLS)) || + (sy2 < sy1) || (sx2 < sx1)) + return ERR; + + sline = sy1; + pline = py; + + num_cols = min((sx2 - sx1 + 1), (w->_maxx - px)); + + while (sline <= sy2) + { + if (pline < w->_maxy) + { + memcpy(curscr->_y[sline] + sx1, w->_y[pline] + px, + num_cols * sizeof(chtype)); + + if ((curscr->_firstch[sline] == _NO_CHANGE) + || (curscr->_firstch[sline] > sx1)) + curscr->_firstch[sline] = sx1; + + if (sx2 > curscr->_lastch[sline]) + curscr->_lastch[sline] = sx2; + + w->_firstch[pline] = _NO_CHANGE; /* updated now */ + w->_lastch[pline] = _NO_CHANGE; /* updated now */ + } + + sline++; + pline++; + } + + if (w->_clear) + { + w->_clear = FALSE; + curscr->_clear = TRUE; + } + + /* position the cursor to the pad's current position if possible -- + is the pad current position going to end up displayed? if not, + then don't move the cursor; if so, move it to the correct place */ + + if (!w->_leaveit && w->_cury >= py && w->_curx >= px && + w->_cury <= py + (sy2 - sy1) && w->_curx <= px + (sx2 - sx1)) + { + curscr->_cury = (w->_cury - py) + sy1; + curscr->_curx = (w->_curx - px) + sx1; + } + + return OK; +} + +int pechochar(WINDOW *pad, chtype ch) +{ + PDC_LOG(("pechochar() - called\n")); + + if (waddch(pad, ch) == ERR) + return ERR; + + return prefresh(pad, save_pminrow, save_pmincol, save_sminrow, + save_smincol, save_smaxrow, save_smaxcol); +} + +#ifdef PDC_WIDE +int pecho_wchar(WINDOW *pad, const cchar_t *wch) +{ + PDC_LOG(("pecho_wchar() - called\n")); + + if (!wch || (waddch(pad, *wch) == ERR)) + return ERR; + + return prefresh(pad, save_pminrow, save_pmincol, save_sminrow, + save_smincol, save_smaxrow, save_smaxcol); +} +#endif + +bool is_pad(const WINDOW *pad) +{ + PDC_LOG(("is_pad() - called\n")); + + if (!pad) + return FALSE; + + return (pad->_flags & _PAD) ? TRUE : FALSE; +} diff --git a/Utilities/cmpdcurses/pdcurses/panel.c b/Utilities/cmpdcurses/pdcurses/panel.c new file mode 100644 index 0000000..b3c48fc --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/panel.c @@ -0,0 +1,633 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +panel +----- + +### Synopsis + + int bottom_panel(PANEL *pan); + int del_panel(PANEL *pan); + int hide_panel(PANEL *pan); + int move_panel(PANEL *pan, int starty, int startx); + PANEL *new_panel(WINDOW *win); + PANEL *panel_above(const PANEL *pan); + PANEL *panel_below(const PANEL *pan); + int panel_hidden(const PANEL *pan); + const void *panel_userptr(const PANEL *pan); + WINDOW *panel_window(const PANEL *pan); + int replace_panel(PANEL *pan, WINDOW *win); + int set_panel_userptr(PANEL *pan, const void *uptr); + int show_panel(PANEL *pan); + int top_panel(PANEL *pan); + void update_panels(void); + +### Description + + For historic reasons, and for compatibility with other versions of + curses, the panel functions are prototyped in a separate header, + panel.h. In many implementations, they're also in a separate library, + but PDCurses incorporates them. + + The panel functions provide a way to have depth relationships between + curses windows. Panels can overlap without making visible the + overlapped portions of underlying windows. The initial curses window, + stdscr, lies beneath all panels. The set of currently visible panels + is the 'deck' of panels. + + You can create panels, fetch and set their associated windows, + shuffle panels in the deck, and manipulate them in other ways. + + bottom_panel() places pan at the bottom of the deck. The size, + location and contents of the panel are unchanged. + + del_panel() deletes pan, but not its associated winwow. + + hide_panel() removes a panel from the deck and thus hides it from + view. + + move_panel() moves the curses window associated with pan, so that its + upper lefthand corner is at the supplied coordinates. (Don't use + mvwin() on the window.) + + new_panel() creates a new panel associated with win and returns the + panel pointer. The new panel is placed at the top of the deck. + + panel_above() returns a pointer to the panel in the deck above pan, + or NULL if pan is the top panel. If the value of pan passed is NULL, + this function returns a pointer to the bottom panel in the deck. + + panel_below() returns a pointer to the panel in the deck below pan, + or NULL if pan is the bottom panel. If the value of pan passed is + NULL, this function returns a pointer to the top panel in the deck. + + panel_hidden() returns OK if pan is hidden and ERR if it is not. + + panel_userptr() - Each panel has a user pointer available for + maintaining relevant information. This function returns a pointer to + that information previously set up by set_panel_userptr(). + + panel_window() returns a pointer to the curses window associated with + the panel. + + replace_panel() replaces the current window of pan with win. + + set_panel_userptr() - Each panel has a user pointer available for + maintaining relevant information. This function sets the value of + that information. + + show_panel() makes a previously hidden panel visible and places it + back in the deck on top. + + top_panel() places pan on the top of the deck. The size, location and + contents of the panel are unchanged. + + update_panels() refreshes the virtual screen to reflect the depth + relationships between the panels in the deck. The user must use + doupdate() to refresh the physical screen. + +### Return Value + + Each routine that returns a pointer to an object returns NULL if an + error occurs. Each panel routine that returns an integer, returns OK + if it executes successfully and ERR if it does not. + +### Portability + X/Open ncurses NetBSD + bottom_panel - Y Y + del_panel - Y Y + hide_panel - Y Y + move_panel - Y Y + new_panel - Y Y + panel_above - Y Y + panel_below - Y Y + panel_hidden - Y Y + panel_userptr - Y Y + panel_window - Y Y + replace_panel - Y Y + set_panel_userptr - Y Y + show_panel - Y Y + top_panel - Y Y + update_panels - Y Y + + Credits: + Original Author - Warren Tucker <wht@n4hgf.mt-park.ga.us> + +**man-end****************************************************************/ + +#include <panel.h> +#include <stdlib.h> + +PANEL *_bottom_panel = (PANEL *)0; +PANEL *_top_panel = (PANEL *)0; +PANEL _stdscr_pseudo_panel = { (WINDOW *)0 }; + +#ifdef PANEL_DEBUG + +static void dPanel(char *text, PANEL *pan) +{ + PDC_LOG(("%s id=%s b=%s a=%s y=%d x=%d", text, pan->user, + pan->below ? pan->below->user : "--", + pan->above ? pan->above->user : "--", + pan->wstarty, pan->wstartx)); +} + +static void dStack(char *fmt, int num, PANEL *pan) +{ + char s80[80]; + + sprintf(s80, fmt, num, pan); + PDC_LOG(("%s b=%s t=%s", s80, _bottom_panel ? _bottom_panel->user : "--", + _top_panel ? _top_panel->user : "--")); + + if (pan) + PDC_LOG(("pan id=%s", pan->user)); + + pan = _bottom_panel; + + while (pan) + { + dPanel("stk", pan); + pan = pan->above; + } +} + +/* debugging hook for wnoutrefresh */ + +static void Wnoutrefresh(PANEL *pan) +{ + dPanel("wnoutrefresh", pan); + wnoutrefresh(pan->win); +} + +static void Touchpan(PANEL *pan) +{ + dPanel("Touchpan", pan); + touchwin(pan->win); +} + +static void Touchline(PANEL *pan, int start, int count) +{ + char s80[80]; + + sprintf(s80, "Touchline s=%d c=%d", start, count); + dPanel(s80, pan); + touchline(pan->win, start, count); +} + +#else /* PANEL_DEBUG */ + +#define dPanel(text, pan) +#define dStack(fmt, num, pan) +#define Wnoutrefresh(pan) wnoutrefresh((pan)->win) +#define Touchpan(pan) touchwin((pan)->win) +#define Touchline(pan, start, count) touchline((pan)->win, start, count) + +#endif /* PANEL_DEBUG */ + +static bool _panels_overlapped(PANEL *pan1, PANEL *pan2) +{ + if (!pan1 || !pan2) + return FALSE; + + return ((pan1->wstarty >= pan2->wstarty && pan1->wstarty < pan2->wendy) + || (pan2->wstarty >= pan1->wstarty && pan2->wstarty < pan1->wendy)) + && ((pan1->wstartx >= pan2->wstartx && pan1->wstartx < pan2->wendx) + || (pan2->wstartx >= pan1->wstartx && pan2->wstartx < pan1->wendx)); +} + +static void _free_obscure(PANEL *pan) +{ + PANELOBS *tobs = pan->obscure; /* "this" one */ + PANELOBS *nobs; /* "next" one */ + + while (tobs) + { + nobs = tobs->above; + free((char *)tobs); + tobs = nobs; + } + pan->obscure = (PANELOBS *)0; +} + +static void _override(PANEL *pan, int show) +{ + int y; + PANEL *pan2; + PANELOBS *tobs = pan->obscure; /* "this" one */ + + if (show == 1) + Touchpan(pan); + else if (!show) + { + Touchpan(pan); + Touchpan(&_stdscr_pseudo_panel); + } + else if (show == -1) + while (tobs && (tobs->pan != pan)) + tobs = tobs->above; + + while (tobs) + { + if ((pan2 = tobs->pan) != pan) + for (y = pan->wstarty; y < pan->wendy; y++) + if ((y >= pan2->wstarty) && (y < pan2->wendy) && + ((is_linetouched(pan->win, y - pan->wstarty)) || + (is_linetouched(stdscr, y)))) + Touchline(pan2, y - pan2->wstarty, 1); + + tobs = tobs->above; + } +} + +static void _calculate_obscure(void) +{ + PANEL *pan, *pan2; + PANELOBS *tobs; /* "this" one */ + PANELOBS *lobs; /* last one */ + + pan = _bottom_panel; + + while (pan) + { + if (pan->obscure) + _free_obscure(pan); + + lobs = (PANELOBS *)0; + pan2 = _bottom_panel; + + while (pan2) + { + if (_panels_overlapped(pan, pan2)) + { + if ((tobs = malloc(sizeof(PANELOBS))) == NULL) + return; + + tobs->pan = pan2; + dPanel("obscured", pan2); + tobs->above = (PANELOBS *)0; + + if (lobs) + lobs->above = tobs; + else + pan->obscure = tobs; + + lobs = tobs; + } + + pan2 = pan2->above; + } + + _override(pan, 1); + pan = pan->above; + } +} + +/* check to see if panel is in the stack */ + +static bool _panel_is_linked(const PANEL *pan) +{ + PANEL *pan2 = _bottom_panel; + + while (pan2) + { + if (pan2 == pan) + return TRUE; + + pan2 = pan2->above; + } + + return FALSE; +} + +/* link panel into stack at top */ + +static void _panel_link_top(PANEL *pan) +{ +#ifdef PANEL_DEBUG + dStack("<lt%d>", 1, pan); + if (_panel_is_linked(pan)) + return; +#endif + pan->above = (PANEL *)0; + pan->below = (PANEL *)0; + + if (_top_panel) + { + _top_panel->above = pan; + pan->below = _top_panel; + } + + _top_panel = pan; + + if (!_bottom_panel) + _bottom_panel = pan; + + _calculate_obscure(); + dStack("<lt%d>", 9, pan); +} + +/* link panel into stack at bottom */ + +static void _panel_link_bottom(PANEL *pan) +{ +#ifdef PANEL_DEBUG + dStack("<lb%d>", 1, pan); + if (_panel_is_linked(pan)) + return; +#endif + pan->above = (PANEL *)0; + pan->below = (PANEL *)0; + + if (_bottom_panel) + { + _bottom_panel->below = pan; + pan->above = _bottom_panel; + } + + _bottom_panel = pan; + + if (!_top_panel) + _top_panel = pan; + + _calculate_obscure(); + dStack("<lb%d>", 9, pan); +} + +static void _panel_unlink(PANEL *pan) +{ + PANEL *prev; + PANEL *next; + +#ifdef PANEL_DEBUG + dStack("<u%d>", 1, pan); + if (!_panel_is_linked(pan)) + return; +#endif + _override(pan, 0); + _free_obscure(pan); + + prev = pan->below; + next = pan->above; + + /* if non-zero, we will not update the list head */ + + if (prev) + { + prev->above = next; + if(next) + next->below = prev; + } + else if (next) + next->below = prev; + + if (pan == _bottom_panel) + _bottom_panel = next; + + if (pan == _top_panel) + _top_panel = prev; + + _calculate_obscure(); + + pan->above = (PANEL *)0; + pan->below = (PANEL *)0; + dStack("<u%d>", 9, pan); + +} + +/************************************************************************ + * The following are the public functions for the panels library. * + ************************************************************************/ + +int bottom_panel(PANEL *pan) +{ + if (!pan) + return ERR; + + if (pan == _bottom_panel) + return OK; + + if (_panel_is_linked(pan)) + hide_panel(pan); + + _panel_link_bottom(pan); + + return OK; +} + +int del_panel(PANEL *pan) +{ + if (pan) + { + if (_panel_is_linked(pan)) + hide_panel(pan); + + free((char *)pan); + return OK; + } + + return ERR; +} + +int hide_panel(PANEL *pan) +{ + if (!pan) + return ERR; + + if (!_panel_is_linked(pan)) + { + pan->above = (PANEL *)0; + pan->below = (PANEL *)0; + return ERR; + } + + _panel_unlink(pan); + + return OK; +} + +int move_panel(PANEL *pan, int starty, int startx) +{ + WINDOW *win; + int maxy, maxx; + + if (!pan) + return ERR; + + if (_panel_is_linked(pan)) + _override(pan, 0); + + win = pan->win; + + if (mvwin(win, starty, startx) == ERR) + return ERR; + + getbegyx(win, pan->wstarty, pan->wstartx); + getmaxyx(win, maxy, maxx); + pan->wendy = pan->wstarty + maxy; + pan->wendx = pan->wstartx + maxx; + + if (_panel_is_linked(pan)) + _calculate_obscure(); + + return OK; +} + +PANEL *new_panel(WINDOW *win) +{ + PANEL *pan; + + if (!win) + return (PANEL *)NULL; + + pan = malloc(sizeof(PANEL)); + + if (!_stdscr_pseudo_panel.win) + { + _stdscr_pseudo_panel.win = stdscr; + _stdscr_pseudo_panel.wstarty = 0; + _stdscr_pseudo_panel.wstartx = 0; + _stdscr_pseudo_panel.wendy = LINES; + _stdscr_pseudo_panel.wendx = COLS; + _stdscr_pseudo_panel.user = "stdscr"; + _stdscr_pseudo_panel.obscure = (PANELOBS *)0; + } + + if (pan) + { + int maxy, maxx; + + pan->win = win; + pan->above = (PANEL *)0; + pan->below = (PANEL *)0; + getbegyx(win, pan->wstarty, pan->wstartx); + getmaxyx(win, maxy, maxx); + pan->wendy = pan->wstarty + maxy; + pan->wendx = pan->wstartx + maxx; +#ifdef PANEL_DEBUG + pan->user = "new"; +#else + pan->user = (char *)0; +#endif + pan->obscure = (PANELOBS *)0; + show_panel(pan); + } + + return pan; +} + +PANEL *panel_above(const PANEL *pan) +{ + return pan ? pan->above : _bottom_panel; +} + +PANEL *panel_below(const PANEL *pan) +{ + return pan ? pan->below : _top_panel; +} + +int panel_hidden(const PANEL *pan) +{ + if (!pan) + return ERR; + + return _panel_is_linked(pan) ? ERR : OK; +} + +const void *panel_userptr(const PANEL *pan) +{ + return pan ? pan->user : NULL; +} + +WINDOW *panel_window(const PANEL *pan) +{ + PDC_LOG(("panel_window() - called\n")); + + if (!pan) + return (WINDOW *)NULL; + + return pan->win; +} + +int replace_panel(PANEL *pan, WINDOW *win) +{ + int maxy, maxx; + + if (!pan) + return ERR; + + if (_panel_is_linked(pan)) + _override(pan, 0); + + pan->win = win; + getbegyx(win, pan->wstarty, pan->wstartx); + getmaxyx(win, maxy, maxx); + pan->wendy = pan->wstarty + maxy; + pan->wendx = pan->wstartx + maxx; + + if (_panel_is_linked(pan)) + _calculate_obscure(); + + return OK; +} + +int set_panel_userptr(PANEL *pan, const void *uptr) +{ + if (!pan) + return ERR; + + pan->user = uptr; + return OK; +} + +int show_panel(PANEL *pan) +{ + if (!pan) + return ERR; + + if (pan == _top_panel) + return OK; + + if (_panel_is_linked(pan)) + hide_panel(pan); + + _panel_link_top(pan); + + return OK; +} + +int top_panel(PANEL *pan) +{ + return show_panel(pan); +} + +void update_panels(void) +{ + PANEL *pan; + + PDC_LOG(("update_panels() - called\n")); + + pan = _bottom_panel; + + while (pan) + { + _override(pan, -1); + pan = pan->above; + } + + if (is_wintouched(stdscr)) + Wnoutrefresh(&_stdscr_pseudo_panel); + + pan = _bottom_panel; + + while (pan) + { + if (is_wintouched(pan->win) || !pan->above) + Wnoutrefresh(pan); + + pan = pan->above; + } +} diff --git a/Utilities/cmpdcurses/pdcurses/printw.c b/Utilities/cmpdcurses/pdcurses/printw.c new file mode 100644 index 0000000..7d19a99 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/printw.c @@ -0,0 +1,129 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +printw +------ + +### Synopsis + + int printw(const char *fmt, ...); + int wprintw(WINDOW *win, const char *fmt, ...); + int mvprintw(int y, int x, const char *fmt, ...); + int mvwprintw(WINDOW *win, int y, int x, const char *fmt,...); + int vwprintw(WINDOW *win, const char *fmt, va_list varglist); + int vw_printw(WINDOW *win, const char *fmt, va_list varglist); + +### Description + + The printw() functions add a formatted string to the window at the + current or specified cursor position. The format strings are the same + as used in the standard C library's printf(). (printw() can be used + as a drop-in replacement for printf().) + + The duplication between vwprintw() and vw_printw() is for historic + reasons. In PDCurses, they're the same. + +### Return Value + + All functions return the number of characters printed, or ERR on + error. + +### Portability + X/Open ncurses NetBSD + printw Y Y Y + wprintw Y Y Y + mvprintw Y Y Y + mvwprintw Y Y Y + vwprintw Y Y Y + vw_printw Y Y Y + +**man-end****************************************************************/ + +#include <string.h> + +int vwprintw(WINDOW *win, const char *fmt, va_list varglist) +{ + char printbuf[513]; + int len; + + PDC_LOG(("vwprintw() - called\n")); + +#ifdef HAVE_VSNPRINTF + len = vsnprintf(printbuf, 512, fmt, varglist); +#else + len = vsprintf(printbuf, fmt, varglist); +#endif + return (waddstr(win, printbuf) == ERR) ? ERR : len; +} + +int printw(const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("printw() - called\n")); + + va_start(args, fmt); + retval = vwprintw(stdscr, fmt, args); + va_end(args); + + return retval; +} + +int wprintw(WINDOW *win, const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("wprintw() - called\n")); + + va_start(args, fmt); + retval = vwprintw(win, fmt, args); + va_end(args); + + return retval; +} + +int mvprintw(int y, int x, const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("mvprintw() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + va_start(args, fmt); + retval = vwprintw(stdscr, fmt, args); + va_end(args); + + return retval; +} + +int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("mvwprintw() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + va_start(args, fmt); + retval = vwprintw(win, fmt, args); + va_end(args); + + return retval; +} + +int vw_printw(WINDOW *win, const char *fmt, va_list varglist) +{ + PDC_LOG(("vw_printw() - called\n")); + + return vwprintw(win, fmt, varglist); +} diff --git a/Utilities/cmpdcurses/pdcurses/refresh.c b/Utilities/cmpdcurses/pdcurses/refresh.c new file mode 100644 index 0000000..cc0a25d --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/refresh.c @@ -0,0 +1,279 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +refresh +------- + +### Synopsis + + int refresh(void); + int wrefresh(WINDOW *win); + int wnoutrefresh(WINDOW *win); + int doupdate(void); + int redrawwin(WINDOW *win); + int wredrawln(WINDOW *win, int beg_line, int num_lines); + +### Description + + wrefresh() copies the named window to the physical terminal screen, + taking into account what is already there in order to optimize cursor + movement. refresh() does the same, using stdscr. These routines must + be called to get any output on the terminal, as other routines only + manipulate data structures. Unless leaveok() has been enabled, the + physical cursor of the terminal is left at the location of the + window's cursor. + + wnoutrefresh() and doupdate() allow multiple updates with more + efficiency than wrefresh() alone. wrefresh() works by first calling + wnoutrefresh(), which copies the named window to the virtual screen. + It then calls doupdate(), which compares the virtual screen to the + physical screen and does the actual update. A series of calls to + wrefresh() will result in alternating calls to wnoutrefresh() and + doupdate(), causing several bursts of output to the screen. By first + calling wnoutrefresh() for each window, it is then possible to call + doupdate() only once. + + In PDCurses, redrawwin() is equivalent to touchwin(), and wredrawln() + is the same as touchline(). In some other curses implementations, + there's a subtle distinction, but it has no meaning in PDCurses. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + refresh Y Y Y + wrefresh Y Y Y + wnoutrefresh Y Y Y + doupdate Y Y Y + redrawwin Y Y Y + wredrawln Y Y Y + +**man-end****************************************************************/ + +#include <string.h> + +int wnoutrefresh(WINDOW *win) +{ + int begy, begx; /* window's place on screen */ + int i, j; + + PDC_LOG(("wnoutrefresh() - called: win=%p\n", win)); + + if ( !win || (win->_flags & (_PAD|_SUBPAD)) ) + return ERR; + + begy = win->_begy; + begx = win->_begx; + + for (i = 0, j = begy; i < win->_maxy; i++, j++) + { + if (win->_firstch[i] != _NO_CHANGE) + { + chtype *src = win->_y[i]; + chtype *dest = curscr->_y[j] + begx; + + int first = win->_firstch[i]; /* first changed */ + int last = win->_lastch[i]; /* last changed */ + + /* ignore areas on the outside that are marked as changed, + but really aren't */ + + while (first <= last && src[first] == dest[first]) + first++; + + while (last >= first && src[last] == dest[last]) + last--; + + /* if any have really changed... */ + + if (first <= last) + { + memcpy(dest + first, src + first, + (last - first + 1) * sizeof(chtype)); + + first += begx; + last += begx; + + if (first < curscr->_firstch[j] || + curscr->_firstch[j] == _NO_CHANGE) + curscr->_firstch[j] = first; + + if (last > curscr->_lastch[j]) + curscr->_lastch[j] = last; + } + + win->_firstch[i] = _NO_CHANGE; /* updated now */ + } + + win->_lastch[i] = _NO_CHANGE; /* updated now */ + } + + if (win->_clear) + win->_clear = FALSE; + + if (!win->_leaveit) + { + curscr->_cury = win->_cury + begy; + curscr->_curx = win->_curx + begx; + } + + return OK; +} + +int doupdate(void) +{ + int y; + bool clearall; + + PDC_LOG(("doupdate() - called\n")); + + if (!SP || !curscr) + return ERR; + + if (isendwin()) /* coming back after endwin() called */ + { + reset_prog_mode(); + clearall = TRUE; + SP->alive = TRUE; /* so isendwin() result is correct */ + } + else + clearall = curscr->_clear; + + for (y = 0; y < SP->lines; y++) + { + PDC_LOG(("doupdate() - Transforming line %d of %d: %s\n", + y, SP->lines, (curscr->_firstch[y] != _NO_CHANGE) ? + "Yes" : "No")); + + if (clearall || curscr->_firstch[y] != _NO_CHANGE) + { + int first, last; + + chtype *src = curscr->_y[y]; + chtype *dest = SP->lastscr->_y[y]; + + if (clearall) + { + first = 0; + last = COLS - 1; + } + else + { + first = curscr->_firstch[y]; + last = curscr->_lastch[y]; + } + + while (first <= last) + { + int len = 0; + + /* build up a run of changed cells; if two runs are + separated by a single unchanged cell, ignore the + break */ + + if (clearall) + len = last - first + 1; + else + while (first + len <= last && + (src[first + len] != dest[first + len] || + (len && first + len < last && + src[first + len + 1] != dest[first + len + 1]) + ) + ) + len++; + + /* update the screen, and SP->lastscr */ + + if (len) + { + PDC_transform_line(y, first, len, src + first); + memcpy(dest + first, src + first, len * sizeof(chtype)); + first += len; + } + + /* skip over runs of unchanged cells */ + + while (first <= last && src[first] == dest[first]) + first++; + } + + curscr->_firstch[y] = _NO_CHANGE; + curscr->_lastch[y] = _NO_CHANGE; + } + } + + curscr->_clear = FALSE; + + if (SP->visibility) + PDC_gotoyx(curscr->_cury, curscr->_curx); + + SP->cursrow = curscr->_cury; + SP->curscol = curscr->_curx; + + PDC_doupdate(); + + return OK; +} + +int wrefresh(WINDOW *win) +{ + bool save_clear; + + PDC_LOG(("wrefresh() - called\n")); + + if ( !win || (win->_flags & (_PAD|_SUBPAD)) ) + return ERR; + + save_clear = win->_clear; + + if (win == curscr) + curscr->_clear = TRUE; + else + wnoutrefresh(win); + + if (save_clear && win->_maxy == SP->lines && win->_maxx == SP->cols) + curscr->_clear = TRUE; + + return doupdate(); +} + +int refresh(void) +{ + PDC_LOG(("refresh() - called\n")); + + return wrefresh(stdscr); +} + +int wredrawln(WINDOW *win, int start, int num) +{ + int i; + + PDC_LOG(("wredrawln() - called: win=%p start=%d num=%d\n", + win, start, num)); + + if (!win || start > win->_maxy || start + num > win->_maxy) + return ERR; + + for (i = start; i < start + num; i++) + { + win->_firstch[i] = 0; + win->_lastch[i] = win->_maxx - 1; + } + + return OK; +} + +int redrawwin(WINDOW *win) +{ + PDC_LOG(("redrawwin() - called: win=%p\n", win)); + + if (!win) + return ERR; + + return wredrawln(win, 0, win->_maxy); +} diff --git a/Utilities/cmpdcurses/pdcurses/scanw.c b/Utilities/cmpdcurses/pdcurses/scanw.c new file mode 100644 index 0000000..23a2d41 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/scanw.c @@ -0,0 +1,581 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +scanw +----- + +### Synopsis + + int scanw(const char *fmt, ...); + int wscanw(WINDOW *win, const char *fmt, ...); + int mvscanw(int y, int x, const char *fmt, ...); + int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...); + int vwscanw(WINDOW *win, const char *fmt, va_list varglist); + int vw_scanw(WINDOW *win, const char *fmt, va_list varglist); + +### Description + + These routines correspond to the standard C library's scanf() family. + Each gets a string from the window via wgetnstr(), and uses the + resulting line as input for the scan. + + The duplication between vwscanw() and vw_scanw() is for historic + reasons. In PDCurses, they're the same. + +### Return Value + + On successful completion, these functions return the number of items + successfully matched. Otherwise they return ERR. + +### Portability + X/Open ncurses NetBSD + scanw Y Y Y + wscanw Y Y Y + mvscanw Y Y Y + mvwscanw Y Y Y + vwscanw Y Y Y + vw_scanw Y Y Y + +**man-end****************************************************************/ + +#include <string.h> + +#ifndef HAVE_VSSCANF +# include <stdlib.h> +# include <ctype.h> +# include <limits.h> + +static int _pdc_vsscanf(const char *, const char *, va_list); + +# define vsscanf _pdc_vsscanf +#endif + +int vwscanw(WINDOW *win, const char *fmt, va_list varglist) +{ + char scanbuf[256]; + + PDC_LOG(("vwscanw() - called\n")); + + if (wgetnstr(win, scanbuf, 255) == ERR) + return ERR; + + return vsscanf(scanbuf, fmt, varglist); +} + +int scanw(const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("scanw() - called\n")); + + va_start(args, fmt); + retval = vwscanw(stdscr, fmt, args); + va_end(args); + + return retval; +} + +int wscanw(WINDOW *win, const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("wscanw() - called\n")); + + va_start(args, fmt); + retval = vwscanw(win, fmt, args); + va_end(args); + + return retval; +} + +int mvscanw(int y, int x, const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("mvscanw() - called\n")); + + if (move(y, x) == ERR) + return ERR; + + va_start(args, fmt); + retval = vwscanw(stdscr, fmt, args); + va_end(args); + + return retval; +} + +int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...) +{ + va_list args; + int retval; + + PDC_LOG(("mvscanw() - called\n")); + + if (wmove(win, y, x) == ERR) + return ERR; + + va_start(args, fmt); + retval = vwscanw(win, fmt, args); + va_end(args); + + return retval; +} + +int vw_scanw(WINDOW *win, const char *fmt, va_list varglist) +{ + PDC_LOG(("vw_scanw() - called\n")); + + return vwscanw(win, fmt, varglist); +} + +#ifndef HAVE_VSSCANF + +/* _pdc_vsscanf() - Internal routine to parse and format an input + buffer. It scans a series of input fields; each field is formatted + according to a supplied format string and the formatted input is + stored in the variable number of addresses passed. Returns the number + of input fields or EOF on error. + + Don't compile this unless required. Some compilers (at least Borland + C++ 3.0) have to link with math libraries due to the use of floats. + + Based on vsscanf.c and input.c from emx 0.8f library source, + Copyright (c) 1990-1992 by Eberhard Mattes, who has kindly agreed to + its inclusion in PDCurses. */ + +#define WHITE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n') + +#define NEXT(x) \ + do { \ + x = *buf++; \ + if (!x) \ + return (count ? count : EOF); \ + ++chars; \ + } while (0) + +#define UNGETC() \ + do { \ + --buf; --chars; \ + } while (0) + +static int _pdc_vsscanf(const char *buf, const char *fmt, va_list arg_ptr) +{ + int count, chars, c, width, radix, d, i; + int *int_ptr; + long *long_ptr; + short *short_ptr; + char *char_ptr; + unsigned char f; + char neg, assign, ok, size; + long n; + char map[256], end; + double dx, dd, *dbl_ptr; + float *flt_ptr; + int exp; + char eneg; + + count = 0; + chars = 0; + c = 0; + while ((f = *fmt) != 0) + { + if (WHITE(f)) + { + do + { + ++fmt; + f = *fmt; + } + while (WHITE(f)); + do + { + c = *buf++; + if (!c) + { + if (!f || count) + return count; + else + return EOF; + } else + ++chars; + } + while (WHITE(c)); + UNGETC(); + } else if (f != '%') + { + NEXT(c); + if (c != f) + return count; + ++fmt; + } else + { + assign = TRUE; + width = INT_MAX; + char_ptr = NULL; + ++fmt; + if (*fmt == '*') + { + assign = FALSE; + ++fmt; + } + if (isdigit(*fmt)) + { + width = 0; + while (isdigit(*fmt)) + width = width * 10 + (*fmt++ - '0'); + if (!width) + width = INT_MAX; + } + size = 0; + if (*fmt == 'h' || *fmt == 'l') + size = *fmt++; + f = *fmt; + switch (f) + { + case 'c': + if (width == INT_MAX) + width = 1; + if (assign) + char_ptr = va_arg(arg_ptr, char *); + while (width > 0) + { + --width; + NEXT(c); + if (assign) + { + *char_ptr++ = (char) c; + ++count; + } + } + break; + case '[': + memset(map, 0, 256); + end = 0; + ++fmt; + if (*fmt == '^') + { + ++fmt; + end = 1; + } + i = 0; + for (;;) + { + f = (unsigned char) *fmt; + switch (f) + { + case 0: + /* avoid skipping past 0 */ + --fmt; + NEXT(c); + goto string; + case ']': + if (i > 0) + { + NEXT(c); + goto string; + } + /* no break */ + default: + if (fmt[1] == '-' && fmt[2] + && f < (unsigned char)fmt[2]) + { + memset(map + f, 1, (unsigned char)fmt[2] - f); + fmt += 2; + } + else + map[f] = 1; + break; + } + ++fmt; + ++i; + } + case 's': + memset(map, 0, 256); + map[' '] = 1; + map['\n'] = 1; + map['\r'] = 1; + map['\t'] = 1; + end = 1; + do + { + NEXT(c); + } + while (WHITE(c)); + string: + if (assign) + char_ptr = va_arg(arg_ptr, char *); + while (width > 0 && map[(unsigned char) c] != end) + { + --width; + if (assign) + *char_ptr++ = (char) c; + c = *buf++; + if (!c) + break; + else + ++chars; + } + if (assign) + { + *char_ptr = 0; + ++count; + } + if (!c) + return count; + else + UNGETC(); + break; + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + neg = ok = FALSE; + dx = 0.0; + do + { + NEXT(c); + } + while (WHITE(c)); + if (c == '+') + { + NEXT(c); + --width; + } else if (c == '-') + { + neg = TRUE; + NEXT(c); + --width; + } + while (width > 0 && isdigit(c)) + { + --width; + dx = dx * 10.0 + (double) (c - '0'); + ok = TRUE; + c = *buf++; + if (!c) + break; + else + ++chars; + } + if (width > 0 && c == '.') + { + --width; + dd = 10.0; + NEXT(c); + while (width > 0 && isdigit(c)) + { + --width; + dx += (double) (c - '0') / dd; + dd *= 10.0; + ok = TRUE; + c = *buf++; + if (!c) + break; + else + ++chars; + } + } + if (!ok) + return count; + if (width > 0 && (c == 'e' || c == 'E')) + { + eneg = FALSE; + exp = 0; + NEXT(c); + --width; + if (width > 0 && c == '+') + { + NEXT(c); + --width; + } else if (width > 0 && c == '-') + { + eneg = TRUE; + NEXT(c); + --width; + } + if (!(width > 0 && isdigit(c))) + { + UNGETC(); + return count; + } + while (width > 0 && isdigit(c)) + { + --width; + exp = exp * 10 + (c - '0'); + c = *buf++; + if (!c) + break; + else + ++chars; + } + if (eneg) + exp = -exp; + while (exp > 0) + { + dx *= 10.0; + --exp; + } + while (exp < 0) + { + dx /= 10.0; + ++exp; + } + } + if (assign) + { + if (neg) + dx = -dx; + if (size == 'l') + { + dbl_ptr = va_arg(arg_ptr, double *); + *dbl_ptr = dx; + } + else + { + flt_ptr = va_arg(arg_ptr, float *); + *flt_ptr = (float)dx; + } + ++count; + } + if (!c) + return count; + else + UNGETC(); + break; + case 'i': + neg = FALSE; + radix = 10; + do + { + NEXT(c); + } + while (WHITE(c)); + if (!(width > 0 && c == '0')) + goto scan_complete_number; + NEXT(c); + --width; + if (width > 0 && (c == 'x' || c == 'X')) + { + NEXT(c); + radix = 16; + --width; + } + else if (width > 0 && (c >= '0' && c <= '7')) + radix = 8; + goto scan_unsigned_number; + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': + do + { + NEXT(c); + } + while (WHITE(c)); + switch (f) + { + case 'o': + radix = 8; + break; + case 'x': + case 'X': + radix = 16; + break; + default: + radix = 10; + break; + } + scan_complete_number: + neg = FALSE; + if (width > 0 && c == '+') + { + NEXT(c); + --width; + } + else if (width > 0 && c == '-' && radix == 10) + { + neg = TRUE; + NEXT(c); + --width; + } + scan_unsigned_number: + n = 0; + ok = FALSE; + while (width > 0) + { + --width; + if (isdigit(c)) + d = c - '0'; + else if (isupper(c)) + d = c - 'A' + 10; + else if (islower(c)) + d = c - 'a' + 10; + else + break; + if (d < 0 || d >= radix) + break; + ok = TRUE; + n = n * radix + d; + c = *buf++; + if (!c) + break; + else + ++chars; + } + if (!ok) + return count; + if (assign) + { + if (neg) + n = -n; + switch (size) + { + case 'h': + short_ptr = va_arg(arg_ptr, short *); + *short_ptr = (short) n; + break; + case 'l': + long_ptr = va_arg(arg_ptr, long *); + *long_ptr = (long) n; + break; + default: + int_ptr = va_arg(arg_ptr, int *); + *int_ptr = (int) n; + } + ++count; + } + if (!c) + return count; + else + UNGETC(); + break; + case 'n': + if (assign) + { + int_ptr = va_arg(arg_ptr, int *); + *int_ptr = chars; + ++count; + } + break; + default: + if (!f) /* % at end of string */ + return count; + NEXT(c); + if (c != f) + return count; + break; + } + ++fmt; + } + } + return count; +} +#endif /* HAVE_VSSCANF */ diff --git a/Utilities/cmpdcurses/pdcurses/scr_dump.c b/Utilities/cmpdcurses/pdcurses/scr_dump.c new file mode 100644 index 0000000..d9105bd --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/scr_dump.c @@ -0,0 +1,217 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +scr_dump +-------- + +### Synopsis + + int putwin(WINDOW *win, FILE *filep); + WINDOW *getwin(FILE *filep); + int scr_dump(const char *filename); + int scr_init(const char *filename); + int scr_restore(const char *filename); + int scr_set(const char *filename); + +### Description + + getwin() reads window-related data previously stored in a file by + putwin(). It then creates and initialises a new window using that + data. + + putwin() writes all data associated with a window into a file, using + an unspecified format. This information can be retrieved later using + getwin(). + + scr_dump() writes the current contents of the virtual screen to the + file named by filename in an unspecified format. + + scr_restore() function sets the virtual screen to the contents of the + file named by filename, which must have been written using + scr_dump(). The next refresh operation restores the screen to the way + it looked in the dump file. + + In PDCurses, scr_init() does nothing, and scr_set() is a synonym for + scr_restore(). Also, scr_dump() and scr_restore() save and load from + curscr. This differs from some other implementations, where + scr_init() works with curscr, and scr_restore() works with newscr; + but the effect should be the same. (PDCurses has no newscr.) + +### Return Value + + On successful completion, getwin() returns a pointer to the window it + created. Otherwise, it returns a null pointer. Other functions return + OK or ERR. + +### Portability + X/Open ncurses NetBSD + putwin Y Y Y + getwin Y Y Y + scr_dump Y Y - + scr_init Y Y - + scr_restore Y Y - + scr_set Y Y - + +**man-end****************************************************************/ + +#include <stdlib.h> +#include <string.h> + +#define DUMPVER 1 /* Should be updated whenever the WINDOW struct is + changed */ + +int putwin(WINDOW *win, FILE *filep) +{ + static const char *marker = "PDC"; + static const unsigned char version = DUMPVER; + + PDC_LOG(("putwin() - called\n")); + + /* write the marker and the WINDOW struct */ + + if (filep && fwrite(marker, strlen(marker), 1, filep) + && fwrite(&version, 1, 1, filep) + && fwrite(win, sizeof(WINDOW), 1, filep)) + { + int i; + + /* write each line */ + + for (i = 0; i < win->_maxy && win->_y[i]; i++) + if (!fwrite(win->_y[i], win->_maxx * sizeof(chtype), 1, filep)) + return ERR; + + return OK; + } + + return ERR; +} + +WINDOW *getwin(FILE *filep) +{ + WINDOW *win; + char marker[4]; + int i, nlines, ncols; + + PDC_LOG(("getwin() - called\n")); + + win = malloc(sizeof(WINDOW)); + if (!win) + return (WINDOW *)NULL; + + /* check for the marker, and load the WINDOW struct */ + + if (!filep || !fread(marker, 4, 1, filep) || strncmp(marker, "PDC", 3) + || marker[3] != DUMPVER || !fread(win, sizeof(WINDOW), 1, filep)) + { + free(win); + return (WINDOW *)NULL; + } + + nlines = win->_maxy; + ncols = win->_maxx; + + /* allocate the line pointer array */ + + win->_y = malloc(nlines * sizeof(chtype *)); + if (!win->_y) + { + free(win); + return (WINDOW *)NULL; + } + + /* allocate the minchng and maxchng arrays */ + + win->_firstch = malloc(nlines * sizeof(int)); + if (!win->_firstch) + { + free(win->_y); + free(win); + return (WINDOW *)NULL; + } + + win->_lastch = malloc(nlines * sizeof(int)); + if (!win->_lastch) + { + free(win->_firstch); + free(win->_y); + free(win); + return (WINDOW *)NULL; + } + + /* allocate the lines */ + + win = PDC_makelines(win); + if (!win) + return (WINDOW *)NULL; + + /* read them */ + + for (i = 0; i < nlines; i++) + { + if (!fread(win->_y[i], ncols * sizeof(chtype), 1, filep)) + { + delwin(win); + return (WINDOW *)NULL; + } + } + + touchwin(win); + + return win; +} + +int scr_dump(const char *filename) +{ + FILE *filep; + + PDC_LOG(("scr_dump() - called: filename %s\n", filename)); + + if (filename && (filep = fopen(filename, "wb")) != NULL) + { + int result = putwin(curscr, filep); + fclose(filep); + return result; + } + + return ERR; +} + +int scr_init(const char *filename) +{ + PDC_LOG(("scr_init() - called: filename %s\n", filename)); + + return OK; +} + +int scr_restore(const char *filename) +{ + FILE *filep; + + PDC_LOG(("scr_restore() - called: filename %s\n", filename)); + + if (filename && (filep = fopen(filename, "rb")) != NULL) + { + WINDOW *replacement = getwin(filep); + fclose(filep); + + if (replacement) + { + int result = overwrite(replacement, curscr); + delwin(replacement); + return result; + } + } + + return ERR; +} + +int scr_set(const char *filename) +{ + PDC_LOG(("scr_set() - called: filename %s\n", filename)); + + return scr_restore(filename); +} diff --git a/Utilities/cmpdcurses/pdcurses/scroll.c b/Utilities/cmpdcurses/pdcurses/scroll.c new file mode 100644 index 0000000..ffe8d0d --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/scroll.c @@ -0,0 +1,101 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +scroll +------ + +### Synopsis + + int scroll(WINDOW *win); + int scrl(int n); + int wscrl(WINDOW *win, int n); + +### Description + + scroll() causes the window to scroll up one line. This involves + moving the lines in the window data strcture. + + With a positive n, scrl() and wscrl() scroll the window up n lines + (line i + n becomes i); otherwise they scroll the window down n + lines. + + For these functions to work, scrolling must be enabled via + scrollok(). Note also that scrolling is not allowed if the supplied + window is a pad. + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + scroll Y Y Y + scrl Y Y Y + wscrl Y Y Y + +**man-end****************************************************************/ + +int wscrl(WINDOW *win, int n) +{ + int i, l, dir, start, end; + chtype blank, *temp; + + /* Check if window scrolls. Valid for window AND pad */ + + if (!win || !win->_scroll || !n) + return ERR; + + blank = win->_bkgd; + + if (n > 0) + { + start = win->_tmarg; + end = win->_bmarg; + dir = 1; + } + else + { + start = win->_bmarg; + end = win->_tmarg; + dir = -1; + } + + for (l = 0; l < (n * dir); l++) + { + temp = win->_y[start]; + + /* re-arrange line pointers */ + + for (i = start; i != end; i += dir) + win->_y[i] = win->_y[i + dir]; + + win->_y[end] = temp; + + /* make a blank line */ + + for (i = 0; i < win->_maxx; i++) + *temp++ = blank; + } + + touchline(win, win->_tmarg, win->_bmarg - win->_tmarg + 1); + + PDC_sync(win); + return OK; +} + +int scrl(int n) +{ + PDC_LOG(("scrl() - called\n")); + + return wscrl(stdscr, n); +} + +int scroll(WINDOW *win) +{ + PDC_LOG(("scroll() - called\n")); + + return wscrl(win, 1); +} diff --git a/Utilities/cmpdcurses/pdcurses/slk.c b/Utilities/cmpdcurses/pdcurses/slk.c new file mode 100644 index 0000000..4fdfee1 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/slk.c @@ -0,0 +1,671 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +slk +--- + +### Synopsis + + int slk_init(int fmt); + int slk_set(int labnum, const char *label, int justify); + int slk_refresh(void); + int slk_noutrefresh(void); + char *slk_label(int labnum); + int slk_clear(void); + int slk_restore(void); + int slk_touch(void); + int slk_attron(const chtype attrs); + int slk_attr_on(const attr_t attrs, void *opts); + int slk_attrset(const chtype attrs); + int slk_attr_set(const attr_t attrs, short color_pair, void *opts); + int slk_attroff(const chtype attrs); + int slk_attr_off(const attr_t attrs, void *opts); + int slk_color(short color_pair); + + int slk_wset(int labnum, const wchar_t *label, int justify); + + int PDC_mouse_in_slk(int y, int x); + void PDC_slk_free(void); + void PDC_slk_initialize(void); + + wchar_t *slk_wlabel(int labnum) + +### Description + + These functions manipulate a window that contain Soft Label Keys + (SLK). To use the SLK functions, a call to slk_init() must be made + BEFORE initscr() or newterm(). slk_init() removes 1 or 2 lines from + the useable screen, depending on the format selected. + + The line(s) removed from the screen are used as a separate window, in + which SLKs are displayed. + + slk_init() requires a single parameter which describes the format of + the SLKs as follows: + + 0 3-2-3 format + 1 4-4 format + 2 4-4-4 format (ncurses extension) + 3 4-4-4 format with index line (ncurses extension) + 2 lines used + 55 5-5 format (pdcurses format) + + slk_refresh(), slk_noutrefresh() and slk_touch() are analogous to + refresh(), noutrefresh() and touch(). + +### Return Value + + All functions return OK on success and ERR on error. + +### Portability + X/Open ncurses NetBSD + slk_init Y Y Y + slk_set Y Y Y + slk_refresh Y Y Y + slk_noutrefresh Y Y Y + slk_label Y Y Y + slk_clear Y Y Y + slk_restore Y Y Y + slk_touch Y Y Y + slk_attron Y Y Y + slk_attrset Y Y Y + slk_attroff Y Y Y + slk_attr_on Y Y Y + slk_attr_set Y Y Y + slk_attr_off Y Y Y + slk_wset Y Y Y + PDC_mouse_in_slk - - - + PDC_slk_free - - - + PDC_slk_initialize - - - + slk_wlabel - - - + +**man-end****************************************************************/ + +#include <stdlib.h> + +enum { LABEL_NORMAL = 8, LABEL_EXTENDED = 10, LABEL_NCURSES_EXTENDED = 12 }; + +static int label_length = 0; +static int labels = 0; +static int label_fmt = 0; +static int label_line = 0; +static bool hidden = FALSE; + +static struct SLK { + chtype label[32]; + int len; + int format; + int start_col; +} *slk = (struct SLK *)NULL; + +/* slk_init() is the slk initialization routine. + This must be called before initscr(). + + label_fmt = 0, 1 or 55. + 0 = 3-2-3 format + 1 = 4 - 4 format + 2 = 4-4-4 format (ncurses extension for PC 12 function keys) + 3 = 4-4-4 format (ncurses extension for PC 12 function keys - + with index line) + 55 = 5 - 5 format (extended for PC, 10 function keys) */ + +int slk_init(int fmt) +{ + PDC_LOG(("slk_init() - called\n")); + + if (SP) + return ERR; + + switch (fmt) + { + case 0: /* 3 - 2 - 3 */ + labels = LABEL_NORMAL; + break; + + case 1: /* 4 - 4 */ + labels = LABEL_NORMAL; + break; + + case 2: /* 4 4 4 */ + labels = LABEL_NCURSES_EXTENDED; + break; + + case 3: /* 4 4 4 with index */ + labels = LABEL_NCURSES_EXTENDED; + break; + + case 55: /* 5 - 5 */ + labels = LABEL_EXTENDED; + break; + + default: + return ERR; + } + + label_fmt = fmt; + + slk = calloc(labels, sizeof(struct SLK)); + + if (!slk) + labels = 0; + + return slk ? OK : ERR; +} + +/* draw a single button */ + +static void _drawone(int num) +{ + int i, col, slen; + + if (hidden) + return; + + slen = slk[num].len; + + switch (slk[num].format) + { + case 0: /* LEFT */ + col = 0; + break; + + case 1: /* CENTER */ + col = (label_length - slen) / 2; + + if (col + slen > label_length) + --col; + break; + + default: /* RIGHT */ + col = label_length - slen; + } + + wmove(SP->slk_winptr, label_line, slk[num].start_col); + + for (i = 0; i < label_length; ++i) + waddch(SP->slk_winptr, (i >= col && i < (col + slen)) ? + slk[num].label[i - col] : ' '); +} + +/* redraw each button */ + +static void _redraw(void) +{ + int i; + + for (i = 0; i < labels; ++i) + _drawone(i); +} + +/* slk_set() Used to set a slk label to a string. + + labnum = 1 - 8 (or 10) (number of the label) + label = string (8 or 7 bytes total), or NULL + justify = 0 : left, 1 : center, 2 : right */ + +int slk_set(int labnum, const char *label, int justify) +{ +#ifdef PDC_WIDE + wchar_t wlabel[32]; + + PDC_mbstowcs(wlabel, label, 31); + return slk_wset(labnum, wlabel, justify); +#else + PDC_LOG(("slk_set() - called\n")); + + if (labnum < 1 || labnum > labels || justify < 0 || justify > 2) + return ERR; + + labnum--; + + if (!label || !(*label)) + { + /* Clear the label */ + + *slk[labnum].label = 0; + slk[labnum].format = 0; + slk[labnum].len = 0; + } + else + { + int i, j = 0; + + /* Skip leading spaces */ + + while (label[j] == ' ') + j++; + + /* Copy it */ + + for (i = 0; i < label_length; i++) + { + chtype ch = label[i + j]; + + slk[labnum].label[i] = ch; + + if (!ch) + break; + } + + /* Drop trailing spaces */ + + while ((i + j) && (label[i + j - 1] == ' ')) + i--; + + slk[labnum].label[i] = 0; + slk[labnum].format = justify; + slk[labnum].len = i; + } + + _drawone(labnum); + + return OK; +#endif +} + +int slk_refresh(void) +{ + PDC_LOG(("slk_refresh() - called\n")); + + return (slk_noutrefresh() == ERR) ? ERR : doupdate(); +} + +int slk_noutrefresh(void) +{ + PDC_LOG(("slk_noutrefresh() - called\n")); + + if (!SP) + return ERR; + + return wnoutrefresh(SP->slk_winptr); +} + +char *slk_label(int labnum) +{ + static char temp[33]; +#ifdef PDC_WIDE + wchar_t *wtemp = slk_wlabel(labnum); + + PDC_wcstombs(temp, wtemp, 32); +#else + chtype *p; + int i; + + PDC_LOG(("slk_label() - called\n")); + + if (labnum < 1 || labnum > labels) + return (char *)0; + + for (i = 0, p = slk[labnum - 1].label; *p; i++) + temp[i] = *p++; + + temp[i] = '\0'; +#endif + return temp; +} + +int slk_clear(void) +{ + PDC_LOG(("slk_clear() - called\n")); + + if (!SP) + return ERR; + + hidden = TRUE; + werase(SP->slk_winptr); + return wrefresh(SP->slk_winptr); +} + +int slk_restore(void) +{ + PDC_LOG(("slk_restore() - called\n")); + + if (!SP) + return ERR; + + hidden = FALSE; + _redraw(); + return wrefresh(SP->slk_winptr); +} + +int slk_touch(void) +{ + PDC_LOG(("slk_touch() - called\n")); + + if (!SP) + return ERR; + + return touchwin(SP->slk_winptr); +} + +int slk_attron(const chtype attrs) +{ + int rc; + + PDC_LOG(("slk_attron() - called\n")); + + if (!SP) + return ERR; + + rc = wattron(SP->slk_winptr, attrs); + _redraw(); + + return rc; +} + +int slk_attr_on(const attr_t attrs, void *opts) +{ + PDC_LOG(("slk_attr_on() - called\n")); + + return slk_attron(attrs); +} + +int slk_attroff(const chtype attrs) +{ + int rc; + + PDC_LOG(("slk_attroff() - called\n")); + + if (!SP) + return ERR; + + rc = wattroff(SP->slk_winptr, attrs); + _redraw(); + + return rc; +} + +int slk_attr_off(const attr_t attrs, void *opts) +{ + PDC_LOG(("slk_attr_off() - called\n")); + + return slk_attroff(attrs); +} + +int slk_attrset(const chtype attrs) +{ + int rc; + + PDC_LOG(("slk_attrset() - called\n")); + + if (!SP) + return ERR; + + rc = wattrset(SP->slk_winptr, attrs); + _redraw(); + + return rc; +} + +int slk_color(short color_pair) +{ + int rc; + + PDC_LOG(("slk_color() - called\n")); + + if (!SP) + return ERR; + + rc = wcolor_set(SP->slk_winptr, color_pair, NULL); + _redraw(); + + return rc; +} + +int slk_attr_set(const attr_t attrs, short color_pair, void *opts) +{ + PDC_LOG(("slk_attr_set() - called\n")); + + return slk_attrset(attrs | COLOR_PAIR(color_pair)); +} + +static void _slk_calc(void) +{ + int i, center, col = 0; + label_length = COLS / labels; + + if (label_length > 31) + label_length = 31; + + switch (label_fmt) + { + case 0: /* 3 - 2 - 3 F-Key layout */ + + --label_length; + + slk[0].start_col = col; + slk[1].start_col = (col += label_length); + slk[2].start_col = (col += label_length); + + center = COLS / 2; + + slk[3].start_col = center - label_length + 1; + slk[4].start_col = center + 1; + + col = COLS - (label_length * 3) + 1; + + slk[5].start_col = col; + slk[6].start_col = (col += label_length); + slk[7].start_col = (col += label_length); + break; + + case 1: /* 4 - 4 F-Key layout */ + + for (i = 0; i < 8; i++) + { + slk[i].start_col = col; + col += label_length; + + if (i == 3) + col = COLS - (label_length * 4) + 1; + } + + break; + + case 2: /* 4 4 4 F-Key layout */ + case 3: /* 4 4 4 F-Key layout with index */ + + for (i = 0; i < 4; i++) + { + slk[i].start_col = col; + col += label_length; + } + + center = COLS / 2; + + slk[4].start_col = center - (label_length * 2) + 1; + slk[5].start_col = center - label_length + 1; + slk[6].start_col = center + 1; + slk[7].start_col = center + label_length + 1; + + col = COLS - (label_length * 4) + 1; + + for (i = 8; i < 12; i++) + { + slk[i].start_col = col; + col += label_length; + } + + break; + + default: /* 5 - 5 F-Key layout */ + + for (i = 0; i < 10; i++) + { + slk[i].start_col = col; + col += label_length; + + if (i == 4) + col = COLS - (label_length * 5) + 1; + } + } + + --label_length; + + /* make sure labels are all in window */ + + _redraw(); +} + +void PDC_slk_initialize(void) +{ + if (slk) + { + if (label_fmt == 3) + { + SP->slklines = 2; + label_line = 1; + } + else + SP->slklines = 1; + + if (!SP->slk_winptr) + { + SP->slk_winptr = newwin(SP->slklines, COLS, + LINES - SP->slklines, 0); + if (!SP->slk_winptr) + return; + + wattrset(SP->slk_winptr, A_REVERSE); + } + + _slk_calc(); + + /* if we have an index line, display it now */ + + if (label_fmt == 3) + { + chtype save_attr; + int i; + + save_attr = SP->slk_winptr->_attrs; + wattrset(SP->slk_winptr, A_NORMAL); + wmove(SP->slk_winptr, 0, 0); + whline(SP->slk_winptr, 0, COLS); + + for (i = 0; i < labels; i++) + mvwprintw(SP->slk_winptr, 0, slk[i].start_col, "F%d", i + 1); + + SP->slk_winptr->_attrs = save_attr; + } + + touchwin(SP->slk_winptr); + } +} + +void PDC_slk_free(void) +{ + if (slk) + { + if (SP->slk_winptr) + { + delwin(SP->slk_winptr); + SP->slk_winptr = (WINDOW *)NULL; + } + + free(slk); + slk = (struct SLK *)NULL; + + label_length = 0; + labels = 0; + label_fmt = 0; + label_line = 0; + hidden = FALSE; + } +} + +int PDC_mouse_in_slk(int y, int x) +{ + int i; + + PDC_LOG(("PDC_mouse_in_slk() - called: y->%d x->%d\n", y, x)); + + /* If the line on which the mouse was clicked is NOT the last line + of the screen, we are not interested in it. */ + + if (!slk || !SP->slk_winptr || (y != SP->slk_winptr->_begy + label_line)) + return 0; + + for (i = 0; i < labels; i++) + if (x >= slk[i].start_col && x < (slk[i].start_col + label_length)) + return i + 1; + + return 0; +} + +#ifdef PDC_WIDE +int slk_wset(int labnum, const wchar_t *label, int justify) +{ + PDC_LOG(("slk_wset() - called\n")); + + if (labnum < 1 || labnum > labels || justify < 0 || justify > 2) + return ERR; + + labnum--; + + if (!label || !(*label)) + { + /* Clear the label */ + + *slk[labnum].label = 0; + slk[labnum].format = 0; + slk[labnum].len = 0; + } + else + { + int i, j = 0; + + /* Skip leading spaces */ + + while (label[j] == L' ') + j++; + + /* Copy it */ + + for (i = 0; i < label_length; i++) + { + chtype ch = label[i + j]; + + slk[labnum].label[i] = ch; + + if (!ch) + break; + } + + /* Drop trailing spaces */ + + while ((i + j) && (label[i + j - 1] == L' ')) + i--; + + slk[labnum].label[i] = 0; + slk[labnum].format = justify; + slk[labnum].len = i; + } + + _drawone(labnum); + + return OK; +} + +wchar_t *slk_wlabel(int labnum) +{ + static wchar_t temp[33]; + chtype *p; + int i; + + PDC_LOG(("slk_wlabel() - called\n")); + + if (labnum < 1 || labnum > labels) + return (wchar_t *)0; + + for (i = 0, p = slk[labnum - 1].label; *p; i++) + temp[i] = *p++; + + temp[i] = '\0'; + + return temp; +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/termattr.c b/Utilities/cmpdcurses/pdcurses/termattr.c new file mode 100644 index 0000000..afb143d --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/termattr.c @@ -0,0 +1,172 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +termattr +-------- + +### Synopsis + + int baudrate(void); + char erasechar(void); + bool has_ic(void); + bool has_il(void); + char killchar(void); + char *longname(void); + chtype termattrs(void); + attr_t term_attrs(void); + char *termname(void); + + int erasewchar(wchar_t *ch); + int killwchar(wchar_t *ch); + + char wordchar(void); + +### Description + + baudrate() is supposed to return the output speed of the terminal. In + PDCurses, it simply returns INT_MAX. + + has_ic and has_il() return TRUE. These functions have meaning in some + other implementations of curses. + + erasechar() and killchar() return ^H and ^U, respectively -- the + ERASE and KILL characters. In other curses implementations, these may + vary by terminal type. erasewchar() and killwchar() are the wide- + character versions; they take a pointer to a location in which to + store the character, and return OK or ERR. + + longname() returns a pointer to a static area containing a verbose + description of the current terminal. The maximum length of the string + is 128 characters. It is defined only after the call to initscr() or + newterm(). + + termname() returns a pointer to a static area containing a short + description of the current terminal (14 characters). + + termattrs() returns a logical OR of all video attributes supported by + the terminal. + + wordchar() is a PDCurses extension of the concept behind the + functions erasechar() and killchar(), returning the "delete word" + character, ^W. + +### Portability + X/Open ncurses NetBSD + baudrate Y Y Y + erasechar Y Y Y + has_ic Y Y Y + has_il Y Y Y + killchar Y Y Y + longname Y Y Y + termattrs Y Y Y + termname Y Y Y + erasewchar Y Y Y + killwchar Y Y Y + term_attrs Y Y Y + wordchar - - - + +**man-end****************************************************************/ + +#include <string.h> +#include <limits.h> + +int baudrate(void) +{ + PDC_LOG(("baudrate() - called\n")); + + return INT_MAX; +} + +char erasechar(void) +{ + PDC_LOG(("erasechar() - called\n")); + + return _ECHAR; /* character delete char (^H) */ +} + +bool has_ic(void) +{ + PDC_LOG(("has_ic() - called\n")); + + return TRUE; +} + +bool has_il(void) +{ + PDC_LOG(("has_il() - called\n")); + + return TRUE; +} + +char killchar(void) +{ + PDC_LOG(("killchar() - called\n")); + + return _DLCHAR; /* line delete char (^U) */ +} + +char *longname(void) +{ + PDC_LOG(("longname() - called\n")); + + return ttytype + 9; /* skip "pdcurses|" */ +} + +chtype termattrs(void) +{ + PDC_LOG(("termattrs() - called\n")); + + return SP ? SP->termattrs : (chtype)0; +} + +attr_t term_attrs(void) +{ + PDC_LOG(("term_attrs() - called\n")); + + return SP ? SP->termattrs : (attr_t)0; +} + +char *termname(void) +{ + static char _termname[14] = "pdcurses"; + + PDC_LOG(("termname() - called\n")); + + return _termname; +} + +char wordchar(void) +{ + PDC_LOG(("wordchar() - called\n")); + + return _DWCHAR; /* word delete char */ +} + +#ifdef PDC_WIDE +int erasewchar(wchar_t *ch) +{ + PDC_LOG(("erasewchar() - called\n")); + + if (!ch) + return ERR; + + *ch = (wchar_t)_ECHAR; + + return OK; +} + +int killwchar(wchar_t *ch) +{ + PDC_LOG(("killwchar() - called\n")); + + if (!ch) + return ERR; + + *ch = (wchar_t)_DLCHAR; + + return OK; +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/touch.c b/Utilities/cmpdcurses/pdcurses/touch.c new file mode 100644 index 0000000..e1b7c60 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/touch.c @@ -0,0 +1,199 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +touch +----- + +### Synopsis + + int touchwin(WINDOW *win); + int touchline(WINDOW *win, int start, int count); + int untouchwin(WINDOW *win); + int wtouchln(WINDOW *win, int y, int n, int changed); + bool is_linetouched(WINDOW *win, int line); + bool is_wintouched(WINDOW *win); + + int touchoverlap(const WINDOW *win1, WINDOW *win2); + +### Description + + touchwin() and touchline() throw away all information about which + parts of the window have been touched, pretending that the entire + window has been drawn on. This is sometimes necessary when using + overlapping windows, since a change to one window will affect the + other window, but the records of which lines have been changed in the + other window will not reflect the change. + + untouchwin() marks all lines in the window as unchanged since the + last call to wrefresh(). + + wtouchln() makes n lines in the window, starting at line y, look as + if they have (changed == 1) or have not (changed == 0) been changed + since the last call to wrefresh(). + + is_linetouched() returns TRUE if the specified line in the specified + window has been changed since the last call to wrefresh(). + + is_wintouched() returns TRUE if the specified window has been changed + since the last call to wrefresh(). + + touchoverlap(win1, win2) marks the portion of win2 which overlaps + with win1 as modified. + +### Return Value + + All functions return OK on success and ERR on error except + is_wintouched() and is_linetouched(). + +### Portability + X/Open ncurses NetBSD + touchwin Y Y Y + touchline Y Y Y + untouchwin Y Y Y + wtouchln Y Y Y + is_linetouched Y Y Y + is_wintouched Y Y Y + touchoverlap - - Y + +**man-end****************************************************************/ + +int touchwin(WINDOW *win) +{ + int i; + + PDC_LOG(("touchwin() - called: Win=%x\n", win)); + + if (!win) + return ERR; + + for (i = 0; i < win->_maxy; i++) + { + win->_firstch[i] = 0; + win->_lastch[i] = win->_maxx - 1; + } + + return OK; +} + +int touchline(WINDOW *win, int start, int count) +{ + int i; + + PDC_LOG(("touchline() - called: win=%p start %d count %d\n", + win, start, count)); + + if (!win || start > win->_maxy || start + count > win->_maxy) + return ERR; + + for (i = start; i < start + count; i++) + { + win->_firstch[i] = 0; + win->_lastch[i] = win->_maxx - 1; + } + + return OK; +} + +int untouchwin(WINDOW *win) +{ + int i; + + PDC_LOG(("untouchwin() - called: win=%p", win)); + + if (!win) + return ERR; + + for (i = 0; i < win->_maxy; i++) + { + win->_firstch[i] = _NO_CHANGE; + win->_lastch[i] = _NO_CHANGE; + } + + return OK; +} + +int wtouchln(WINDOW *win, int y, int n, int changed) +{ + int i; + + PDC_LOG(("wtouchln() - called: win=%p y=%d n=%d changed=%d\n", + win, y, n, changed)); + + if (!win || y > win->_maxy || y + n > win->_maxy) + return ERR; + + for (i = y; i < y + n; i++) + { + if (changed) + { + win->_firstch[i] = 0; + win->_lastch[i] = win->_maxx - 1; + } + else + { + win->_firstch[i] = _NO_CHANGE; + win->_lastch[i] = _NO_CHANGE; + } + } + + return OK; +} + +bool is_linetouched(WINDOW *win, int line) +{ + PDC_LOG(("is_linetouched() - called: win=%p line=%d\n", win, line)); + + if (!win || line > win->_maxy || line < 0) + return FALSE; + + return (win->_firstch[line] != _NO_CHANGE) ? TRUE : FALSE; +} + +bool is_wintouched(WINDOW *win) +{ + int i; + + PDC_LOG(("is_wintouched() - called: win=%p\n", win)); + + if (win) + for (i = 0; i < win->_maxy; i++) + if (win->_firstch[i] != _NO_CHANGE) + return TRUE; + + return FALSE; +} + +int touchoverlap(const WINDOW *win1, WINDOW *win2) +{ + int y, endy, endx, starty, startx; + + PDC_LOG(("touchoverlap() - called: win1=%p win2=%p\n", win1, win2)); + + if (!win1 || !win2) + return ERR; + + starty = max(win1->_begy, win2->_begy); + startx = max(win1->_begx, win2->_begx); + endy = min(win1->_maxy + win1->_begy, win2->_maxy + win2->_begy); + endx = min(win1->_maxx + win1->_begx, win2->_maxx + win2->_begx); + + if (starty >= endy || startx >= endx) + return OK; + + starty -= win2->_begy; + startx -= win2->_begx; + endy -= win2->_begy; + endx -= win2->_begx; + endx -= 1; + + for (y = starty; y < endy; y++) + { + win2->_firstch[y] = startx; + win2->_lastch[y] = endx; + } + + return OK; +} diff --git a/Utilities/cmpdcurses/pdcurses/util.c b/Utilities/cmpdcurses/pdcurses/util.c new file mode 100644 index 0000000..2d29306 --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/util.c @@ -0,0 +1,308 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +util +---- + +### Synopsis + + char *unctrl(chtype c); + void filter(void); + void use_env(bool x); + int delay_output(int ms); + + int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs, + short *color_pair, void *opts); + int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs, + short color_pair, const void *opts); + wchar_t *wunctrl(cchar_t *wc); + + int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n); + size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n); + size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n); + +### Description + + unctrl() expands the text portion of the chtype c into a printable + string. Control characters are changed to the "^X" notation; others + are passed through. wunctrl() is the wide-character version of the + function. + + filter() and use_env() are no-ops in PDCurses. + + delay_output() inserts an ms millisecond pause in output. + + getcchar() works in two modes: When wch is not NULL, it reads the + cchar_t pointed to by wcval and stores the attributes in attrs, the + color pair in color_pair, and the text in the wide-character string + wch. When wch is NULL, getcchar() merely returns the number of wide + characters in wcval. In either mode, the opts argument is unused. + + setcchar constructs a cchar_t at wcval from the wide-character text + at wch, the attributes in attr and the color pair in color_pair. The + opts argument is unused. + + Currently, the length returned by getcchar() is always 1 or 0. + Similarly, setcchar() will only take the first wide character from + wch, and ignore any others that it "should" take (i.e., combining + characters). Nor will it correctly handle any character outside the + basic multilingual plane (UCS-2). + +### Return Value + + wunctrl() returns NULL on failure. delay_output() always returns OK. + + getcchar() returns the number of wide characters wcval points to when + wch is NULL; when it's not, getcchar() returns OK or ERR. + + setcchar() returns OK or ERR. + +### Portability + X/Open ncurses NetBSD + unctrl Y Y Y + filter Y Y Y + use_env Y Y Y + delay_output Y Y Y + getcchar Y Y Y + setcchar Y Y Y + wunctrl Y Y Y + PDC_mbtowc - - - + PDC_mbstowcs - - - + PDC_wcstombs - - - + +**man-end****************************************************************/ + +#include <stdlib.h> +#include <string.h> + +char *unctrl(chtype c) +{ + static char strbuf[3] = {0, 0, 0}; + + chtype ic; + + PDC_LOG(("unctrl() - called\n")); + + ic = c & A_CHARTEXT; + + if (ic >= 0x20 && ic != 0x7f) /* normal characters */ + { + strbuf[0] = (char)ic; + strbuf[1] = '\0'; + return strbuf; + } + + strbuf[0] = '^'; /* '^' prefix */ + + if (ic == 0x7f) /* 0x7f == DEL */ + strbuf[1] = '?'; + else /* other control */ + strbuf[1] = (char)(ic + '@'); + + return strbuf; +} + +void filter(void) +{ + PDC_LOG(("filter() - called\n")); +} + +void use_env(bool x) +{ + PDC_LOG(("use_env() - called: x %d\n", x)); +} + +int delay_output(int ms) +{ + PDC_LOG(("delay_output() - called: ms %d\n", ms)); + + return napms(ms); +} + +#ifdef PDC_WIDE +int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs, + short *color_pair, void *opts) +{ + if (!wcval) + return ERR; + + if (wch) + { + if (!attrs || !color_pair) + return ERR; + + *wch = (*wcval & A_CHARTEXT); + *attrs = (*wcval & (A_ATTRIBUTES & ~A_COLOR)); + *color_pair = PAIR_NUMBER(*wcval & A_COLOR); + + if (*wch) + *++wch = L'\0'; + + return OK; + } + else + return ((*wcval & A_CHARTEXT) != L'\0'); +} + +int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs, + short color_pair, const void *opts) +{ + if (!wcval || !wch) + return ERR; + + *wcval = *wch | attrs | COLOR_PAIR(color_pair); + + return OK; +} + +wchar_t *wunctrl(cchar_t *wc) +{ + static wchar_t strbuf[3] = {0, 0, 0}; + + cchar_t ic; + + PDC_LOG(("wunctrl() - called\n")); + + if (!wc) + return NULL; + + ic = *wc & A_CHARTEXT; + + if (ic >= 0x20 && ic != 0x7f) /* normal characters */ + { + strbuf[0] = (wchar_t)ic; + strbuf[1] = L'\0'; + return strbuf; + } + + strbuf[0] = '^'; /* '^' prefix */ + + if (ic == 0x7f) /* 0x7f == DEL */ + strbuf[1] = '?'; + else /* other control */ + strbuf[1] = (wchar_t)(ic + '@'); + + return strbuf; +} + +int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n) +{ +# ifdef PDC_FORCE_UTF8 + wchar_t key; + int i = -1; + const unsigned char *string; + + if (!s || (n < 1)) + return -1; + + if (!*s) + return 0; + + string = (const unsigned char *)s; + + key = string[0]; + + /* Simplistic UTF-8 decoder -- only does the BMP, minimal validation */ + + if (key & 0x80) + { + if ((key & 0xe0) == 0xc0) + { + if (1 < n) + { + key = ((key & 0x1f) << 6) | (string[1] & 0x3f); + i = 2; + } + } + else if ((key & 0xe0) == 0xe0) + { + if (2 < n) + { + key = ((key & 0x0f) << 12) | ((string[1] & 0x3f) << 6) | + (string[2] & 0x3f); + i = 3; + } + } + } + else + i = 1; + + if (i) + *pwc = key; + + return i; +# else + return mbtowc(pwc, s, n); +# endif +} + +size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n) +{ +# ifdef PDC_FORCE_UTF8 + size_t i = 0, len; + + if (!src || !dest) + return 0; + + len = strlen(src); + + while (*src && i < n) + { + int retval = PDC_mbtowc(dest + i, src, len); + + if (retval < 1) + return -1; + + src += retval; + len -= retval; + i++; + } +# else + size_t i = mbstowcs(dest, src, n); +# endif + dest[i] = 0; + return i; +} + +size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n) +{ +# ifdef PDC_FORCE_UTF8 + size_t i = 0; + + if (!src || !dest) + return 0; + + while (*src && i < n) + { + chtype code = *src++; + + if (code < 0x80) + { + dest[i] = code; + i++; + } + else + if (code < 0x800) + { + dest[i] = ((code & 0x07c0) >> 6) | 0xc0; + dest[i + 1] = (code & 0x003f) | 0x80; + i += 2; + } + else + { + dest[i] = ((code & 0xf000) >> 12) | 0xe0; + dest[i + 1] = ((code & 0x0fc0) >> 6) | 0x80; + dest[i + 2] = (code & 0x003f) | 0x80; + i += 3; + } + } +# else + size_t i = wcstombs(dest, src, n); +# endif + dest[i] = '\0'; + return i; +} +#endif diff --git a/Utilities/cmpdcurses/pdcurses/window.c b/Utilities/cmpdcurses/pdcurses/window.c new file mode 100644 index 0000000..2eb294e --- /dev/null +++ b/Utilities/cmpdcurses/pdcurses/window.c @@ -0,0 +1,582 @@ +/* PDCurses */ + +#include <curspriv.h> + +/*man-start************************************************************** + +window +------ + +### Synopsis + + WINDOW *newwin(int nlines, int ncols, int begy, int begx); + WINDOW *derwin(WINDOW* orig, int nlines, int ncols, + int begy, int begx); + WINDOW *subwin(WINDOW* orig, int nlines, int ncols, + int begy, int begx); + WINDOW *dupwin(WINDOW *win); + int delwin(WINDOW *win); + int mvwin(WINDOW *win, int y, int x); + int mvderwin(WINDOW *win, int pary, int parx); + int syncok(WINDOW *win, bool bf); + void wsyncup(WINDOW *win); + void wcursyncup(WINDOW *win); + void wsyncdown(WINDOW *win); + + WINDOW *resize_window(WINDOW *win, int nlines, int ncols); + int wresize(WINDOW *win, int nlines, int ncols); + WINDOW *PDC_makelines(WINDOW *win); + WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx); + void PDC_sync(WINDOW *win); + +### Description + + newwin() creates a new window with the given number of lines, nlines + and columns, ncols. The upper left corner of the window is at line + begy, column begx. If nlines is zero, it defaults to LINES - begy; + ncols to COLS - begx. Create a new full-screen window by calling + newwin(0, 0, 0, 0). + + delwin() deletes the named window, freeing all associated memory. In + the case of overlapping windows, subwindows should be deleted before + the main window. + + mvwin() moves the window so that the upper left-hand corner is at + position (y,x). If the move would cause the window to be off the + screen, it is an error and the window is not moved. Moving subwindows + is allowed. + + subwin() creates a new subwindow within a window. The dimensions of + the subwindow are nlines lines and ncols columns. The subwindow is at + position (begy, begx) on the screen. This position is relative to the + screen, and not to the window orig. Changes made to either window + will affect both. When using this routine, you will often need to + call touchwin() before calling wrefresh(). + + derwin() is the same as subwin(), except that begy and begx are + relative to the origin of the window orig rather than the screen. + There is no difference between subwindows and derived windows. + + mvderwin() moves a derived window (or subwindow) inside its parent + window. The screen-relative parameters of the window are not changed. + This routine is used to display different parts of the parent window + at the same physical position on the screen. + + dupwin() creates an exact duplicate of the window win. + + wsyncup() causes a touchwin() of all of the window's parents. + + If wsyncok() is called with a second argument of TRUE, this causes a + wsyncup() to be called every time the window is changed. + + wcursyncup() causes the current cursor position of all of a window's + ancestors to reflect the current cursor position of the current + window. + + wsyncdown() causes a touchwin() of the current window if any of its + parent's windows have been touched. + + resize_window() allows the user to resize an existing window. It + returns the pointer to the new window, or NULL on failure. + + wresize() is an ncurses-compatible wrapper for resize_window(). Note + that, unlike ncurses, it will NOT process any subwindows of the + window. (However, you still can call it _on_ subwindows.) It returns + OK or ERR. + + PDC_makenew() allocates all data for a new WINDOW * except the actual + lines themselves. If it's unable to allocate memory for the window + structure, it will free all allocated memory and return a NULL + pointer. + + PDC_makelines() allocates the memory for the lines. + + PDC_sync() handles wrefresh() and wsyncup() calls when a window is + changed. + +### Return Value + + newwin(), subwin(), derwin() and dupwin() return a pointer to the new + window, or NULL on failure. delwin(), mvwin(), mvderwin() and + syncok() return OK or ERR. wsyncup(), wcursyncup() and wsyncdown() + return nothing. + +### Errors + + It is an error to call resize_window() before calling initscr(). + Also, an error will be generated if we fail to create a newly sized + replacement window for curscr, or stdscr. This could happen when + increasing the window size. NOTE: If this happens, the previously + successfully allocated windows are left alone; i.e., the resize is + NOT cancelled for those windows. + +### Portability + X/Open ncurses NetBSD + newwin Y Y Y + delwin Y Y Y + mvwin Y Y Y + subwin Y Y Y + derwin Y Y Y + mvderwin Y Y Y + dupwin Y Y Y + wsyncup Y Y Y + syncok Y Y Y + wcursyncup Y Y Y + wsyncdown Y Y Y + wresize - Y Y + resize_window - - - + PDC_makelines - - - + PDC_makenew - - - + PDC_sync - - - + +**man-end****************************************************************/ + +#include <stdlib.h> + +WINDOW *PDC_makenew(int nlines, int ncols, int begy, int begx) +{ + WINDOW *win; + + PDC_LOG(("PDC_makenew() - called: lines %d cols %d begy %d begx %d\n", + nlines, ncols, begy, begx)); + + /* allocate the window structure itself */ + + win = calloc(1, sizeof(WINDOW)); + if (!win) + return win; + + /* allocate the line pointer array */ + + win->_y = malloc(nlines * sizeof(chtype *)); + if (!win->_y) + { + free(win); + return (WINDOW *)NULL; + } + + /* allocate the minchng and maxchng arrays */ + + win->_firstch = malloc(nlines * sizeof(int)); + if (!win->_firstch) + { + free(win->_y); + free(win); + return (WINDOW *)NULL; + } + + win->_lastch = malloc(nlines * sizeof(int)); + if (!win->_lastch) + { + free(win->_firstch); + free(win->_y); + free(win); + return (WINDOW *)NULL; + } + + /* initialize window variables */ + + win->_maxy = nlines; /* real max screen size */ + win->_maxx = ncols; /* real max screen size */ + win->_begy = begy; + win->_begx = begx; + win->_bkgd = ' '; /* wrs 4/10/93 -- initialize background to blank */ + win->_clear = (bool) ((nlines == LINES) && (ncols == COLS)); + win->_bmarg = nlines - 1; + win->_parx = win->_pary = -1; + + /* init to say window all changed */ + + touchwin(win); + + return win; +} + +WINDOW *PDC_makelines(WINDOW *win) +{ + int i, j, nlines, ncols; + + PDC_LOG(("PDC_makelines() - called\n")); + + if (!win) + return (WINDOW *)NULL; + + nlines = win->_maxy; + ncols = win->_maxx; + + for (i = 0; i < nlines; i++) + { + win->_y[i] = malloc(ncols * sizeof(chtype)); + if (!win->_y[i]) + { + /* if error, free all the data */ + + for (j = 0; j < i; j++) + free(win->_y[j]); + + free(win->_firstch); + free(win->_lastch); + free(win->_y); + free(win); + + return (WINDOW *)NULL; + } + } + + return win; +} + +void PDC_sync(WINDOW *win) +{ + PDC_LOG(("PDC_sync() - called:\n")); + + if (win->_immed) + wrefresh(win); + if (win->_sync) + wsyncup(win); +} + +WINDOW *newwin(int nlines, int ncols, int begy, int begx) +{ + WINDOW *win; + + PDC_LOG(("newwin() - called:lines=%d cols=%d begy=%d begx=%d\n", + nlines, ncols, begy, begx)); + + if (!nlines) + nlines = LINES - begy; + if (!ncols) + ncols = COLS - begx; + + if (!SP || begy + nlines > SP->lines || begx + ncols > SP->cols) + return (WINDOW *)NULL; + + win = PDC_makenew(nlines, ncols, begy, begx); + if (win) + win = PDC_makelines(win); + + if (win) + werase(win); + + return win; +} + +int delwin(WINDOW *win) +{ + int i; + + PDC_LOG(("delwin() - called\n")); + + if (!win) + return ERR; + + /* subwindows use parents' lines */ + + if (!(win->_flags & (_SUBWIN|_SUBPAD))) + for (i = 0; i < win->_maxy && win->_y[i]; i++) + if (win->_y[i]) + free(win->_y[i]); + + free(win->_firstch); + free(win->_lastch); + free(win->_y); + free(win); + + return OK; +} + +int mvwin(WINDOW *win, int y, int x) +{ + PDC_LOG(("mvwin() - called\n")); + + if (!win || (y + win->_maxy > LINES || y < 0) + || (x + win->_maxx > COLS || x < 0)) + return ERR; + + win->_begy = y; + win->_begx = x; + touchwin(win); + + return OK; +} + +WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begy, int begx) +{ + WINDOW *win; + int i, j, k; + + PDC_LOG(("subwin() - called: lines %d cols %d begy %d begx %d\n", + nlines, ncols, begy, begx)); + + /* make sure window fits inside the original one */ + + if (!orig || (begy < orig->_begy) || (begx < orig->_begx) || + (begy + nlines) > (orig->_begy + orig->_maxy) || + (begx + ncols) > (orig->_begx + orig->_maxx)) + return (WINDOW *)NULL; + + j = begy - orig->_begy; + k = begx - orig->_begx; + + if (!nlines) + nlines = orig->_maxy - 1 - j; + if (!ncols) + ncols = orig->_maxx - 1 - k; + + win = PDC_makenew(nlines, ncols, begy, begx); + if (!win) + return (WINDOW *)NULL; + + /* initialize window variables */ + + win->_attrs = orig->_attrs; + win->_bkgd = orig->_bkgd; + win->_leaveit = orig->_leaveit; + win->_scroll = orig->_scroll; + win->_nodelay = orig->_nodelay; + win->_delayms = orig->_delayms; + win->_use_keypad = orig->_use_keypad; + win->_immed = orig->_immed; + win->_sync = orig->_sync; + win->_pary = j; + win->_parx = k; + win->_parent = orig; + + for (i = 0; i < nlines; i++, j++) + win->_y[i] = orig->_y[j] + k; + + win->_flags |= _SUBWIN; + + return win; +} + +WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begy, int begx) +{ + return subwin(orig, nlines, ncols, begy + orig->_begy, begx + orig->_begx); +} + +int mvderwin(WINDOW *win, int pary, int parx) +{ + int i, j; + WINDOW *mypar; + + if (!win || !(win->_parent)) + return ERR; + + mypar = win->_parent; + + if (pary < 0 || parx < 0 || (pary + win->_maxy) > mypar->_maxy || + (parx + win->_maxx) > mypar->_maxx) + return ERR; + + j = pary; + + for (i = 0; i < win->_maxy; i++) + win->_y[i] = (mypar->_y[j++]) + parx; + + win->_pary = pary; + win->_parx = parx; + + return OK; +} + +WINDOW *dupwin(WINDOW *win) +{ + WINDOW *new; + chtype *ptr, *ptr1; + int nlines, ncols, begy, begx, i; + + if (!win) + return (WINDOW *)NULL; + + nlines = win->_maxy; + ncols = win->_maxx; + begy = win->_begy; + begx = win->_begx; + + new = PDC_makenew(nlines, ncols, begy, begx); + if (new) + new = PDC_makelines(new); + + if (!new) + return (WINDOW *)NULL; + + /* copy the contents of win into new */ + + for (i = 0; i < nlines; i++) + { + for (ptr = new->_y[i], ptr1 = win->_y[i]; + ptr < new->_y[i] + ncols; ptr++, ptr1++) + *ptr = *ptr1; + + new->_firstch[i] = 0; + new->_lastch[i] = ncols - 1; + } + + new->_curx = win->_curx; + new->_cury = win->_cury; + new->_maxy = win->_maxy; + new->_maxx = win->_maxx; + new->_begy = win->_begy; + new->_begx = win->_begx; + new->_flags = win->_flags; + new->_attrs = win->_attrs; + new->_clear = win->_clear; + new->_leaveit = win->_leaveit; + new->_scroll = win->_scroll; + new->_nodelay = win->_nodelay; + new->_delayms = win->_delayms; + new->_use_keypad = win->_use_keypad; + new->_tmarg = win->_tmarg; + new->_bmarg = win->_bmarg; + new->_parx = win->_parx; + new->_pary = win->_pary; + new->_parent = win->_parent; + new->_bkgd = win->_bkgd; + new->_flags = win->_flags; + + return new; +} + +WINDOW *resize_window(WINDOW *win, int nlines, int ncols) +{ + WINDOW *new; + int i, save_cury, save_curx, new_begy, new_begx; + + PDC_LOG(("resize_window() - called: nlines %d ncols %d\n", + nlines, ncols)); + + if (!win || !SP) + return (WINDOW *)NULL; + + if (win->_flags & _SUBPAD) + { + new = subpad(win->_parent, nlines, ncols, win->_begy, win->_begx); + if (!new) + return (WINDOW *)NULL; + } + else if (win->_flags & _SUBWIN) + { + new = subwin(win->_parent, nlines, ncols, win->_begy, win->_begx); + if (!new) + return (WINDOW *)NULL; + } + else + { + if (win == SP->slk_winptr) + { + new_begy = SP->lines - SP->slklines; + new_begx = 0; + } + else + { + new_begy = win->_begy; + new_begx = win->_begx; + } + + new = PDC_makenew(nlines, ncols, new_begy, new_begx); + if (!new) + return (WINDOW *)NULL; + } + + save_curx = min(win->_curx, (new->_maxx - 1)); + save_cury = min(win->_cury, (new->_maxy - 1)); + + if (!(win->_flags & (_SUBPAD|_SUBWIN))) + { + new = PDC_makelines(new); + if (!new) + return (WINDOW *)NULL; + + new->_bkgd = win->_bkgd; + werase(new); + + copywin(win, new, 0, 0, 0, 0, min(win->_maxy, new->_maxy) - 1, + min(win->_maxx, new->_maxx) - 1, FALSE); + + for (i = 0; i < win->_maxy && win->_y[i]; i++) + if (win->_y[i]) + free(win->_y[i]); + } + + new->_flags = win->_flags; + new->_attrs = win->_attrs; + new->_clear = win->_clear; + new->_leaveit = win->_leaveit; + new->_scroll = win->_scroll; + new->_nodelay = win->_nodelay; + new->_delayms = win->_delayms; + new->_use_keypad = win->_use_keypad; + new->_tmarg = (win->_tmarg > new->_maxy - 1) ? 0 : win->_tmarg; + new->_bmarg = (win->_bmarg == win->_maxy - 1) ? + new->_maxy - 1 : min(win->_bmarg, (new->_maxy - 1)); + new->_parent = win->_parent; + new->_immed = win->_immed; + new->_sync = win->_sync; + new->_bkgd = win->_bkgd; + + new->_curx = save_curx; + new->_cury = save_cury; + + free(win->_firstch); + free(win->_lastch); + free(win->_y); + + *win = *new; + free(new); + + return win; +} + +int wresize(WINDOW *win, int nlines, int ncols) +{ + return (resize_window(win, nlines, ncols) ? OK : ERR); +} + +void wsyncup(WINDOW *win) +{ + WINDOW *tmp; + + PDC_LOG(("wsyncup() - called\n")); + + for (tmp = win; tmp; tmp = tmp->_parent) + touchwin(tmp); +} + +int syncok(WINDOW *win, bool bf) +{ + PDC_LOG(("syncok() - called\n")); + + if (!win) + return ERR; + + win->_sync = bf; + + return OK; +} + +void wcursyncup(WINDOW *win) +{ + WINDOW *tmp; + + PDC_LOG(("wcursyncup() - called\n")); + + for (tmp = win; tmp && tmp->_parent; tmp = tmp->_parent) + wmove(tmp->_parent, tmp->_pary + tmp->_cury, tmp->_parx + tmp->_curx); +} + +void wsyncdown(WINDOW *win) +{ + WINDOW *tmp; + + PDC_LOG(("wsyncdown() - called\n")); + + for (tmp = win; tmp; tmp = tmp->_parent) + { + if (is_wintouched(tmp)) + { + touchwin(win); + break; + } + } +} |