2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/* Copyright (c) 1988 AT&T */
2N/A/* All Rights Reserved */
2N/A
2N/A/*
2N/A * University Copyright- Copyright (c) 1982, 1986, 1988
2N/A * The Regents of the University of California
2N/A * All Rights Reserved
2N/A *
2N/A * University Acknowledgment- Portions of this document are derived from
2N/A * software developed by the University of California, Berkeley, and its
2N/A * contributors.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*LINTLIBRARY*/
2N/A
2N/A#include <sys/types.h>
2N/A#include "curses_inc.h"
2N/A
2N/A#define LENGTH 256
2N/A
2N/A/* This routine gets a string starting at (_cury, _curx) */
2N/A
2N/Aint
2N/Awgetstr(WINDOW *win, char *str)
2N/A{
2N/A return ((wgetnstr(win, str, LENGTH) == ERR) ? ERR : OK);
2N/A}
2N/A
2N/Aint
2N/Awgetnstr(WINDOW *win, char *str, int n)
2N/A{
2N/A int cpos = 0, ch;
2N/A int nbyte = 0;
2N/A int tbyte = 0;
2N/A int byte[LENGTH];
2N/A int eucw, scrw;
2N/A int docont = 0;
2N/A char *cp = str;
2N/A int i = 0;
2N/A int total = 0;
2N/A char myerase, mykill;
2N/A char rownum[LENGTH], colnum[LENGTH], length[LENGTH];
2N/A int doecho = SP->fl_echoit;
2N/A int savecb = cur_term->_fl_rawmode;
2N/A bool savsync, savimmed, savleave;
2N/A
2N/A#ifdef DEBUG
2N/A if (outf)
2N/A fprintf(outf, "doecho %d, savecb %d\n", doecho, savecb);
2N/A#endif /* DEBUG */
2N/A
2N/A myerase = erasechar();
2N/A mykill = killchar();
2N/A if (!savecb)
2N/A (void) cbreak();
2N/A
2N/A if (doecho) {
2N/A SP->fl_echoit = FALSE;
2N/A savsync = win->_sync;
2N/A savimmed = win->_immed;
2N/A savleave = win->_leave;
2N/A win->_immed = win->_sync = win->_leave = FALSE;
2N/A (void) wrefresh(win);
2N/A if (n > LENGTH)
2N/A n = LENGTH;
2N/A }
2N/A n--;
2N/A
2N/A while (nbyte < n) {
2N/A if (doecho && !docont) {
2N/A rownum[cpos] = win->_cury;
2N/A colnum[cpos] = win->_curx;
2N/A }
2N/A
2N/A ch = wgetch(win);
2N/A if (docont)
2N/A goto cont;
2N/A
2N/A if ((ch == ERR) || (ch == '\n') || (ch == '\r') ||
2N/A (ch == KEY_ENTER))
2N/A break;
2N/A if ((ch == myerase) || (ch == KEY_LEFT) ||
2N/A (ch == KEY_BACKSPACE) || (ch == mykill)) {
2N/A if (cpos > 0) {
2N/A if (ch == mykill) {
2N/A i = total;
2N/A total = cpos = 0;
2N/A nbyte = 0;
2N/A cp = str;
2N/A } else {
2N/A cpos--;
2N/A cp -= byte[cpos];
2N/A if (doecho)
2N/A total -= (i = length[cpos]);
2N/A }
2N/A if (doecho) {
2N/A (void) wmove(win, rownum[cpos],
2N/A colnum[cpos]);
2N/A /* Add the correct amount of blanks. */
2N/A for (; i > 0; i--)
2N/A (void) waddch(win, ' ');
2N/A /* Move back after the blanks are */
2N/A /* put in. */
2N/A (void) wmove(win, rownum[cpos],
2N/A colnum[cpos]);
2N/A /* Update total. */
2N/A (void) wrefresh(win);
2N/A }
2N/A } else
2N/A if (doecho)
2N/A (void) beep();
2N/A } else if ((KEY_MIN <= ch) && (ch <= KEY_MAX))
2N/A (void) beep();
2N/A else {
2N/Acont:
2N/A /* LINTED */
2N/A *cp++ = (char)ch;
2N/A if (docont) {
2N/A tbyte++;
2N/A } else if (ISMBIT(ch)) {
2N/A docont = 1;
2N/A tbyte = 1;
2N/A scrw = mbscrw(ch);
2N/A eucw = mbeucw(ch);
2N/A }
2N/A
2N/A if (docont && (tbyte >= eucw)) {
2N/A docont = 0;
2N/A tbyte = 0;
2N/A if (doecho) {
2N/A byte[cpos] = eucw;
2N/A /* LINTED */
2N/A length[cpos] = (char)scrw;
2N/A (void) wechochar(win,
2N/A (chtype) ch);
2N/A }
2N/A } else if (doecho) {
2N/A /* Add the length of the */
2N/A /* character to total. */
2N/A byte[cpos] = 1;
2N/A if (ch >= ' ')
2N/A length[cpos] = 1;
2N/A else
2N/A if (ch == '\t')
2N/A length[cpos] = TABSIZE-
2N/A (colnum[cpos] %
2N/A TABSIZE);
2N/A else
2N/A length[cpos] = 2;
2N/A total += length[cpos];
2N/A (void) wechochar(win, (chtype) ch);
2N/A }
2N/A if (!docont)
2N/A cpos++;
2N/A nbyte++;
2N/A }
2N/A }
2N/A
2N/A *cp = '\0';
2N/A
2N/A if (!savecb)
2N/A (void) nocbreak();
2N/A /*
2N/A * The following code is equivalent to waddch(win, '\n')
2N/A * except that it does not do a wclrtoeol.
2N/A */
2N/A if (doecho) {
2N/A SP->fl_echoit = TRUE;
2N/A win->_curx = 0;
2N/A if (win->_cury + 1 > win->_bmarg)
2N/A (void) wscrl(win, 1);
2N/A else
2N/A win->_cury++;
2N/A
2N/A win->_sync = savsync;
2N/A win->_immed = savimmed;
2N/A win->_leave = savleave;
2N/A (void) wrefresh(win);
2N/A }
2N/A return (ch);
2N/A}