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

Annotation of src/lib/libcurses/ins_wch.c, Revision 1.13

1.13    ! blymn       1: /*   $NetBSD: ins_wch.c,v 1.12 2018/11/22 22:16:45 uwe 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.13    ! blymn      39: __RCSID("$NetBSD: ins_wch.c,v 1.12 2018/11/22 22:16:45 uwe 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_wch --
                     50:  *     Do an insert-char on the line, leaving (cury, curx) unchanged.
                     51:  */
                     52: int
                     53: ins_wch(const cchar_t *wch)
                     54: {
                     55:        return wins_wch(stdscr, wch);
                     56: }
                     57:
                     58: /*
                     59:  * mvins_wch --
                     60:  *       Do an insert-char on the line at (y, x).
                     61:  */
                     62: int
                     63: mvins_wch(int y, int x, const cchar_t *wch)
                     64: {
                     65:        return mvwins_wch(stdscr, y, x, wch);
                     66: }
                     67:
                     68: /*
                     69:  * mvwins_wch --
                     70:  *       Do an insert-char on the line at (y, x) in the given window.
                     71:  */
                     72: int
                     73: mvwins_wch(WINDOW *win, int y, int x, const cchar_t *wch)
                     74: {
1.13    ! blymn      75:        if (_cursesi_wmove(win, y, x, 0) == ERR)
1.1       blymn      76:                return ERR;
                     77:
                     78:        return wins_wch(stdscr, wch);
                     79: }
                     80:
                     81: /*
                     82:  * wins_wch --
                     83:  *     Do an insert-char on the line, leaving (cury, curx) unchanged.
                     84:  */
                     85: int
                     86: wins_wch(WINDOW *win, const cchar_t *wch)
                     87: {
                     88:        __LDATA *start, *temp1, *temp2;
                     89:        __LINE *lnp;
1.11      roy        90:        int cw, pcw, x, y, sx, ex, newx, i;
1.1       blymn      91:        nschar_t *np, *tnp;
                     92:        wchar_t ws[] = L"               ";
                     93:
                     94:        /* check for non-spacing characters */
1.9       roy        95:        if (!wch)
1.1       blymn      96:                return OK;
                     97:        cw = wcwidth(wch->vals[0]);
1.5       drochner   98:        if (cw < 0)
                     99:                cw = 1;
1.1       blymn     100:        if (!cw)
                    101:                return wadd_wch( win, wch );
                    102:
                    103: #ifdef DEBUG
1.2       blymn     104:        __CTRACE(__CTRACE_INPUT, "--before--\n");
1.9       roy       105:        for (x = 0; x < win->maxx; x++)
1.2       blymn     106:                __CTRACE(__CTRACE_INPUT, "wins_wch: (0,%d)=(%x,%x,%p)\n", x,
1.4       roy       107:                    win->alines[0]->line[x].ch,
                    108:                    win->alines[0]->line[x].attr,
                    109:                    win->alines[0]->line[x].nsp);
1.1       blymn     110: #endif /* DEBUG */
                    111:        x = win->curx;
                    112:        y = win->cury;
                    113: #ifdef DEBUG
1.2       blymn     114:        __CTRACE(__CTRACE_INPUT, "wins_wch: (%d,%d)\n", y, x);
1.1       blymn     115: #endif /* DEBUG */
1.9       roy       116:        switch (wch->vals[0]) {
1.1       blymn     117:                case L'\b':
1.9       roy       118:                        if (--x < 0)
1.1       blymn     119:                                x = 0;
                    120:                        win->curx = x;
                    121:                        return OK;
                    122:                case L'\r':
                    123:                        win->curx = 0;
                    124:                        return OK;
                    125:                case L'\n':
1.9       roy       126:                        wclrtoeol(win);
1.1       blymn     127:                        if (y == win->scr_b) {
                    128:                                if (!(win->flags & __SCROLLOK))
                    129:                                        return ERR;
                    130:                                scroll(win);
                    131:                        }
                    132:                        return OK;
                    133:                case L'\t':
1.6       roy       134:                        if (wins_nwstr(win, ws, min(win->maxx - x,
1.11      roy       135:                            TABSIZE - (x % TABSIZE))) == ERR)
1.1       blymn     136:                                return ERR;
                    137:                        return OK;
                    138:        }
                    139:
                    140:        /* locate current cell */
                    141:        x = win->curx;
                    142:        y = win->cury;
1.9       roy       143:        lnp = win->alines[y];
                    144:        start = &win->alines[y]->line[x];
1.1       blymn     145:        sx = x;
1.9       roy       146:        pcw = WCOL(*start);
1.1       blymn     147:        if (pcw < 0) {
                    148:                start += pcw;
                    149:                sx += pcw;
                    150:        }
1.9       roy       151:        if (cw > win->maxx - sx)
1.1       blymn     152:                return ERR;
                    153:        lnp->flags |= __ISDIRTY;
                    154:        newx = sx + win->ch_off;
1.9       roy       155:        if (newx < *lnp->firstchp)
1.1       blymn     156:                *lnp->firstchp = newx;
                    157:
                    158:        /* shift all complete characters */
                    159: #ifdef DEBUG
1.2       blymn     160:        __CTRACE(__CTRACE_INPUT, "wins_wch: shift all characters\n");
1.1       blymn     161: #endif /* DEBUG */
1.9       roy       162:        temp1 = &win->alines[y]->line[win->maxx - 1];
1.1       blymn     163:        temp2 = temp1 - cw;
                    164:        pcw = WCOL(*(temp2 + 1));
                    165:        if (pcw < 0) {
                    166: #ifdef DEBUG
1.2       blymn     167:                __CTRACE(__CTRACE_INPUT, "wins_wch: clear EOL\n");
1.1       blymn     168: #endif /* DEBUG */
                    169:                temp2 += pcw;
1.9       roy       170:                while (temp1 > temp2 + cw) {
1.1       blymn     171:                        np = temp1->nsp;
                    172:                        if (np) {
1.9       roy       173:                                while (np) {
1.1       blymn     174:                                        tnp = np->next;
1.9       roy       175:                                        free(np);
1.1       blymn     176:                                        np = tnp;
                    177:                                }
                    178:                                temp1->nsp = NULL;
                    179:                        }
1.9       roy       180:                        temp1->ch = (wchar_t)btowc((int)win->bch );
1.1       blymn     181:                        if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR)
                    182:                                return ERR;
                    183:                        temp1->attr = win->battr;
1.9       roy       184:                        SET_WCOL(*temp1, 1);
1.1       blymn     185:                        temp1--;
                    186:                }
                    187:        }
