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 /*LINTLIBRARY*/ 41 42 #include <sys/types.h> 43 #include "curses_inc.h" 44 45 /* 46 * Insert to 'win' at most n chars of a string 47 * starting at (cury, curx). However, if n <= 0, 48 * insert the entire string. 49 * \n, \t, \r, \b are treated in the same way 50 * as other control chars. 51 */ 52 53 int 54 winsnstr(WINDOW *win, char *tsp, int n) 55 { 56 chtype *wcp; 57 int x, cury, endx, maxx, len; 58 bool savscrl, savsync, savimmed; 59 short savx, savy; 60 unsigned char *sp = (unsigned char *)tsp; 61 62 /* only insert at the start of a character */ 63 win->_nbyte = -1; 64 win->_insmode = TRUE; 65 if (_scrmax > 1 && _mbvalid(win) == ERR) 66 return (ERR); 67 68 if (n < 0) 69 n = MAXINT; 70 71 /* compute total length of the insertion */ 72 endx = win->_curx; 73 maxx = win->_maxx; 74 for (x = 0; sp[x] != '\0' && x < n && endx < maxx; ++x) { 75 len = (sp[x] < ' '|| sp[x] == _CTRL('?')) ? 2 : 1; 76 77 if (ISMBIT(sp[x])) { 78 int m, k, ty; 79 chtype c; 80 81 /* see if the entire character is defined */ 82 c = RBYTE(sp[x]); 83 ty = TYPE(c); 84 m = x + cswidth[ty] - (ty == 0 ? 1 : 0); 85 for (k = x + 1; sp[k] != '\0' && k <= m; ++k) { 86 c = RBYTE(sp[k]); 87 if (TYPE(c) != 0) 88 break; 89 } 90 if (k <= m) 91 break; 92 /* recompute # of columns used */ 93 len = _curs_scrwidth[ty]; 94 /* skip an appropriate number of bytes */ 95 x = m; 96 } 97 98 if ((endx += len) > maxx) { 99 endx -= len; 100 break; 101 } 102 } 103 104 /* length of chars to be shifted */ 105 if ((len = endx - win->_curx) <= 0) 106 return (ERR); 107 108 /* number of chars insertible */ 109 n = x; 110 111 /* shift data */ 112 cury = win->_cury; 113 114 if (_mbinsshift(win, len) == ERR) 115 return (ERR); 116 117 /* insert new data */ 118 wcp = win->_y[cury] + win->_curx; 119 120 /* act as if we are adding characters */ 121 savx = win->_curx; 122 savy = win->_cury; 123 win->_insmode = FALSE; 124 savscrl = win->_scroll; 125 savimmed = win->_immed; 126 savsync = win->_sync; 127 win->_scroll = win->_sync; 128 129 for (; n > 0; --n, ++sp) { 130 /* multi-byte characters */ 131 if (_mbtrue && ISMBIT(*sp)) { 132 (void) _mbaddch(win, A_NORMAL, RBYTE(*sp)); 133 wcp = win->_y[cury] + win->_curx; 134 continue; 135 } 136 if (_scrmax > 1 && ISMBIT(*wcp)) 137 (void) _mbclrch(win, cury, win->_curx); 138 /* single byte character */ 139 win->_nbyte = -1; 140 141 if (*sp < ' ' || *sp == _CTRL('?')) { 142 *wcp++ = _CHAR('^') | win->_attrs; 143 *wcp = _CHAR(_UNCTRL(*sp)) | win->_attrs; 144 } else 145 *wcp = _CHAR(*sp) | win->_attrs; 146 win->_curx += (*sp < ' ' || *sp == _CTRL('?')) ? 2 : 1; 147 ++wcp; 148 } 149 win->_curx = savx; 150 win->_cury = savy; 151 152 /* update the change structure */ 153 if (win->_firstch[cury] > win->_curx) 154 win->_firstch[cury] = win->_curx; 155 win->_lastch[cury] = maxx - 1; 156 157 win->_flags |= _WINCHANGED; 158 159 win->_scroll = savscrl; 160 win->_sync = savsync; 161 win->_immed = savimmed; 162 163 if (win->_sync) 164 wsyncup(win); 165 return (win->_immed ? wrefresh(win) : OK); 166 } 167