/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1997 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ /*LINTLIBRARY*/ #include #include "curses_inc.h" /* * Insert to 'win' at most n chars of a string * starting at (cury, curx). However, if n <= 0, * insert the entire string. * \n, \t, \r, \b are treated in the same way * as other control chars. */ int winsnstr(WINDOW *win, char *tsp, int n) { chtype *wcp; int x, cury, endx, maxx, len; bool savscrl, savsync, savimmed; short savx, savy; unsigned char *sp = (unsigned char *)tsp; /* only insert at the start of a character */ win->_nbyte = -1; win->_insmode = TRUE; if (_scrmax > 1 && _mbvalid(win) == ERR) return (ERR); if (n < 0) n = MAXINT; /* compute total length of the insertion */ endx = win->_curx; maxx = win->_maxx; for (x = 0; sp[x] != '\0' && x < n && endx < maxx; ++x) { len = (sp[x] < ' '|| sp[x] == _CTRL('?')) ? 2 : 1; if (ISMBIT(sp[x])) { int m, k, ty; chtype c; /* see if the entire character is defined */ c = RBYTE(sp[x]); ty = TYPE(c); m = x + cswidth[ty] - (ty == 0 ? 1 : 0); for (k = x + 1; sp[k] != '\0' && k <= m; ++k) { c = RBYTE(sp[k]); if (TYPE(c) != 0) break; } if (k <= m) break; /* recompute # of columns used */ len = _curs_scrwidth[ty]; /* skip an appropriate number of bytes */ x = m; } if ((endx += len) > maxx) { endx -= len; break; } } /* length of chars to be shifted */ if ((len = endx - win->_curx) <= 0) return (ERR); /* number of chars insertible */ n = x; /* shift data */ cury = win->_cury; if (_mbinsshift(win, len) == ERR) return (ERR); /* insert new data */ wcp = win->_y[cury] + win->_curx; /* act as if we are adding characters */ savx = win->_curx; savy = win->_cury; win->_insmode = FALSE; savscrl = win->_scroll; savimmed = win->_immed; savsync = win->_sync; win->_scroll = win->_sync; for (; n > 0; --n, ++sp) { /* multi-byte characters */ if (_mbtrue && ISMBIT(*sp)) { (void) _mbaddch(win, A_NORMAL, RBYTE(*sp)); wcp = win->_y[cury] + win->_curx; continue; } if (_scrmax > 1 && ISMBIT(*wcp)) (void) _mbclrch(win, cury, win->_curx); /* single byte character */ win->_nbyte = -1; if (*sp < ' ' || *sp == _CTRL('?')) { *wcp++ = _CHAR('^') | win->_attrs; *wcp = _CHAR(_UNCTRL(*sp)) | win->_attrs; } else *wcp = _CHAR(*sp) | win->_attrs; win->_curx += (*sp < ' ' || *sp == _CTRL('?')) ? 2 : 1; ++wcp; } win->_curx = savx; win->_cury = savy; /* update the change structure */ if (win->_firstch[cury] > win->_curx) win->_firstch[cury] = win->_curx; win->_lastch[cury] = maxx - 1; win->_flags |= _WINCHANGED; win->_scroll = savscrl; win->_sync = savsync; win->_immed = savimmed; if (win->_sync) wsyncup(win); return (win->_immed ? wrefresh(win) : OK); }