/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
*/

/*	Copyright (c) 1984 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident	"$Header: winsch.c 1.5 89/11/30 $@(#)curses:screen/winsch.c	1.4"
#include	"curses_inc.h"
#include	<ctype.h>

/* Insert a character at (curx, cury). */

winsch(win, c)
register	WINDOW	*win;
chtype	c;
{
    register	int	x, endx, n, curx = win->_curx, cury = win->_cury;
    register	chtype	*wcp, a;
    int 		rv;

    a = _ATTR(c);
    c &= A_CHARTEXT;

    rv = OK;
    win->_insmode = TRUE;
    if(_scrmax > 1 && (rv = _mbvalid(win)) == ERR)
	goto done;
    /* take care of multi-byte characters */
    if(_mbtrue && ISMBIT(c))
	{
	rv = _mbaddch(win,A_NORMAL,RBYTE(c));
	goto done;
	}
    win->_nbyte = -1;
    curx = win->_curx;
    /* let waddch() worry about these */
    if (c == '\r' || c == '\b')
	return (waddch(win, c));

    /* with \n, in contrast to waddch, we don't clear-to-eol */
    if (c == '\n')
    {
	if (cury >= (win->_maxy-1) || cury == win->_bmarg)
	    return (wscrl(win, 1));
	else
	{
	    win->_cury++;
	    win->_curx = 0;
	    return (OK);
	}
    }

    /* with tabs or control characters, we have to do more */
    if (c == '\t')
    {
	n = (TABSIZE - (curx % TABSIZE));
	if ((curx + n) >= win->_maxx)
	    n = win->_maxx - curx;
	c = ' ';
    }
    else
    {
	if (iscntrl((int) c))
	{
	    if (curx >= win->_maxx-1)
		return (ERR);
	    n = 2;
	}
	else
	    n = 1;
    }

    /* shift right */
    endx = curx + n;
    x = win->_maxx - 1;
    wcp = win->_y[cury] + x;
    wcp = win->_y[cury] + curx;
    if((rv = _insshift(win,n)) == ERR)
	goto done;

    /* insert new control character */
    if (c < ' ' || c == _CTRL('?'))
    {
	*wcp++ = '^' | win->_attrs | a;
	*wcp = _UNCTRL(c) | win->_attrs | a;
    }
    else
    {
	/* normal characters */
	c = _WCHAR(win, c) | a;
	for ( ; n > 0; --n)
	    *wcp++ = c;
    }

done:
    if (curx < win->_firstch[cury])
	win->_firstch[cury] = curx;
    win->_lastch[cury] = win->_maxx-1;

    win->_flags |= _WINCHANGED;

    if (win->_sync)
	wsyncup(win);

    return((rv == OK && win->_immed) ? wrefresh(win) : rv);
}
