xref: /titanic_50/usr/src/lib/libcurses/screen/slk_start.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
32*7c478bd9Sstevel@tonic-gate  * The Regents of the University of California
33*7c478bd9Sstevel@tonic-gate  * All Rights Reserved
34*7c478bd9Sstevel@tonic-gate  *
35*7c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
36*7c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
37*7c478bd9Sstevel@tonic-gate  * contributors.
38*7c478bd9Sstevel@tonic-gate  */
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #include	<sys/types.h>
45*7c478bd9Sstevel@tonic-gate #include	<stdlib.h>
46*7c478bd9Sstevel@tonic-gate #include	"curses_inc.h"
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate /*
49*7c478bd9Sstevel@tonic-gate  * Initialize usage of soft labels
50*7c478bd9Sstevel@tonic-gate  * This routine should be called before each call of newscreen
51*7c478bd9Sstevel@tonic-gate  * or initscr to initialize for the next terminal.
52*7c478bd9Sstevel@tonic-gate  *
53*7c478bd9Sstevel@tonic-gate  * ng:	number of groupings. If gp is NULL, it denotes one
54*7c478bd9Sstevel@tonic-gate  * 	of two default groupings:
55*7c478bd9Sstevel@tonic-gate  * 	0:	- - -   - -   - - -
56*7c478bd9Sstevel@tonic-gate  * 	1:      - - - -     - - - -
57*7c478bd9Sstevel@tonic-gate  * gp:	groupings.
58*7c478bd9Sstevel@tonic-gate  */
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate static	void	_init_slk_func(void);
61*7c478bd9Sstevel@tonic-gate static  int	_slk_setpos(int, short *);
62*7c478bd9Sstevel@tonic-gate static	int	_ngroups, _groups[LABMAX];
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate int
slk_start(int ng,int * gp)65*7c478bd9Sstevel@tonic-gate slk_start(int ng, int *gp)
66*7c478bd9Sstevel@tonic-gate {
67*7c478bd9Sstevel@tonic-gate 	int	i = 0, j = 0;
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 	if (gp == NULL) {
70*7c478bd9Sstevel@tonic-gate 		switch (ng) {
71*7c478bd9Sstevel@tonic-gate 			case 2 :
72*7c478bd9Sstevel@tonic-gate 				_ngroups = 2;
73*7c478bd9Sstevel@tonic-gate 				_groups[0] = 4;
74*7c478bd9Sstevel@tonic-gate 				_groups[1] = 4;
75*7c478bd9Sstevel@tonic-gate 				break;
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 			case 3 :
78*7c478bd9Sstevel@tonic-gate no_format :
79*7c478bd9Sstevel@tonic-gate 				_ngroups = 3;
80*7c478bd9Sstevel@tonic-gate 				_groups[0] = 3;
81*7c478bd9Sstevel@tonic-gate 				_groups[1] = 2;
82*7c478bd9Sstevel@tonic-gate 				_groups[2] = 3;
83*7c478bd9Sstevel@tonic-gate 				break;
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 			default :
86*7c478bd9Sstevel@tonic-gate 				if (label_format) {
87*7c478bd9Sstevel@tonic-gate 				    int		k;
88*7c478bd9Sstevel@tonic-gate 				    char	ch1[3], *ch = label_format;
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate 					/*CONSTCOND*/
91*7c478bd9Sstevel@tonic-gate 					while (TRUE) {
92*7c478bd9Sstevel@tonic-gate 						if ((*ch == ',') ||
93*7c478bd9Sstevel@tonic-gate 						    (*ch == '\0')) {
94*7c478bd9Sstevel@tonic-gate 							ch1[i] = '\0';
95*7c478bd9Sstevel@tonic-gate 							if ((k = atoi(ch1)) <=
96*7c478bd9Sstevel@tonic-gate 							    0)
97*7c478bd9Sstevel@tonic-gate 								goto err;
98*7c478bd9Sstevel@tonic-gate 							_groups[j++] = k;
99*7c478bd9Sstevel@tonic-gate 							i = 0;
100*7c478bd9Sstevel@tonic-gate 							if (*ch == '\0') {
101*7c478bd9Sstevel@tonic-gate 								break;
102*7c478bd9Sstevel@tonic-gate 							}
103*7c478bd9Sstevel@tonic-gate 						} else
104*7c478bd9Sstevel@tonic-gate 							ch1[i++] = *ch++;
105*7c478bd9Sstevel@tonic-gate 					}
106*7c478bd9Sstevel@tonic-gate 				} else
107*7c478bd9Sstevel@tonic-gate 					goto no_format;
108*7c478bd9Sstevel@tonic-gate 				break;
109*7c478bd9Sstevel@tonic-gate 		}
110*7c478bd9Sstevel@tonic-gate 	} else {
111*7c478bd9Sstevel@tonic-gate 		for (; i < ng; i++) {
112*7c478bd9Sstevel@tonic-gate 			if ((j += gp[i]) > LABMAX)
113*7c478bd9Sstevel@tonic-gate err :
114*7c478bd9Sstevel@tonic-gate 				return (ERR);
115*7c478bd9Sstevel@tonic-gate 			_groups[i] = gp[i];
116*7c478bd9Sstevel@tonic-gate 		}
117*7c478bd9Sstevel@tonic-gate 		_ngroups = ng;
118*7c478bd9Sstevel@tonic-gate 	}
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate 	/* signal newscreen() */
121*7c478bd9Sstevel@tonic-gate 	_slk_init = _init_slk_func;
122*7c478bd9Sstevel@tonic-gate 	return (OK);
123*7c478bd9Sstevel@tonic-gate }
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate static	void
_init_slk_func(void)126*7c478bd9Sstevel@tonic-gate _init_slk_func(void)
127*7c478bd9Sstevel@tonic-gate {
128*7c478bd9Sstevel@tonic-gate 	int	i, len, num;
129*7c478bd9Sstevel@tonic-gate 	SLK_MAP	*slk;
130*7c478bd9Sstevel@tonic-gate 	char	*cp, *ep;
131*7c478bd9Sstevel@tonic-gate 	WINDOW	*win;
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate 	/* clear this out to ready for next time */
134*7c478bd9Sstevel@tonic-gate 	_slk_init = NULL;
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 	/* get space for slk structure */
137*7c478bd9Sstevel@tonic-gate 	if ((slk = (SLK_MAP *) malloc(sizeof (SLK_MAP))) == NULL) {
138*7c478bd9Sstevel@tonic-gate 		curs_errno = CURS_BAD_MALLOC;
139*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
140*7c478bd9Sstevel@tonic-gate 		strcpy(curs_parm_err, "_init_slk_func");
141*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
142*7c478bd9Sstevel@tonic-gate 		return;
143*7c478bd9Sstevel@tonic-gate 	}
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	/* compute actual number of labels */
146*7c478bd9Sstevel@tonic-gate 	num = 0;
147*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < _ngroups; i++)
148*7c478bd9Sstevel@tonic-gate 		num += _groups[i];
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 	/* max label length */
151*7c478bd9Sstevel@tonic-gate 	if (plab_norm && (label_height * label_width >= LABLEN) &&
152*7c478bd9Sstevel@tonic-gate 	    (num_labels >= num)) {
153*7c478bd9Sstevel@tonic-gate 		win = NULL;
154*7c478bd9Sstevel@tonic-gate 		goto next;
155*7c478bd9Sstevel@tonic-gate 	} else {
156*7c478bd9Sstevel@tonic-gate 		if ((win = newwin(1, COLS, LINES - 1, 0)) == NULL)
157*7c478bd9Sstevel@tonic-gate 			goto err;
158*7c478bd9Sstevel@tonic-gate 		win->_leave = TRUE;
159*7c478bd9Sstevel@tonic-gate 		(void) wattrset(win, A_REVERSE | A_DIM);
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 		/* remove one line from the screen */
162*7c478bd9Sstevel@tonic-gate 		LINES = --SP->lsize;
163*7c478bd9Sstevel@tonic-gate 		if ((len = (COLS - 1) / (num + 1)) > LABLEN) {
164*7c478bd9Sstevel@tonic-gate next :
165*7c478bd9Sstevel@tonic-gate 			len = LABLEN;
166*7c478bd9Sstevel@tonic-gate 		}
167*7c478bd9Sstevel@tonic-gate 	}
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate 	/* positions to place labels */
170*7c478bd9Sstevel@tonic-gate 	if (len <= 0 || num <= 0 || (_slk_setpos(len, slk->_labx) == ERR)) {
171*7c478bd9Sstevel@tonic-gate 		if (win != NULL)
172*7c478bd9Sstevel@tonic-gate 			(void) delwin(win);
173*7c478bd9Sstevel@tonic-gate err :
174*7c478bd9Sstevel@tonic-gate 		free(slk);
175*7c478bd9Sstevel@tonic-gate 	} else {
176*7c478bd9Sstevel@tonic-gate 		/* LINTED */
177*7c478bd9Sstevel@tonic-gate 		slk->_num = (short) num;
178*7c478bd9Sstevel@tonic-gate 		/* LINTED */
179*7c478bd9Sstevel@tonic-gate 		slk->_len = (short) len;
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < num; ++i) {
182*7c478bd9Sstevel@tonic-gate 			cp = slk->_ldis[i];
183*7c478bd9Sstevel@tonic-gate 			ep = cp + len;
184*7c478bd9Sstevel@tonic-gate 			for (; cp < ep; ++cp)
185*7c478bd9Sstevel@tonic-gate 				*cp = ' ';
186*7c478bd9Sstevel@tonic-gate 			*ep = '\0';
187*7c478bd9Sstevel@tonic-gate 			slk->_lval[i][0] = '\0';
188*7c478bd9Sstevel@tonic-gate 			slk->_lch[i] = TRUE;
189*7c478bd9Sstevel@tonic-gate 		}
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate 		slk->_changed = TRUE;
192*7c478bd9Sstevel@tonic-gate 		slk->_win = win;
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate 		_do_slk_ref = _slk_update;
195*7c478bd9Sstevel@tonic-gate 		_do_slk_tch = slk_touch;
196*7c478bd9Sstevel@tonic-gate 		_do_slk_noref = slk_noutrefresh;
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 		SP->slk = slk;
199*7c478bd9Sstevel@tonic-gate 	}
200*7c478bd9Sstevel@tonic-gate }
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate /*
204*7c478bd9Sstevel@tonic-gate  * Compute placements of labels. The general idea is to spread
205*7c478bd9Sstevel@tonic-gate  * the groups out evenly. This routine is designed for the day
206*7c478bd9Sstevel@tonic-gate  * when > 8 labels and other kinds of groupings may be desired.
207*7c478bd9Sstevel@tonic-gate  *
208*7c478bd9Sstevel@tonic-gate  * The main assumption behind the algorithm is that the total
209*7c478bd9Sstevel@tonic-gate  * # of labels in all the groups is <= LABMAX.
210*7c478bd9Sstevel@tonic-gate  *
211*7c478bd9Sstevel@tonic-gate  * len: length of a label
212*7c478bd9Sstevel@tonic-gate  * labx: to return the coords of the labels.
213*7c478bd9Sstevel@tonic-gate  */
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate static int
_slk_setpos(int len,short * labx)216*7c478bd9Sstevel@tonic-gate _slk_setpos(int len, short *labx)
217*7c478bd9Sstevel@tonic-gate {
218*7c478bd9Sstevel@tonic-gate 	int	i, k, n, spread, left, begadd;
219*7c478bd9Sstevel@tonic-gate 	int	grpx[LABMAX];
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate 	/* compute starting coords for each group */
222*7c478bd9Sstevel@tonic-gate 	grpx[0] = 0;
223*7c478bd9Sstevel@tonic-gate 	if (_ngroups > 1) {
224*7c478bd9Sstevel@tonic-gate 		/* spacing between groups */
225*7c478bd9Sstevel@tonic-gate 		for (i = 0, n = 0; i < _ngroups; ++i)
226*7c478bd9Sstevel@tonic-gate 			n += _groups[i] * (len + 1) - 1;
227*7c478bd9Sstevel@tonic-gate 		if ((spread = (COLS - (n + 1))/(_ngroups - 1)) <= 0)
228*7c478bd9Sstevel@tonic-gate 			return (ERR);
229*7c478bd9Sstevel@tonic-gate 		left = (COLS-(n + 1)) % (_ngroups - 1);
230*7c478bd9Sstevel@tonic-gate 		begadd = (_ngroups / 2) - (left / 2);
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 		/* coords of groups */
233*7c478bd9Sstevel@tonic-gate 		for (i = 1; i < _ngroups; ++i) {
234*7c478bd9Sstevel@tonic-gate 			grpx[i] = grpx[i - 1] + (_groups[i - 1] *
235*7c478bd9Sstevel@tonic-gate 			    (len + 1) - 1) + spread;
236*7c478bd9Sstevel@tonic-gate 			if (left > 0 && i > begadd) {
237*7c478bd9Sstevel@tonic-gate 				grpx[i]++;
238*7c478bd9Sstevel@tonic-gate 				left--;
239*7c478bd9Sstevel@tonic-gate 			}
240*7c478bd9Sstevel@tonic-gate 		}
241*7c478bd9Sstevel@tonic-gate 	}
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	/* now set coords of each label */
244*7c478bd9Sstevel@tonic-gate 	n = 0;
245*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < _ngroups; ++i)
246*7c478bd9Sstevel@tonic-gate 		for (k = 0; k < _groups[i]; ++k)
247*7c478bd9Sstevel@tonic-gate 			labx[n++] = grpx[i] + k * (len + 1);
248*7c478bd9Sstevel@tonic-gate 	return (OK);
249*7c478bd9Sstevel@tonic-gate }
250