[BACK]Return to ins_wstr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libcurses

Annotation of src/lib/libcurses/ins_wstr.c, Revision 1.11.4.1

1.11.4.1! martin      1: /*   $NetBSD: ins_wstr.c,v 1.11 2017/01/31 09:17:53 roy Exp $ */
1.1       blymn       2:
                      3: /*
                      4:  * Copyright (c) 2005 The NetBSD Foundation Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from code donated to the NetBSD Foundation
                      8:  * by Ruibiao Qiu <ruibiao@arl.wustl.edu,ruibiao@gmail.com>.
                      9:  *
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     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.
                     22:  *
                     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
                     34:  * SUCH DAMAGE.
                     35:  */
                     36:
                     37: #include <sys/cdefs.h>
                     38: #ifndef lint
1.11.4.1! martin     39: __RCSID("$NetBSD: ins_wstr.c,v 1.11 2017/01/31 09:17:53 roy Exp $");
1.1       blymn      40: #endif                                           /* not lint */
                     41:
                     42: #include <string.h>
                     43: #include <stdlib.h>
                     44:
                     45: #include "curses.h"
                     46: #include "curses_private.h"
                     47:
                     48: /*
                     49:  * ins_wstr --
1.6       wiz        50:  *     insert a multi-character wide-character string into the current window
1.1       blymn      51:  */
                     52: int
                     53: ins_wstr(const wchar_t *wstr)
                     54: {
                     55:        return wins_wstr(stdscr, wstr);
                     56: }
                     57:
                     58: /*
                     59:  * ins_nwstr --
1.6       wiz        60:  *     insert a multi-character wide-character string into the current window
1.1       blymn      61:  *     with at most n characters
                     62:  */
                     63: int
                     64: ins_nwstr(const wchar_t *wstr, int n)
                     65: {
                     66:        return wins_nwstr(stdscr, wstr, n);
                     67: }
                     68:
                     69: /*
                     70:  * mvins_wstr --
                     71:  *       Do an insert-string on the line at (y, x).
                     72:  */
                     73: int
                     74: mvins_wstr(int y, int x, const wchar_t *wstr)
                     75: {
                     76:        return mvwins_wstr(stdscr, y, x, wstr);
                     77: }
                     78:
                     79: /*
                     80:  * mvins_nwstr --
                     81:  *       Do an insert-n-string on the line at (y, x).
                     82:  */
                     83: int
                     84: mvins_nwstr(int y, int x, const wchar_t *wstr, int n)
                     85: {
                     86:        return mvwins_nwstr(stdscr, y, x, wstr, n);
                     87: }
                     88:
                     89: /*
                     90:  * mvwins_wstr --
                     91:  *       Do an insert-string on the line at (y, x) in the given window.
                     92:  */
                     93: int
                     94: mvwins_wstr(WINDOW *win, int y, int x, const wchar_t *wstr)
                     95: {
                     96:        if (wmove(win, y, x) == ERR)
                     97:                return ERR;
                     98:
1.11.4.1! martin     99:        return wins_wstr(win, wstr);
1.1       blymn     100: }
                    101:
                    102: /*
                    103:  * mvwins_nwstr --
                    104:  *       Do an insert-n-string on the line at (y, x) in the given window.
                    105:  */
                    106: int
                    107: mvwins_nwstr(WINDOW *win, int y, int x, const wchar_t *wstr, int n)
                    108: {
                    109:        if (wmove(win, y, x) == ERR)
                    110:                return ERR;
                    111:
1.11.4.1! martin    112:        return wins_nwstr(win, wstr, n);
1.1       blymn     113: }
                    114:
                    115:
                    116: /*
                    117:  * wins_wstr --
                    118:  *     Do an insert-string on the line, leaving (cury, curx) unchanged.
                    119:  */
                    120: int
                    121: wins_wstr(WINDOW *win, const wchar_t *wstr)
                    122: {
                    123:        return wins_nwstr(win, wstr, -1);
                    124: }
                    125:
                    126: /*
                    127:  * wins_nwstr --
                    128:  *     Do an insert-n-string on the line, leaving (cury, curx) unchanged.
                    129:  */
                    130: int
                    131: wins_nwstr(WINDOW *win, const wchar_t *wstr, int n)
                    132: {
                    133: #ifndef HAVE_WCHAR
                    134:        return ERR;
                    135: #else
                    136:        __LDATA  *start, *temp1, *temp2;
                    137:        __LINE    *lnp;
                    138:        const wchar_t *scp;
1.11      roy       139:        int width, len, sx, x, y, cw, pcw, newx;
1.1       blymn     140:        nschar_t *np;
                    141:        wchar_t ws[] = L"               ";
                    142:
                    143:        /* check for leading non-spacing character */
                    144:        if (!wstr)
                    145:                return OK;
                    146:        cw = wcwidth(*wstr);
1.5       drochner  147:        if (cw < 0)
                    148:                cw = 1;
1.1       blymn     149:        if (!cw)
                    150:                return ERR;
                    151:
                    152:        scp = wstr + 1;
                    153:        width = cw;
                    154:        len = 1;
                    155:        n--;
                    156:        while (*scp) {
1.5       drochner  157:                int w;
1.1       blymn     158:                if (!n)
                    159:                        break;
1.5       drochner  160:                w = wcwidth(*scp);
                    161:                if (w < 0)
                    162:                        w = 1;
                    163:                n--, len++, width += w;
1.1       blymn     164:                scp++;
                    165:        }
                    166: #ifdef DEBUG
1.2       blymn     167:        __CTRACE(__CTRACE_INPUT, "wins_nwstr: width=%d,len=%d\n", width, len);
1.1       blymn     168: #endif /* DEBUG */
                    169:
                    170:        if (cw > win->maxx - win->curx + 1)
                    171:                return ERR;
1.4       roy       172:        start = &win->alines[win->cury]->line[win->curx];
1.1       blymn     173:        sx = win->curx;
1.4       roy       174:        lnp = win->alines[win->cury];
1.1       blymn     175:        pcw = WCOL(*start);
                    176:        if (pcw < 0) {
                    177:                sx += pcw;
                    178:                start += pcw;
                    179:        }
                    180: #ifdef DEBUG
1.2       blymn     181:        __CTRACE(__CTRACE_INPUT, "wins_nwstr: start@(%d)\n", sx);
1.1       blymn     182: #endif /* DEBUG */
                    183:        pcw = WCOL(*start);
                    184:        lnp->flags |= __ISDIRTY;
                    185:        newx = sx + win->ch_off;
                    186:        if (newx < *lnp->firstchp)
                    187:                *lnp->firstchp = newx;
                    188: #ifdef DEBUG
                    189:        {
1.2       blymn     190:                __CTRACE(__CTRACE_INPUT, "========before=======\n");
1.1       blymn     191:                for (x = 0; x < win->maxx; x++)
1.2       blymn     192:                        __CTRACE(__CTRACE_INPUT,
                    193:                            "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
                    194:                            (int) win->cury, x,
1.4       roy       195:                            win->alines[win->cury]->line[x].ch,
                    196:                            win->alines[win->cury]->line[x].attr,
                    197:                            win->alines[win->cury]->line[x].nsp);
1.1       blymn     198:        }
                    199: #endif /* DEBUG */
                    200:
                    201:        /* shift all complete characters */
                    202:        if (sx + width + pcw <= win->maxx) {
                    203: #ifdef DEBUG
1.2       blymn     204:                __CTRACE(__CTRACE_INPUT, "wins_nwstr: shift all characters\n");
1.1       blymn     205: #endif /* DEBUG */
1.4       roy       206:                temp1 = &win->alines[win->cury]->line[win->maxx - 1];
1.1       blymn     207:                temp2 = temp1 - width;
                    208:                pcw = WCOL(*(temp2 + 1));
                    209:                if (pcw < 0) {
                    210: #ifdef DEBUG
1.2       blymn     211:                        __CTRACE(__CTRACE_INPUT,
                    212:                            "wins_nwstr: clear from %d to EOL(%d)\n",
                    213:                            win->maxx + pcw, win->maxx - 1);
1.1       blymn     214: #endif /* DEBUG */
                    215:                        temp2 += pcw;
                    216:                        while (temp1 > temp2 + width) {
                    217:                                temp1->ch = (wchar_t)btowc((int) win->bch);
                    218:                                if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR)
                    219:                                        return ERR;
                    220:                                temp1->attr = win->battr;
                    221:                                SET_WCOL(*temp1, 1);
                    222: #ifdef DEBUG
1.2       blymn     223:                                __CTRACE(__CTRACE_INPUT,
                    224:                                    "wins_nwstr: empty cell(%p)\n", temp1);
1.1       blymn     225: #endif /* DEBUG */
                    226:                                temp1--;
                    227:                        }
                    228:                }
                    229:                while (temp2 >= start) {
                    230:                        (void)memcpy(temp1, temp2, sizeof(__LDATA));
                    231:                        temp1--, temp2--;
                    232:                }
                    233: #ifdef DEBUG
                    234:                {
1.2       blymn     235:                        __CTRACE(__CTRACE_INPUT, "=====after shift====\n");
1.1       blymn     236:                        for (x = 0; x < win->maxx; x++)
1.2       blymn     237:                                __CTRACE(__CTRACE_INPUT,
                    238:                                    "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
                    239:                                    (int) win->cury, x,
1.4       roy       240:                                    win->alines[win->cury]->line[x].ch,
                    241:                                    win->alines[win->cury]->line[x].attr,
                    242:                                    win->alines[win->cury]->line[x].nsp);
1.1       blymn     243:                }
                    244: #endif /* DEBUG */
                    245:        }
                    246:
                    247:        /* update string columns */
                    248:        x = win->curx;
                    249:        y = win->cury;
                    250:        for (scp = wstr, temp1 = start; len; len--, scp++) {
                    251:                switch (*scp) {
                    252:                        case L'\b':
                    253:                                if (--x < 0)
                    254:                                        x = 0;
                    255:                                win->curx = x;
                    256:                                continue;;
                    257:                        case L'\r':
                    258:                                win->curx = 0;
                    259:                                continue;
                    260:                        case L'\n':
                    261:                                wclrtoeol(win);
                    262:                                if (y == win->scr_b) {
                    263:                                        if (!(win->flags & __SCROLLOK))
                    264:                                                return ERR;
                    265:                                        scroll(win);
                    266:                                }
                    267:                                continue;
                    268:                        case L'\t':
                    269:                                if (wins_nwstr(win, ws,
1.11      roy       270:                                    min(win->maxx - x, TABSIZE - (x % TABSIZE)))
1.7       roy       271:                                    == ERR)
1.1       blymn     272:                                        return ERR;
                    273:                                continue;
                    274:                }
                    275:                cw = wcwidth(*scp);
1.5       drochner  276:                if (cw < 0)
                    277:                        cw = 1;
1.1       blymn     278:                if (cw) {
                    279:                        /* 1st column */
                    280:                        temp1->ch = (wchar_t)*scp;
                    281:                        temp1->attr = win->wattr;
                    282:                        SET_WCOL(*temp1, cw);
                    283:                        temp1->nsp = NULL;
                    284: #ifdef DEBUG
1.2       blymn     285:                        __CTRACE(__CTRACE_INPUT,
                    286:                            "wins_nwstr: add spacing char(%x)\n", temp1->ch);
1.1       blymn     287: #endif /* DEBUG */
                    288:                        temp2 = temp1++;
                    289:                        if (cw > 1) {
                    290:                                x = -1;
                    291:                                while (temp1 < temp2 + cw) {
                    292:                                        /* the rest columns */
                    293:                                        temp1->ch = (wchar_t)*scp;
                    294:                                        temp1->attr = win->wattr;
                    295:                                        temp1->nsp = NULL;
                    296:                                        SET_WCOL(*temp1, x);
                    297:                                        temp1++, x--;
                    298:                                }
                    299:                                temp1--;
                    300:                        }
                    301:                } else {
                    302:                        /* non-spacing character */
1.8       christos  303:                        np = malloc(sizeof(nschar_t));
1.1       blymn     304:                        if (!np)
                    305:                                return ERR;
                    306:                        np->ch = *scp;
                    307:                        np->next = temp1->nsp;
                    308:                        temp1->nsp = np;
                    309: #ifdef DEBUG
1.2       blymn     310:                        __CTRACE(__CTRACE_INPUT,
                    311:                            "wins_nstr: add non-spacing char(%x)\n", np->ch);
1.1       blymn     312: #endif /* DEBUG */
                    313:                }
                    314:        }
                    315: #ifdef DEBUG
                    316:        {
1.2       blymn     317:                __CTRACE(__CTRACE_INPUT, "========after=======\n");
1.1       blymn     318:                for (x = 0; x < win->maxx; x++)
1.2       blymn     319:                        __CTRACE(__CTRACE_INPUT,
                    320:                            "wins_nwstr: (%d,%d)=(%x,%x,%p)\n",
                    321:                            (int) win->cury, x,
1.4       roy       322:                            win->alines[win->cury]->line[x].ch,
                    323:                            win->alines[win->cury]->line[x].attr,
                    324:                            win->alines[win->cury]->line[x].nsp);
1.1       blymn     325:        }
                    326: #endif /* DEBUG */
                    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);
1.9       roy       331:        __sync(win);
1.1       blymn     332:        return OK;
                    333: #endif /* HAVE_WCHAR */
                    334: }

CVSweb <webmaster@jp.NetBSD.org>