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