1 /* $NetBSD: ins_wstr.c,v 1.6 2010/12/16 17:42:28 wiz 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.6 2010/12/16 17:42:28 wiz 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 */
163 n
--, len
++, width
+= w
;
167 __CTRACE(__CTRACE_INPUT
, "wins_nwstr: width=%d,len=%d\n", width
, len
);
170 if (cw
> win
->maxx
- win
->curx
+ 1)
172 start
= &win
->alines
[win
->cury
]->line
[win
->curx
];
174 lnp
= win
->alines
[win
->cury
];
181 __CTRACE(__CTRACE_INPUT
, "wins_nwstr: start@(%d)\n", sx
);
184 lnp
->flags
|= __ISDIRTY
;
185 newx
= sx
+ win
->ch_off
;
186 if (newx
< *lnp
->firstchp
)
187 *lnp
->firstchp
= newx
;
190 __CTRACE(__CTRACE_INPUT
, "========before=======\n");
191 for (x
= 0; x
< win
->maxx
; x
++)
192 __CTRACE(__CTRACE_INPUT
,
193 "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
195 win
->alines
[win
->cury
]->line
[x
].ch
,
196 win
->alines
[win
->cury
]->line
[x
].attr
,
197 win
->alines
[win
->cury
]->line
[x
].nsp
);
201 /* shift all complete characters */
202 if (sx
+ width
+ pcw
<= win
->maxx
) {
204 __CTRACE(__CTRACE_INPUT
, "wins_nwstr: shift all characters\n");
206 temp1
= &win
->alines
[win
->cury
]->line
[win
->maxx
- 1];
207 temp2
= temp1
- width
;
208 pcw
= WCOL(*(temp2
+ 1));
211 __CTRACE(__CTRACE_INPUT
,
212 "wins_nwstr: clear from %d to EOL(%d)\n",
213 win
->maxx
+ pcw
, win
->maxx
- 1);
216 while (temp1
> temp2
+ width
) {
217 temp1
->ch
= (wchar_t)btowc((int) win
->bch
);
218 if (_cursesi_copy_nsp(win
->bnsp
, temp1
) == ERR
)
220 temp1
->attr
= win
->battr
;
223 __CTRACE(__CTRACE_INPUT
,
224 "wins_nwstr: empty cell(%p)\n", temp1
);
229 while (temp2
>= start
) {
230 (void)memcpy(temp1
, temp2
, sizeof(__LDATA
));
235 __CTRACE(__CTRACE_INPUT
, "=====after shift====\n");
236 for (x
= 0; x
< win
->maxx
; x
++)
237 __CTRACE(__CTRACE_INPUT
,
238 "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
240 win
->alines
[win
->cury
]->line
[x
].ch
,
241 win
->alines
[win
->cury
]->line
[x
].attr
,
242 win
->alines
[win
->cury
]->line
[x
].nsp
);
247 /* update string columns */
250 for (scp
= wstr
, temp1
= start
; len
; len
--, scp
++) {
262 if (y
== win
->scr_b
) {
263 if (!(win
->flags
& __SCROLLOK
))
269 if (wins_nwstr(win
, ws
,
270 min(win
->maxx
- x
, 8-(x
% 8)))
280 temp1
->ch
= (wchar_t)*scp
;
281 temp1
->attr
= win
->wattr
;
282 SET_WCOL(*temp1
, cw
);
285 __CTRACE(__CTRACE_INPUT
,
286 "wins_nwstr: add spacing char(%x)\n", temp1
->ch
);
291 while (temp1
< temp2
+ cw
) {
292 /* the rest columns */
293 temp1
->ch
= (wchar_t)*scp
;
294 temp1
->attr
= win
->wattr
;
302 /* non-spacing character */
303 np
= (nschar_t
*)malloc(sizeof(nschar_t
));
307 np
->next
= temp1
->nsp
;
310 __CTRACE(__CTRACE_INPUT
,
311 "wins_nstr: add non-spacing char(%x)\n", np
->ch
);
317 __CTRACE(__CTRACE_INPUT
, "========after=======\n");
318 for (x
= 0; x
< win
->maxx
; x
++)
319 __CTRACE(__CTRACE_INPUT
,
320 "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
322 win
->alines
[win
->cury
]->line
[x
].ch
,
323 win
->alines
[win
->cury
]->line
[x
].attr
,
324 win
->alines
[win
->cury
]->line
[x
].nsp
);
327 newx
= win
->maxx
- 1 + win
->ch_off
;
328 if (newx
> *lnp
->lastchp
)
329 *lnp
->lastchp
= newx
;
330 __touchline(win
, (int) win
->cury
, sx
, (int) win
->maxx
- 1);
332 #endif /* HAVE_WCHAR */