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