17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bdstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bdstevel@tonic-gate * with the License.
87c478bdstevel@tonic-gate *
97c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bdstevel@tonic-gate * See the License for the specific language governing permissions
127c478bdstevel@tonic-gate * and limitations under the License.
137c478bdstevel@tonic-gate *
147c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bdstevel@tonic-gate *
207c478bdstevel@tonic-gate * CDDL HEADER END
217c478bdstevel@tonic-gate */
227c478bdstevel@tonic-gate/*
237c478bdstevel@tonic-gate * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
247c478bdstevel@tonic-gate * Use is subject to license terms.
2548bbca8Daniel Hoffman * Copyright (c) 2016 by Delphix. All rights reserved.
267c478bdstevel@tonic-gate */
277c478bdstevel@tonic-gate
287c478bdstevel@tonic-gate/*	Copyright (c) 1988 AT&T	*/
297c478bdstevel@tonic-gate/*	  All Rights Reserved  	*/
307c478bdstevel@tonic-gate
317c478bdstevel@tonic-gate/* Copyright (c) 1979 Regents of the University of California */
327c478bdstevel@tonic-gate
337c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
347c478bdstevel@tonic-gate
357c478bdstevel@tonic-gate/*LINTLIBRARY*/
367c478bdstevel@tonic-gate
377c478bdstevel@tonic-gate#include	<sys/types.h>
387c478bdstevel@tonic-gate#include	<ctype.h>
397c478bdstevel@tonic-gate#include	"curses_inc.h"
407c478bdstevel@tonic-gate
417c478bdstevel@tonic-gate/*
427c478bdstevel@tonic-gate * Put the character string cp out, with padding.
437c478bdstevel@tonic-gate * The number of affected lines is affcnt, and the routine
447c478bdstevel@tonic-gate * used to output one character is outc.
457c478bdstevel@tonic-gate */
467c478bdstevel@tonic-gatestatic	char	*ocp;
477c478bdstevel@tonic-gate
487c478bdstevel@tonic-gatestatic	char	*
497c478bdstevel@tonic-gate_tpad(char *, int, int (*)(char));
507c478bdstevel@tonic-gate
517c478bdstevel@tonic-gatestatic	char	*
527c478bdstevel@tonic-gate_tpad(char *cp, int affcnt, int (*outc)(char x))
537c478bdstevel@tonic-gate{
547c478bdstevel@tonic-gate	int	delay = 0;
557c478bdstevel@tonic-gate	char	*icp = cp;
567c478bdstevel@tonic-gate	int	ignorexon = 0, doaffcnt = 0;
577c478bdstevel@tonic-gate
587c478bdstevel@tonic-gate#ifdef	_VR2_COMPAT_CODE
597c478bdstevel@tonic-gate	/*
607c478bdstevel@tonic-gate	 * Why is this here?
617c478bdstevel@tonic-gate	 * Because mandatory padding must be used for flash_screen
627c478bdstevel@tonic-gate	 * and bell. We cannot force users to code mandatory padding
637c478bdstevel@tonic-gate	 * in their terminfo entries, as that would break compatibility.
647c478bdstevel@tonic-gate	 * We therefore, do it here.
657c478bdstevel@tonic-gate	 *
6648bbca8Daniel Hoffman	 * When compatibility is to be broken, it will go away
677c478bdstevel@tonic-gate	 * and users will be informed that they MUST use mandatory
687c478bdstevel@tonic-gate	 * padding for flash and bell.
697c478bdstevel@tonic-gate	 */
707c478bdstevel@tonic-gate	if (ocp == bell || ocp == flash_screen)
717c478bdstevel@tonic-gate		ignorexon = TRUE;
727c478bdstevel@tonic-gate#endif	/* _VR2_COMPAT_CODE */
737c478bdstevel@tonic-gate
747c478bdstevel@tonic-gate	/* Eat initial $< */
757c478bdstevel@tonic-gate	cp += 2;
767c478bdstevel@tonic-gate
777c478bdstevel@tonic-gate	/* Convert the number representing the delay. */
787c478bdstevel@tonic-gate	if (isdigit(*cp)) {
797c478bdstevel@tonic-gate		do
807c478bdstevel@tonic-gate			delay = delay * 10 + *cp++ - '0';
817c478bdstevel@tonic-gate		while (isdigit(*cp));
827c478bdstevel@tonic-gate	}
837c478bdstevel@tonic-gate	delay *= 10;
847c478bdstevel@tonic-gate	if (*cp == '.') {
857c478bdstevel@tonic-gate		cp++;
867c478bdstevel@tonic-gate		if (isdigit(*cp))
877c478bdstevel@tonic-gate			delay += *cp - '0';
887c478bdstevel@tonic-gate	/* Only one digit to the right of the decimal point. */
897c478bdstevel@tonic-gate		while (isdigit(*cp))
907c478bdstevel@tonic-gate			cp++;
917c478bdstevel@tonic-gate	}
927c478bdstevel@tonic-gate
937c478bdstevel@tonic-gate	/*
947c478bdstevel@tonic-gate	 * If the delay is followed by a `*', then
957c478bdstevel@tonic-gate	 * multiply by the affected lines count.
967c478bdstevel@tonic-gate	 * If the delay is followed by a '/', then
977c478bdstevel@tonic-gate	 * the delay is done irregardless of xon/xoff.
987c478bdstevel@tonic-gate	 */
997c478bdstevel@tonic-gate	/*CONSTCOND*/
1007c478bdstevel@tonic-gate	while (TRUE) {
1017c478bdstevel@tonic-gate		if (*cp == '/')
1027c478bdstevel@tonic-gate			ignorexon = TRUE;
1037c478bdstevel@tonic-gate		else
1047c478bdstevel@tonic-gate			if (*cp == '*')
1057c478bdstevel@tonic-gate				doaffcnt = TRUE;
1067c478bdstevel@tonic-gate			else
1077c478bdstevel@tonic-gate				break;
1087c478bdstevel@tonic-gate		cp++;
1097c478bdstevel@tonic-gate	}
1107c478bdstevel@tonic-gate	if (doaffcnt)
1117c478bdstevel@tonic-gate		delay *= affcnt;
1127c478bdstevel@tonic-gate	if (*cp == '>')
1137c478bdstevel@tonic-gate		cp++;	/* Eat trailing '>' */
1147c478bdstevel@tonic-gate	else {
1157c478bdstevel@tonic-gate	/*
1167c478bdstevel@tonic-gate	 * We got a "$<" with no ">".  This is usually caused by
1177c478bdstevel@tonic-gate	 * a cursor addressing sequence that happened to generate
1187c478bdstevel@tonic-gate	 * $ < .  To avoid an infinite loop, we output the $ here
1197c478bdstevel@tonic-gate	 * and pass back the rest.
1207c478bdstevel@tonic-gate	 */
1217c478bdstevel@tonic-gate		(*outc)(*icp++);
1227c478bdstevel@tonic-gate		return (icp);
1237c478bdstevel@tonic-gate	}
1247c478bdstevel@tonic-gate
1257c478bdstevel@tonic-gate	/*
1267c478bdstevel@tonic-gate	 * If no delay needed, or output speed is
1277c478bdstevel@tonic-gate	 * not comprehensible, then don't try to delay.
1287c478bdstevel@tonic-gate	 */
1297c478bdstevel@tonic-gate	if (delay == 0)
1307c478bdstevel@tonic-gate		return (cp);
1317c478bdstevel@tonic-gate	/*
1327c478bdstevel@tonic-gate	 * Let handshaking take care of it - no extra cpu load from pads.
1337c478bdstevel@tonic-gate	 * Also, this will be more optimal since the pad info is usually
1347c478bdstevel@tonic-gate	 * worst case.  We only use padding info for such terminals to
1357c478bdstevel@tonic-gate	 * estimate the cost of a capability in choosing the cheapest one.
1367c478bdstevel@tonic-gate	 * Some capabilities, such as flash_screen, really want the
1377c478bdstevel@tonic-gate	 * padding irregardless.
1387c478bdstevel@tonic-gate	 */
1397c478bdstevel@tonic-gate	if (xon_xoff && !ignorexon)
1407c478bdstevel@tonic-gate		return (cp);
1417c478bdstevel@tonic-gate	(void) _delay(delay, outc);
1427c478bdstevel@tonic-gate	return (cp);
1437c478bdstevel@tonic-gate}
1447c478bdstevel@tonic-gate
1457c478bdstevel@tonic-gateint
1467c478bdstevel@tonic-gatetputs(char *cp, int affcnt, int (*outc)(char))
1477c478bdstevel@tonic-gate{
1487c478bdstevel@tonic-gate	if (cp != 0) {
1497c478bdstevel@tonic-gate		ocp = cp;
1507c478bdstevel@tonic-gate
1517c478bdstevel@tonic-gate		/* The guts of the string. */
1527c478bdstevel@tonic-gate		while (*cp)
1537c478bdstevel@tonic-gate			if (*cp == '$' && cp[1] == '<')
1547c478bdstevel@tonic-gate				cp = _tpad(cp, affcnt, outc);
1557c478bdstevel@tonic-gate			else
1567c478bdstevel@tonic-gate				(*outc)(*cp++);
1577c478bdstevel@tonic-gate	}
1587c478bdstevel@tonic-gate	return (OK);
1597c478bdstevel@tonic-gate}
160