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