1 /*
2    Copyright (c) 2002 Perry Rapp
3    "The MIT license"
4    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7 */
8 /*=============================================================
9  * cscurses.c -- layer on top of curses,
10  *  providing conversion to internal codeset
11  *==============================================================*/
12 
13 #include "llstdlib.h"
14 #include "liflines.h"
15 #include "llinesi.h"
16 #include "screen.h"
17 #include "cscurses.h"
18 #include "zstr.h"
19 
20 /*********************************************
21  * local function prototypes
22  *********************************************/
23 
24 /* alphabetical */
25 static void disp_to_int(ZSTR zstr);
26 static void int_to_disp(ZSTR zstr);
27 static size_t output_width(ZSTR zstr);
28 
29 /*********************************************
30  * local & exported function definitions
31  * body of module
32  *********************************************/
33 
34 /*============================
35  * int_to_disp -- convert internal codeset to GUI
36  * Created: 2002/12/03 (Perry Rapp)
37  *==========================*/
38 void
int_to_disp(ZSTR zstr)39 int_to_disp (ZSTR zstr)
40 {
41 	XLAT xlat = transl_get_predefined_xlat(MINDS);
42 	if (xlat)
43 		transl_xlat(xlat, zstr); /* ignore failure */
44 }
45 /*============================
46  * disp_to_int -- convert GUI codeset to internal
47  * Created: 2002/12/03 (Perry Rapp)
48  *==========================*/
49 void
disp_to_int(ZSTR zstr)50 disp_to_int (ZSTR zstr)
51 {
52 	XLAT xlat = transl_get_predefined_xlat(MDSIN);
53 	if (xlat)
54 		transl_xlat(xlat, zstr); /* ignore failure */
55 }
56 /*============================
57  * output_width -- display width of string in characters
58  *==========================*/
59 static size_t
output_width(ZSTR zstr)60 output_width (ZSTR zstr)
61 {
62 	if (gui8) {
63 		/* TODO: Need to use wcswidth here */
64 		return str8chlen(zs_str(zstr));
65 	} else {
66 		return zs_len(zstr);
67 
68 	}
69 }
70 /*============================
71  * mvcuwaddstr -- convert to GUI codeset & output to screen
72  * Created: 2002/12/13 (Perry Rapp)
73  *==========================*/
74 int
mvccuwaddstr(UIWINDOW uiw,int y,int x,const char * cp)75 mvccuwaddstr (UIWINDOW uiw, int y, int x, const char *cp)
76 {
77 	return mvccwaddnstr(uiw_win(uiw), y, x, cp, uiw_cols(uiw));
78 }
79 /*============================
80  * mvcwaddstr -- convert to GUI codeset & call mvwaddstr
81  * Created: 2002/12/03 (Perry Rapp)
82  * TODO: Convert all calls of this to call mvccuwaddstr (or mvccwaddnstr) !
83  *==========================*/
84 int
mvccwaddstr(WINDOW * wp,int y,int x,const char * cp)85 mvccwaddstr (WINDOW *wp, int y, int x, const char *cp)
86 {
87 	ZSTR zstr = zs_news(cp);
88 	int rtn;
89 	int_to_disp(zstr);
90 	rtn = mvwaddstr(wp, y, x, zs_str(zstr));
91 	zs_free(&zstr);
92 	return rtn;
93 }
94 /*============================
95  * mvcwaddnstr -- convert to GUI codeset & call mvwaddstr with length limit
96  * Created: 2002/12/13 (Perry Rapp)
97   *==========================*/
98 int
mvccwaddnstr(WINDOW * wp,int y,int x,const char * cp,int n)99 mvccwaddnstr (WINDOW *wp, int y, int x, const char *cp, int n)
100 {
101 	ZSTR zstr = zs_news(cp);
102 	int rtn=0;
103 
104 	int_to_disp(zstr);
105 
106 	if (zs_len(zstr) < (unsigned int)n) {
107 		rtn = mvwaddstr(wp, y, x, zs_str(zstr));
108 	} else {
109 		if (output_width(zstr) > (size_t)n) {
110 			STRING str = zs_str(zstr);
111 			/* We need to do length truncation correctly for UTF-8 output */
112 			/* #1) We need to not break UTF-8 multibytes */
113 
114 			INT width=0;
115 			STRING prev = find_prev_char(&str[n-1], &width, str, gui8);
116 			width += (prev - str);
117 			zs_chop(zstr, width);
118 
119 			/* #2) We should account for zero-width characters, eg, use wcwidth */
120 			/* Unfortunately, lifelines doesn't yet use wcwidth or config test it */
121 			/* TODO:
122 			config test for wcswidth
123 			and substitute Markus Kuhn's
124 			http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
125 			*/
126 		}
127 		rtn = mvwaddnstr(wp, y, x, zs_str(zstr), n);
128 	}
129 	zs_free(&zstr);
130 	return rtn;
131 }
132 /*============================
133  * mvccwprintw -- mvwprintw with codeset convert from internal to GUI
134  * mvcwaddstr -- convert to GUI codeset & call mvwaddstr
135  * Created: 2002/12/03 (Perry Rapp)
136  *==========================*/
137 int
mvccwprintw(WINDOW * wp,int y,int x,...)138 mvccwprintw (WINDOW *wp, int y, int x, ...)
139 {
140 	va_list args;
141 	char * fmt;
142 	va_start(args, x);
143 	wmove(wp, y, x);
144 	fmt = va_arg(args, char *);
145 	return vccwprintw(wp, fmt, args);
146 }
147 /*============================
148  * vccwprintw -- vwprintw with codeset convert from internal to GUI
149  * Created: 2002/12/03 (Perry Rapp)
150  *==========================*/
151 int
vccwprintw(WINDOW * wp,const char * fmt,va_list args)152 vccwprintw (WINDOW *wp, const char *fmt, va_list args)
153 {
154 	ZSTR zstr = zs_newvf(fmt, args);
155 	int rtn;
156 	int_to_disp(zstr);
157 	rtn = waddstr(wp, zs_str(zstr));
158 	zs_free(&zstr);
159 	return rtn;
160 }
161 /*============================
162  * vccprintf -- vprintf with codeset convert from internal to GUI
163  * Created: 2002/12/03 (Perry Rapp)
164  *==========================*/
165 int
vccprintf(const char * fmt,va_list args)166 vccprintf (const char *fmt, va_list args)
167 {
168 	int rtn;
169 	ZSTR zstr = zs_newvf(fmt, args);
170 	int_to_disp(zstr);
171 	rtn = printf(zs_str(zstr));
172 	zs_free(&zstr);
173 	return rtn;
174 }
175 /*============================
176  * wgetccnstr -- wgetnstr with codeset convert from GUI to internal
177  * Created: 2002/12/03 (Perry Rapp)
178  *==========================*/
179 int
wgetccnstr(WINDOW * wp,char * cp,int n)180 wgetccnstr (WINDOW *wp, char *cp, int n)
181 {
182 	ZSTR zstr=0;
183 /* TODO: Need Win32-specific code here to handle Unicode input on NT family */
184 	int rtn = wgetnstr(wp, (char *)cp, n);
185 	zstr = zs_news(cp);
186 	disp_to_int(zstr);
187 	llstrsets(cp, n, uu8, zs_str(zstr));
188 	zs_free(&zstr);
189 	return rtn;
190 }
191