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 /* Copyright (c) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright (c) 1997, by Sun Microsystems, Inc. 28 * All rights reserved. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /*LINTLIBRARY*/ 34 35 #include <sys/types.h> 36 #include "curses_inc.h" 37 38 #define LENGTH 256 39 40 /* This routine gets a string starting at (_cury, _curx) */ 41 int 42 wgetwstr(WINDOW *win, wchar_t *str) 43 { 44 return ((wgetnwstr(win, str, LENGTH) == ERR) ? ERR : OK); 45 } 46 47 int 48 wgetnwstr(WINDOW *win, wchar_t *str, int n) 49 { 50 int cpos = 0, ch; 51 wchar_t *cp = str; 52 int i = 0; 53 int total = 0; 54 char myerase, mykill; 55 char rownum[LENGTH], colnum[LENGTH], length[LENGTH]; 56 int doecho = SP->fl_echoit; 57 int savecb = cur_term->_fl_rawmode; 58 bool savsync, savimmed, savleave; 59 60 #ifdef DEBUG 61 if (outf) 62 fprintf(outf, "doecho %d, savecb %d\n", doecho, savecb); 63 #endif /* DEBUG */ 64 65 myerase = erasechar(); 66 mykill = killchar(); 67 if (!savecb) 68 (void) cbreak(); 69 70 if (doecho) { 71 SP->fl_echoit = FALSE; 72 savsync = win->_sync; 73 savimmed = win->_immed; 74 savleave = win->_leave; 75 win->_immed = win->_sync = win->_leave = FALSE; 76 (void) wrefresh(win); 77 if (n > LENGTH) 78 n = LENGTH; 79 } 80 n--; 81 82 while (cpos < n) { 83 if (doecho) { 84 rownum[cpos] = win->_cury; 85 colnum[cpos] = win->_curx; 86 } 87 88 ch = wgetwch(win); 89 if ((ch == ERR) || (ch == '\n') || (ch == '\r') || 90 (ch == KEY_ENTER)) 91 break; 92 if ((ch == myerase) || (ch == KEY_LEFT) || 93 (ch == KEY_BACKSPACE) || (ch == mykill)) { 94 if (cpos > 0) { 95 if (ch == mykill) { 96 i = total; 97 total = cpos = 0; 98 cp = str; 99 } else { 100 cp--; 101 cpos--; 102 if (doecho) 103 total -= (i = length[cpos]); 104 } 105 if (doecho) { 106 (void) wmove(win, rownum[cpos], 107 colnum[cpos]); 108 /* Add the correct amount of blanks. */ 109 for (; i > 0; i--) 110 (void) waddch(win, ' '); 111 /* Move back after the blanks */ 112 /* are put in. */ 113 (void) wmove(win, rownum[cpos], 114 colnum[cpos]); 115 /* Update total. */ 116 (void) wrefresh(win); 117 } 118 } else 119 if (doecho) 120 (void) beep(); 121 } else 122 if ((KEY_MIN <= ch) && (ch <= KEY_MAX)) 123 (void) beep(); 124 else { 125 *cp++ = ch; 126 if (doecho) { 127 /* Add the length of the */ 128 /* character to total. */ 129 if ((ch & EUCMASK) != P00) 130 length[cpos] = wcscrw(ch); 131 else if (ch >= ' ') 132 length[cpos] = 1; 133 else if (ch == '\t') 134 length[cpos] = TABSIZE - 135 (colnum[cpos] % TABSIZE); 136 else 137 length[cpos] = 2; 138 total += length[cpos]; 139 (void) wechowchar(win, (chtype) ch); 140 } 141 cpos++; 142 } 143 } 144 145 *cp = '\0'; 146 147 if (!savecb) 148 (void) nocbreak(); 149 /* 150 * The following code is equivalent to waddch(win, '\n') 151 * except that it does not do a wclrtoeol. 152 */ 153 if (doecho) { 154 SP->fl_echoit = TRUE; 155 win->_curx = 0; 156 if (win->_cury + 1 > win->_bmarg) 157 (void) wscrl(win, 1); 158 else 159 win->_cury++; 160 161 win->_sync = savsync; 162 win->_immed = savimmed; 163 win->_leave = savleave; 164 (void) wrefresh(win); 165 } 166 return (ch); 167 } 168