128 lines
2.6 KiB
C
128 lines
2.6 KiB
C
|
|
/* This work is copyrighted. See COPYRIGHT.OLD & COPYRIGHT.NEW for *
|
|
* details. If they are missing then this copy is in violation of *
|
|
* the copyright conditions. */
|
|
|
|
/*
|
|
** lib_addch.c
|
|
**
|
|
** The routine waddch().
|
|
**
|
|
*/
|
|
|
|
#include "curses.priv.h"
|
|
#include "unctrl.h"
|
|
|
|
static inline chtype render_char(WINDOW *win, chtype ch)
|
|
/* compute a rendition of the given char correct for the current context */
|
|
{
|
|
if (TextOf(ch) == ' ')
|
|
ch = ch_or_attr(ch, win->_bkgd);
|
|
else if (!(ch & A_ATTRIBUTES))
|
|
ch = ch_or_attr(ch, (win->_bkgd & A_ATTRIBUTES));
|
|
TR(TRACE_CHARPUT, ("bkg = %#lx -> ch = %#lx", win->_bkgd, ch));
|
|
|
|
return(ch);
|
|
}
|
|
|
|
chtype _nc_background(WINDOW *win)
|
|
/* make render_char() visible while still allowing us to inline it below */
|
|
{
|
|
return(render_char(win, BLANK));
|
|
}
|
|
|
|
chtype _nc_render(WINDOW *win, chtype ch)
|
|
/* make render_char() visible while still allowing us to inline it below */
|
|
{
|
|
chtype c = render_char(win,ch);
|
|
return (ch_or_attr(c,win->_attrs));
|
|
}
|
|
|
|
static int
|
|
wladdch(WINDOW *win, chtype c, bool literal)
|
|
{
|
|
int x, y;
|
|
int newx;
|
|
chtype ch = c;
|
|
|
|
x = win->_curx;
|
|
y = win->_cury;
|
|
|
|
if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
|
|
return(ERR);
|
|
|
|
/* ugly, but necessary --- and, bizarrely enough, even portable! */
|
|
if (literal)
|
|
goto noctrl;
|
|
|
|
switch (ch&A_CHARTEXT) {
|
|
case '\t':
|
|
for (newx = x + (8 - (x & 07)); x < newx; x++)
|
|
if (waddch(win, ' ') == ERR)
|
|
return(ERR);
|
|
return(OK);
|
|
case '\n':
|
|
wclrtoeol(win);
|
|
x = 0;
|
|
goto newline;
|
|
case '\r':
|
|
x = 0;
|
|
break;
|
|
case '\b':
|
|
if (--x < 0)
|
|
x = 0;
|
|
break;
|
|
default:
|
|
if (ch < ' ')
|
|
return(waddstr(win, unctrl(ch)));
|
|
|
|
/* FALL THROUGH */
|
|
noctrl:
|
|
T(("win attr = %x", win->_attrs));
|
|
ch = render_char(win, ch);
|
|
ch = ch_or_attr(ch,win->_attrs);
|
|
|
|
if (win->_line[y][x] != ch) {
|
|
if (win->_firstchar[y] == _NOCHANGE)
|
|
win->_firstchar[y] = win->_lastchar[y] = x;
|
|
else if (x < win->_firstchar[y])
|
|
win->_firstchar[y] = x;
|
|
else if (x > win->_lastchar[y])
|
|
win->_lastchar[y] = x;
|
|
|
|
}
|
|
|
|
T(("char %d of line %d is %x", x, y, ch));
|
|
win->_line[y][x++] = ch;
|
|
if (x > win->_maxx) {
|
|
x = 0;
|
|
newline:
|
|
y++;
|
|
if (y > win->_regbottom) {
|
|
y--;
|
|
if (win->_scroll)
|
|
scroll(win);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
win->_curx = x;
|
|
win->_cury = y;
|
|
|
|
return(OK);
|
|
}
|
|
|
|
int waddch(WINDOW *win, chtype ch)
|
|
{
|
|
TR(TRACE_CHARPUT, ("waddch(%x,%c (%x)) called", win, ch&A_CHARTEXT, ch));
|
|
return wladdch(win, ch, FALSE);
|
|
}
|
|
|
|
int wechochar(WINDOW *win, chtype ch)
|
|
{
|
|
T(("wechochar(%x,%c (%x)) called", win, ch&A_CHARTEXT, ch));
|
|
|
|
return wladdch(win, ch, TRUE);
|
|
}
|