xref: /openbsd/lib/libcurses/base/lib_insch.c (revision 73471bf0)
1 /* $OpenBSD: lib_insch.c,v 1.3 2010/01/12 23:22:05 nicm Exp $ */
2 
3 /****************************************************************************
4  * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc.              *
5  *                                                                          *
6  * Permission is hereby granted, free of charge, to any person obtaining a  *
7  * copy of this software and associated documentation files (the            *
8  * "Software"), to deal in the Software without restriction, including      *
9  * without limitation the rights to use, copy, modify, merge, publish,      *
10  * distribute, distribute with modifications, sublicense, and/or sell       *
11  * copies of the Software, and to permit persons to whom the Software is    *
12  * furnished to do so, subject to the following conditions:                 *
13  *                                                                          *
14  * The above copyright notice and this permission notice shall be included  *
15  * in all copies or substantial portions of the Software.                   *
16  *                                                                          *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
20  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
23  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
24  *                                                                          *
25  * Except as contained in this notice, the name(s) of the above copyright   *
26  * holders shall not be used in advertising or otherwise to promote the     *
27  * sale, use or other dealings in this Software without prior written       *
28  * authorization.                                                           *
29  ****************************************************************************/
30 
31 /****************************************************************************
32  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
33  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
34  *     and: Sven Verdoolaege                                                *
35  *     and: Thomas E. Dickey                                                *
36  ****************************************************************************/
37 
38 /*
39 **	lib_insch.c
40 **
41 **	The routine winsch().
42 **
43 */
44 
45 #include <curses.priv.h>
46 #include <ctype.h>
47 
48 MODULE_ID("$Id: lib_insch.c,v 1.3 2010/01/12 23:22:05 nicm Exp $")
49 
50 /*
51  * Insert the given character, updating the current location to simplify
52  * inserting a string.
53  */
54 NCURSES_EXPORT(int)
55 _nc_insert_ch(WINDOW *win, chtype ch)
56 {
57     int code = OK;
58     NCURSES_CH_T wch;
59     int count;
60     NCURSES_CONST char *s;
61 
62     switch (ch) {
63     case '\t':
64 	for (count = (TABSIZE - (win->_curx % TABSIZE)); count > 0; count--) {
65 	    if ((code = _nc_insert_ch(win, ' ')) != OK)
66 		break;
67 	}
68 	break;
69     case '\n':
70     case '\r':
71     case '\b':
72 	SetChar2(wch, ch);
73 	_nc_waddch_nosync(win, wch);
74 	break;
75     default:
76 	if (
77 #if USE_WIDEC_SUPPORT
78 	       WINDOW_EXT(win, addch_used) == 0 &&
79 #endif
80 	       is8bits(ChCharOf(ch)) &&
81 	       isprint(ChCharOf(ch))) {
82 	    if (win->_curx <= win->_maxx) {
83 		struct ldat *line = &(win->_line[win->_cury]);
84 		NCURSES_CH_T *end = &(line->text[win->_curx]);
85 		NCURSES_CH_T *temp1 = &(line->text[win->_maxx]);
86 		NCURSES_CH_T *temp2 = temp1 - 1;
87 
88 		SetChar2(wch, ch);
89 
90 		CHANGED_TO_EOL(line, win->_curx, win->_maxx);
91 		while (temp1 > end)
92 		    *temp1-- = *temp2--;
93 
94 		*temp1 = _nc_render(win, wch);
95 		win->_curx++;
96 	    }
97 	} else if (is8bits(ChCharOf(ch)) && iscntrl(ChCharOf(ch))) {
98 	    s = unctrl(ChCharOf(ch));
99 	    while (*s != '\0') {
100 		code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s));
101 		if (code != OK)
102 		    break;
103 		++s;
104 	    }
105 	}
106 #if USE_WIDEC_SUPPORT
107 	else {
108 	    /*
109 	     * Handle multibyte characters here
110 	     */
111 	    SetChar2(wch, ch);
112 	    wch = _nc_render(win, wch);
113 	    count = _nc_build_wch(win, &wch);
114 	    if (count > 0) {
115 		code = wins_wch(win, &wch);
116 	    } else if (count == -1) {
117 		/* handle EILSEQ */
118 		if (is8bits(ch)) {
119 		    s = unctrl(ChCharOf(ch));
120 		    while (*s != '\0') {
121 			code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s));
122 			if (code != OK)
123 			    break;
124 			++s;
125 		    }
126 		} else {
127 		    code = ERR;
128 		}
129 	    }
130 	}
131 #endif
132 	break;
133     }
134     return code;
135 }
136 
137 NCURSES_EXPORT(int)
138 winsch(WINDOW *win, chtype c)
139 {
140     NCURSES_SIZE_T oy;
141     NCURSES_SIZE_T ox;
142     int code = ERR;
143 
144     T((T_CALLED("winsch(%p, %s)"), win, _tracechtype(c)));
145 
146     if (win != 0) {
147 	oy = win->_cury;
148 	ox = win->_curx;
149 
150 	code = _nc_insert_ch(win, c);
151 
152 	win->_curx = ox;
153 	win->_cury = oy;
154 	_nc_synchook(win);
155     }
156     returnCode(code);
157 }
158