1*6348e3f3Sblymn /* $NetBSD: insstr.c,v 1.12 2024/12/23 02:58:03 blymn Exp $ */ 2fa0b432bSblymn 3fa0b432bSblymn /* 4fa0b432bSblymn * Copyright (c) 2005 The NetBSD Foundation Inc. 5fa0b432bSblymn * All rights reserved. 6fa0b432bSblymn * 7fa0b432bSblymn * This code is derived from code donated to the NetBSD Foundation 8fa0b432bSblymn * by Ruibiao Qiu <ruibiao@arl.wustl.edu,ruibiao@gmail.com>. 9fa0b432bSblymn * 10fa0b432bSblymn * 11fa0b432bSblymn * Redistribution and use in source and binary forms, with or without 12fa0b432bSblymn * modification, are permitted provided that the following conditions 13fa0b432bSblymn * are met: 14fa0b432bSblymn * 1. Redistributions of source code must retain the above copyright 15fa0b432bSblymn * notice, this list of conditions and the following disclaimer. 16fa0b432bSblymn * 2. Redistributions in binary form must reproduce the above copyright 17fa0b432bSblymn * notice, this list of conditions and the following disclaimer in the 18fa0b432bSblymn * documentation and/or other materials provided with the distribution. 19fa0b432bSblymn * 3. Neither the name of the NetBSD Foundation nor the names of its 20fa0b432bSblymn * contributors may be used to endorse or promote products derived 21fa0b432bSblymn * from this software without specific prior written permission. 22fa0b432bSblymn * 23fa0b432bSblymn * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 24fa0b432bSblymn * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 25fa0b432bSblymn * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26fa0b432bSblymn * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27fa0b432bSblymn * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28fa0b432bSblymn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29fa0b432bSblymn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30fa0b432bSblymn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31fa0b432bSblymn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32fa0b432bSblymn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33fa0b432bSblymn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34fa0b432bSblymn * SUCH DAMAGE. 35fa0b432bSblymn */ 36fa0b432bSblymn 37fa0b432bSblymn #include <sys/cdefs.h> 38fa0b432bSblymn #ifndef lint 39*6348e3f3Sblymn __RCSID("$NetBSD: insstr.c,v 1.12 2024/12/23 02:58:03 blymn Exp $"); 40fa0b432bSblymn #endif /* not lint */ 41fa0b432bSblymn 42fa0b432bSblymn #include <string.h> 43fa0b432bSblymn #include <stdlib.h> 44fa0b432bSblymn 45fa0b432bSblymn #include "curses.h" 46fa0b432bSblymn #include "curses_private.h" 47fa0b432bSblymn 48fa0b432bSblymn #ifndef _CURSES_USE_MACROS 49fa0b432bSblymn 50fa0b432bSblymn /* 51fa0b432bSblymn * insstr -- 52fa0b432bSblymn * insert a multi-byte character string into the current window 53fa0b432bSblymn */ 54fa0b432bSblymn int 55fa0b432bSblymn insstr(const char *str) 56fa0b432bSblymn { 5750a63ac8Sroy 58fa0b432bSblymn return winsstr(stdscr, str); 59fa0b432bSblymn } 60fa0b432bSblymn 61fa0b432bSblymn /* 62fa0b432bSblymn * insnstr -- 63fa0b432bSblymn * insert a multi-byte character string into the current window 64fa0b432bSblymn * with at most n characters 65fa0b432bSblymn */ 66fa0b432bSblymn int 67fa0b432bSblymn insnstr(const char *str, int n) 68fa0b432bSblymn { 6950a63ac8Sroy 70fa0b432bSblymn return winsnstr(stdscr, str, n); 71fa0b432bSblymn } 72fa0b432bSblymn 73fa0b432bSblymn /* 74fa0b432bSblymn * mvinsstr -- 75fa0b432bSblymn * Do an insert-string on the line at (y, x). 76fa0b432bSblymn */ 77fa0b432bSblymn int 78fa0b432bSblymn mvinsstr(int y, int x, const char *str) 79fa0b432bSblymn { 8050a63ac8Sroy 81fa0b432bSblymn return mvwinsstr(stdscr, y, x, str); 82fa0b432bSblymn } 83fa0b432bSblymn 84fa0b432bSblymn /* 85fa0b432bSblymn * mvinsnstr -- 86fa0b432bSblymn * Do an insert-n-string on the line at (y, x). 87fa0b432bSblymn */ 88fa0b432bSblymn int 89fa0b432bSblymn mvinsnstr(int y, int x, const char *str, int n) 90fa0b432bSblymn { 9150a63ac8Sroy 92fa0b432bSblymn return mvwinsnstr(stdscr, y, x, str, n); 93fa0b432bSblymn } 94fa0b432bSblymn 95fa0b432bSblymn /* 96fa0b432bSblymn * mvwinsstr -- 97fa0b432bSblymn * Do an insert-string on the line at (y, x) in the given window. 98fa0b432bSblymn */ 99fa0b432bSblymn int 100fa0b432bSblymn mvwinsstr(WINDOW *win, int y, int x, const char *str) 101fa0b432bSblymn { 10250a63ac8Sroy 1032a780e62Sblymn if (wmove(win, y, x) == ERR) 104fa0b432bSblymn return ERR; 105fa0b432bSblymn 106f6dea36dSuwe return winsstr(win, str); 107fa0b432bSblymn } 108fa0b432bSblymn 109fa0b432bSblymn /* 110fa0b432bSblymn * mvwinsnstr -- 111fa0b432bSblymn * Do an insert-n-string on the line at (y, x) in the given window. 112fa0b432bSblymn */ 113fa0b432bSblymn int 114fa0b432bSblymn mvwinsnstr(WINDOW *win, int y, int x, const char *str, int n) 115fa0b432bSblymn { 11650a63ac8Sroy 1172a780e62Sblymn if (wmove(win, y, x) == ERR) 118fa0b432bSblymn return ERR; 119fa0b432bSblymn 120f6dea36dSuwe return winsnstr(win, str, n); 121fa0b432bSblymn } 122fa0b432bSblymn 123fa0b432bSblymn #endif 124fa0b432bSblymn 125fa0b432bSblymn /* 126fa0b432bSblymn * winsstr -- 127fa0b432bSblymn * Do an insert-string on the line, leaving (cury, curx) unchanged. 128fa0b432bSblymn * No wrapping. 129fa0b432bSblymn */ 130fa0b432bSblymn int 131fa0b432bSblymn winsstr(WINDOW *win, const char *str) 132fa0b432bSblymn { 13350a63ac8Sroy 134fa0b432bSblymn return winsnstr(win, str, -1); 135fa0b432bSblymn } 136fa0b432bSblymn 137fa0b432bSblymn /* 138fa0b432bSblymn * winsnstr -- 139fa0b432bSblymn * Do an insert-n-string on the line, leaving (cury, curx) unchanged. 140fa0b432bSblymn * Performs wrapping. 141fa0b432bSblymn */ 142fa0b432bSblymn int 143fa0b432bSblymn winsnstr(WINDOW *win, const char *str, int n) 144fa0b432bSblymn { 145fa0b432bSblymn __LDATA *end, *temp1, *temp2; 146fa0b432bSblymn const char *scp; 147fa0b432bSblymn int len, x; 148fa0b432bSblymn __LINE *lnp; 149fa0b432bSblymn #ifdef HAVE_WCHAR 150fa0b432bSblymn nschar_t *np, *tnp; 151fa0b432bSblymn #endif /* HAVE_WCHAR */ 152fa0b432bSblymn 153*6348e3f3Sblymn if (__predict_false(win == NULL)) 154*6348e3f3Sblymn return ERR; 155*6348e3f3Sblymn 156fa0b432bSblymn /* find string length */ 157fa0b432bSblymn if (n > 0) 158fa0b432bSblymn for (scp = str, len = 0; n-- && *scp++; ++len); 159fa0b432bSblymn else 160fa0b432bSblymn for (scp = str, len = 0; *scp++; ++len); 161e124de36Sblymn __CTRACE(__CTRACE_INPUT, "winsnstr: len = %d\n", len); 162fa0b432bSblymn 163fa0b432bSblymn /* move string */ 16443d5eb45Sroy end = &win->alines[win->cury]->line[win->curx]; 165fa0b432bSblymn if (len < win->maxx - win->curx) { 166e124de36Sblymn __CTRACE(__CTRACE_INPUT, "winsnstr: shift %d cells\n", len); 16743d5eb45Sroy temp1 = &win->alines[win->cury]->line[win->maxx - 1]; 168fa0b432bSblymn temp2 = temp1 - len; 169fa0b432bSblymn while (temp2 >= end) { 170fa0b432bSblymn #ifdef HAVE_WCHAR 171fa0b432bSblymn np = temp1->nsp; 172fa0b432bSblymn if (np){ 173fa0b432bSblymn while (np) { 174fa0b432bSblymn tnp = np->next; 175fa0b432bSblymn free(np); 176fa0b432bSblymn np = tnp; 177fa0b432bSblymn } 178fa0b432bSblymn temp1->nsp = NULL; 179fa0b432bSblymn } 180fa0b432bSblymn #endif /* HAVE_WCHAR */ 181fa0b432bSblymn (void)memcpy(temp1, temp2, sizeof(__LDATA)); 182fa0b432bSblymn temp1--, temp2--; 183fa0b432bSblymn } 184fa0b432bSblymn } 185fa0b432bSblymn 186fa0b432bSblymn for (scp = str, temp1 = end, x = win->curx; 187fa0b432bSblymn *scp && x < len + win->curx && x < win->maxx; 18850a63ac8Sroy scp++, temp1++, x++) 18950a63ac8Sroy { 190fa0b432bSblymn temp1->ch = (wchar_t)*scp & __CHARTEXT; 191fa0b432bSblymn temp1->attr = win->wattr; 192ee6c5161Sblymn temp1->cflags &= ~CA_BACKGROUND; 193ee6c5161Sblymn temp1->cflags &= ~CA_CONTINUATION; 194fa0b432bSblymn #ifdef HAVE_WCHAR 195f1942931Sblymn temp1->wcols = 1; 196fa0b432bSblymn #endif /* HAVE_WCHAR */ 197fa0b432bSblymn } 198fa0b432bSblymn #ifdef DEBUG 199fa0b432bSblymn { 200fa0b432bSblymn int i; 201fa0b432bSblymn 202fa0b432bSblymn for (i = win->curx; i < win->curx + len; i++) { 203e124de36Sblymn __CTRACE(__CTRACE_INPUT, 204e124de36Sblymn "winsnstr: (%d,%d)=('%c',%x)\n", win->cury, i, 20543d5eb45Sroy win->alines[win->cury]->line[i].ch, 20643d5eb45Sroy win->alines[win->cury]->line[i].attr); 207fa0b432bSblymn } 208fa0b432bSblymn } 209fa0b432bSblymn #endif /* DEBUG */ 21043d5eb45Sroy lnp = win->alines[win->cury]; 211fa0b432bSblymn lnp->flags |= __ISDIRTY; 212fa0b432bSblymn if (win->ch_off < *lnp->firstchp) 213fa0b432bSblymn *lnp->firstchp = win->ch_off; 214fa0b432bSblymn if (win->ch_off + win->maxx - 1 > *lnp->lastchp) 215fa0b432bSblymn *lnp->lastchp = win->ch_off + win->maxx - 1; 216fa0b432bSblymn __touchline(win, (int)win->cury, (int)win->curx, (int)win->maxx - 1); 2171369811dSroy __sync(win); 218fa0b432bSblymn return OK; 219fa0b432bSblymn } 220