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