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