1.9       roy       188:        while (temp2 >= start) {
                    189:                (void)memcpy(temp1, temp2, sizeof(__LDATA));
1.1       blymn     190:                temp1--, temp2--;
                    191:        }
                    192:
                    193:        /* update character under cursor */
                    194:        start->nsp = NULL;
1.9       roy       195:        start->ch = wch->vals[0];
1.1       blymn     196:        start->attr = wch->attributes & WA_ATTRIBUTES;
1.9       roy       197:        SET_WCOL(*start, cw);
                    198:        if (wch->elements > 1) {
                    199:                for (i = 1; i < wch->elements; i++) {
1.7       christos  200:                        np = malloc(sizeof(nschar_t));
1.1       blymn     201:                        if (!np)
                    202:                                return ERR;
1.9       roy       203:                        np->ch = wch->vals[i];
1.1       blymn     204:                        np->next = start->nsp;
                    205:                        start->nsp = np;
                    206:                }
                    207:        }
                    208: #ifdef DEBUG
1.2       blymn     209:        __CTRACE(__CTRACE_INPUT, "wins_wch: insert (%x,%x,%p)\n",
                    210:            start->ch, start->attr, start->nsp);
1.1       blymn     211: #endif /* DEBUG */
                    212:        temp1 = start + 1;
                    213:        ex = x + 1;
1.9       roy       214:        while (ex - x < cw) {
                    215:                temp1->ch = wch->vals[0];
                    216:                SET_WCOL(*temp1, x - ex);
1.1       blymn     217:                temp1->nsp = NULL;
                    218:                ex++, temp1++;
                    219:        }
                    220: #ifdef DEBUG
                    221:        {
1.2       blymn     222:                __CTRACE(__CTRACE_INPUT, "--after---\n");
1.9       roy       223:                for (x = 0; x < win->maxx; x++)
1.2       blymn     224:                        __CTRACE(__CTRACE_INPUT,
                    225:                            "wins_wch: (0,%d)=(%x,%x,%p)\n", x,
1.4       roy       226:                            win->alines[0]->line[x].ch,
                    227:                            win->alines[0]->line[x].attr,
                    228:                            win->alines[0]->line[x].nsp);
1.1       blymn     229:        }
                    230: #endif /* DEBUG */
                    231:        newx = win->maxx - 1 + win->ch_off;
1.9       roy       232:        if (newx > *lnp->lastchp)
1.1       blymn     233:                *lnp->lastchp = newx;
1.9       roy       234:        __touchline(win, y, sx, (int)win->maxx - 1);
1.8       roy       235:        __sync(win);
1.1       blymn     236:        return OK;
                    237: }

CVSweb <webmaster@jp.NetBSD.org>