1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /*LINTLIBRARY*/ 43 44 #include <sys/types.h> 45 #include "curses_inc.h" 46 47 /* 48 * Insert to 'win' at most n chars of a string 49 * starting at (cury, curx). However, if n <= 0, 50 * insert the entire string. 51 * \n, \t, \r, \b are treated in the same way 52 * as other control chars. 53 */ 54 55 int 56 winsnstr(WINDOW *win, char *tsp, int n) 57 { 58 chtype *wcp; 59 int x, cury, endx, maxx, len; 60 bool savscrl, savsync, savimmed; 61 short savx, savy; 62 unsigned char *sp = (unsigned char *)tsp; 63 64 /* only insert at the start of a character */ 65 win->_nbyte = -1; 66 win->_insmode = TRUE; 67 if (_scrmax > 1 && _mbvalid(win) == ERR) 68 return (ERR); 69 70 if (n < 0) 71 n = MAXINT; 72 73 /* compute total length of the insertion */ 74 endx = win->_curx; 75 maxx = win->_maxx; 76 for (x = 0; sp[x] != '\0' && x < n && endx < maxx; ++x) { 77 len = (sp[x] < ' '|| sp[x] == _CTRL('?')) ? 2 : 1; 78 79 if (ISMBIT(sp[x])) { 80 int m, k, ty; 81 chtype c; 82 83 /* see if the entire character is defined */ 84 c = RBYTE(sp[x]); 85 ty = TYPE(c); 86 m = x + cswidth[ty] - (ty == 0 ? 1 : 0); 87 for (k = x + 1; sp[k] != '\0' && k <= m; ++k) { 88 c = RBYTE(sp[k]); 89 if (TYPE(c) != 0) 90 break; 91 } 92 if (k <= m) 93 break; 94 /* recompute # of columns used */ 95 len = _curs_scrwidth[ty]; 96 /* skip an appropriate number of bytes */ 97 x = m; 98 } 99 100 if ((endx += len) > maxx) { 101 endx -= len; 102 break; 103 } 104 } 105 106 /* length of chars to be shifted */ 107 if ((len = endx - win->_curx) <= 0) 108 return (ERR); 109 110 /* number of chars insertible */ 111 n = x; 112 113 /* shift data */ 114 cury = win->_cury; 115 116 if (_mbinsshift(win, len) == ERR) 117 return (ERR); 118 119 /* insert new data */ 120 wcp = win->_y[cury] + win->_curx; 121 122 /* act as if we are adding characters */ 123 savx = win->_curx; 124 savy = win->_cury; 125 win->_insmode = FALSE; 126 savscrl = win->_scroll; 127 savimmed = win->_immed; 128 savsync = win->_sync; 129 win->_scroll = win->_sync; 130 131 for (; n > 0; --n, ++sp) { 132 /* multi-byte characters */ 133 if (_mbtrue && ISMBIT(*sp)) { 134 (void) _mbaddch(win, A_NORMAL, RBYTE(*sp)); 135 wcp = win->_y[cury] + win->_curx; 136 continue; 137 } 138 if (_scrmax > 1 && ISMBIT(*wcp)) 139 (void) _mbclrch(win, cury, win->_curx); 140 /* single byte character */ 141 win->_nbyte = -1; 142 143 if (*sp < ' ' || *sp == _CTRL('?')) { 144 *wcp++ = _CHAR('^') | win->_attrs; 145 *wcp = _CHAR(_UNCTRL(*sp)) | win->_attrs; 146 } else 147 *wcp = _CHAR(*sp) | win->_attrs; 148 win->_curx += (*sp < ' ' || *sp == _CTRL('?')) ? 2 : 1; 149 ++wcp; 150 } 151 win->_curx = savx; 152 win->_cury = savy; 153 154 /* update the change structure */ 155 if (win->_firstch[cury] > win->_curx) 156 win->_firstch[cury] = win->_curx; 157 win->_lastch[cury] = maxx - 1; 158 159 win->_flags |= _WINCHANGED; 160 161 win->_scroll = savscrl; 162 win->_sync = savsync; 163 win->_immed = savimmed; 164 165 if (win->_sync) 166 wsyncup(win); 167 return (win->_immed ? wrefresh(win) : OK); 168 } 169