1 /* $NetBSD: ins_wstr.c,v 1.3 2007/05/29 11:10:56 blymn Exp $ */
4 * Copyright (c) 2005 The NetBSD Foundation Inc.
7 * This code is derived from code donated to the NetBSD Foundation
8 * by Ruibiao Qiu <ruibiao@arl.wustl.edu,ruibiao@gmail.com>.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the NetBSD Foundation nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
24 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <sys/cdefs.h>
39 __RCSID("$NetBSD: ins_wstr.c,v 1.3 2007/05/29 11:10:56 blymn Exp $");
46 #include "curses_private.h"
50 * insert a multi-character wide character string into the current window
53 ins_wstr(const wchar_t *wstr
)
55 return wins_wstr(stdscr
, wstr
);
60 * insert a multi-character wide character string into the current window
61 * with at most n characters
64 ins_nwstr(const wchar_t *wstr
, int n
)
66 return wins_nwstr(stdscr
, wstr
, n
);
71 * Do an insert-string on the line at (y, x).
74 mvins_wstr(int y
, int x
, const wchar_t *wstr
)
76 return mvwins_wstr(stdscr
, y
, x
, wstr
);
81 * Do an insert-n-string on the line at (y, x).
84 mvins_nwstr(int y
, int x
, const wchar_t *wstr
, int n
)
86 return mvwins_nwstr(stdscr
, y
, x
, wstr
, n
);
91 * Do an insert-string on the line at (y, x) in the given window.
94 mvwins_wstr(WINDOW
*win
, int y
, int x
, const wchar_t *wstr
)
96 if (wmove(win
, y
, x
) == ERR
)
99 return wins_wstr(stdscr
, wstr
);
104 * Do an insert-n-string on the line at (y, x) in the given window.
107 mvwins_nwstr(WINDOW
*win
, int y
, int x
, const wchar_t *wstr
, int n
)
109 if (wmove(win
, y
, x
) == ERR
)
112 return wins_nwstr(stdscr
, wstr
, n
);
118 * Do an insert-string on the line, leaving (cury, curx) unchanged.
121 wins_wstr(WINDOW
*win
, const wchar_t *wstr
)
123 return wins_nwstr(win
, wstr
, -1);
128 * Do an insert-n-string on the line, leaving (cury, curx) unchanged.
131 wins_nwstr(WINDOW
*win
, const wchar_t *wstr
, int n
)
136 __LDATA
*start
, *temp1
, *temp2
;
139 int width
, len
, sx
, x
, y
, cw
, pcw
, newx
;
143 /* check for leading non-spacing character */
157 n
--, len
++, width
+= wcwidth(*scp
);
161 __CTRACE(__CTRACE_INPUT
, "wins_nwstr: width=%d,len=%d\n", width
, len
);
164 if (cw
> win
->maxx
- win
->curx
+ 1)
166 start
= &win
->alines
[win
->cury
]->line
[win
->curx
];
168 lnp
= win
->alines
[win
->cury
];
175 __CTRACE(__CTRACE_INPUT
, "wins_nwstr: start@(%d)\n", sx
);
178 lnp
->flags
|= __ISDIRTY
;
179 newx
= sx
+ win
->ch_off
;
180 if (newx
< *lnp
->firstchp
)
181 *lnp
->firstchp
= newx
;
184 __CTRACE(__CTRACE_INPUT
, "========before=======\n");
185 for (x
= 0; x
< win
->maxx
; x
++)
186 __CTRACE(__CTRACE_INPUT
,
187 "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
189 win
->alines
[win
->cury
]->line
[x
].ch
,
190 win
->alines
[win
->cury
]->line
[x
].attr
,
191 win
->alines
[win
->cury
]->line
[x
].nsp
);
195 /* shift all complete characters */
196 if (sx
+ width
+ pcw
<= win
->maxx
) {
198 __CTRACE(__CTRACE_INPUT
, "wins_nwstr: shift all characters\n");
200 temp1
= &win
->alines
[win
->cury
]->line
[win
->maxx
- 1];
201 temp2
= temp1
- width
;
202 pcw
= WCOL(*(temp2
+ 1));
205 __CTRACE(__CTRACE_INPUT
,
206 "wins_nwstr: clear from %d to EOL(%d)\n",
207 win
->maxx
+ pcw
, win
->maxx
- 1);
210 while (temp1
> temp2
+ width
) {
211 temp1
->ch
= (wchar_t)btowc((int) win
->bch
);
212 if (_cursesi_copy_nsp(win
->bnsp
, temp1
) == ERR
)
214 temp1
->attr
= win
->battr
;
217 __CTRACE(__CTRACE_INPUT
,
218 "wins_nwstr: empty cell(%p)\n", temp1
);
223 while (temp2
>= start
) {
224 (void)memcpy(temp1
, temp2
, sizeof(__LDATA
));
229 __CTRACE(__CTRACE_INPUT
, "=====after shift====\n");
230 for (x
= 0; x
< win
->maxx
; x
++)
231 __CTRACE(__CTRACE_INPUT
,
232 "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
234 win
->alines
[win
->cury
]->line
[x
].ch
,
235 win
->alines
[win
->cury
]->line
[x
].attr
,
236 win
->alines
[win
->cury
]->line
[x
].nsp
);
241 /* update string columns */
244 for (scp
= wstr
, temp1
= start
; len
; len
--, scp
++) {
256 if (y
== win
->scr_b
) {
257 if (!(win
->flags
& __SCROLLOK
))
263 if (wins_nwstr(win
, ws
,
264 min(win
->maxx
- x
, 8-(x
% 8)))
272 temp1
->ch
= (wchar_t)*scp
;
273 temp1
->attr
= win
->wattr
;
274 SET_WCOL(*temp1
, cw
);
277 __CTRACE(__CTRACE_INPUT
,
278 "wins_nwstr: add spacing char(%x)\n", temp1
->ch
);
283 while (temp1
< temp2
+ cw
) {
284 /* the rest columns */
285 temp1
->ch
= (wchar_t)*scp
;
286 temp1
->attr
= win
->wattr
;
294 /* non-spacing character */
295 np
= (nschar_t
*)malloc(sizeof(nschar_t
));
299 np
->next
= temp1
->nsp
;
302 __CTRACE(__CTRACE_INPUT
,
303 "wins_nstr: add non-spacing char(%x)\n", np
->ch
);
309 __CTRACE(__CTRACE_INPUT
, "========after=======\n");
310 for (x
= 0; x
< win
->maxx
; x
++)
311 __CTRACE(__CTRACE_INPUT
,
312 "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
314 win
->alines
[win
->cury
]->line
[x
].ch
,
315 win
->alines
[win
->cury
]->line
[x
].attr
,
316 win
->alines
[win
->cury
]->line
[x
].nsp
);
319 newx
= win
->maxx
- 1 + win
->ch_off
;
320 if (newx
> *lnp
->lastchp
)
321 *lnp
->lastchp
= newx
;
322 __touchline(win
, (int) win
->cury
, sx
, (int) win
->maxx
- 1);
324 #endif /* HAVE_WCHAR */