/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */ /* UNIX System Laboratories, Inc. */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ #ident "@(#)curses:screen/slk_start.c 1.5" #include "curses_inc.h" /* * Initialize usage of soft labels * This routine should be called before each call of newscreen * or initscr to initialize for the next terminal. * * ng: number of groupings. If gp is NULL, it denotes one * of two default groupings: * 0: - - - - - - - - * 1: - - - - - - - - * gp: groupings. */ static void _init_slk_func(void); static int _slk_setpos(int, short *); static char _ngroups, _groups[LABMAX]; int slk_start(int ng, int *gp) { register int i = 0, j = 0; if (gp == NULL) { switch (ng) { case 2 : _ngroups = 2; _groups[0] = 4; _groups[1] = 4; break; case 3 : no_format : _ngroups = 3; _groups[0] = 3; _groups[1] = 2; _groups[2] = 3; break; default : if (label_format) { int k; char ch1[3], *ch = label_format; while (TRUE) { if ((*ch == ',') || (*ch == '\0')) { ch1[i] = '\0'; if ((k = atoi(ch1)) <= 0) goto err; _groups[j++] = (char) k; i = 0; if (*ch == '\0') { ng = j; break; } } else ch1[i++] = *ch++; } } else goto no_format; break; } } else { for (; i < ng; i++) { if ((j += gp[i]) > LABMAX) err : return (ERR); _groups[i] = (char) gp[i]; } _ngroups = (char) ng; } /* signal newscreen() */ _slk_init = _init_slk_func; return (OK); } static void _init_slk_func() { register int i, len, num = 0; register SLK_MAP *slk; register char *cp, *ep; register WINDOW *win; /* clear this out to ready for next time */ _slk_init = NULL; /* get space for slk structure */ if ((slk = (SLK_MAP *) malloc(sizeof(SLK_MAP))) == NULL) { curs_errno = CURS_BAD_MALLOC; #ifdef DEBUG strcpy(curs_parm_err, "_init_slk_func"); #endif /* DEBUG */ return; } /* compute actual number of labels */ num = 0; for (i = 0; i < _ngroups; i++) num += _groups[i]; /* max label length */ if (plab_norm && (label_height * label_width >= LABLEN) && (num_labels >= num)) { win = NULL; goto next; } else { if ((win = newwin(1, COLS, LINES - 1, 0)) == NULL) goto err; win->_leave = TRUE; wattrset(win, A_REVERSE | A_DIM); /* remove one line from the screen */ LINES = --SP->lsize; if ((len = (COLS - 1) / (num + 1)) > LABLEN) { next : len = LABLEN; } } /* positions to place labels */ if (len <= 0 || num <= 0 || (_slk_setpos(len, slk->_labx) == ERR)) { if (win != NULL) (void) delwin (win); err : free(slk); } else { slk->_num = (short) num; slk->_len = (short) len; for (i = 0; i < num; ++i) { cp = slk->_ldis[i]; ep = cp + len; for (; cp < ep; ++cp) *cp = ' '; *ep = '\0'; slk->_lval[i][0] = '\0'; slk->_lch[i] = TRUE; } slk->_changed = TRUE; slk->_win = win; _do_slk_ref = _slk_update; _do_slk_tch = slk_touch; _do_slk_noref = slk_noutrefresh; SP->slk = slk; } } /* * Compute placements of labels. The general idea is to spread * the groups out evenly. This routine is designed for the day * when > 8 labels and other kinds of groupings may be desired. * * The main assumption behind the algorithm is that the total * # of labels in all the groups is <= LABMAX. * * len: length of a label * labx: to return the coords of the labels. */ static int _slk_setpos(int len, short *labx) { register int i, k, n, spread, left, begadd; int grpx[LABMAX]; /* compute starting coords for each group */ grpx[0] = 0; if (_ngroups > 1) { /* spacing between groups */ for (i = 0, n = 0; i < _ngroups; ++i) n += _groups[i] * (len + 1) - 1; if ((spread = (COLS - (n + 1))/(_ngroups - 1)) <= 0) return (ERR); left = (COLS-(n + 1)) % (_ngroups - 1); begadd = (_ngroups / 2) - (left / 2); /* coords of groups */ for (i = 1; i < _ngroups; ++i) { grpx[i] = grpx[i - 1] + (_groups[i - 1] * (len + 1) - 1) + spread; if (left > 0 && i > begadd) { grpx[i]++; left--; } } } /* now set coords of each label */ n = 0; for (i = 0; i < _ngroups; ++i) for (k = 0; k < _groups[i]; ++k) labx[n++] = (short) (grpx[i] + k * (len + 1)); return (OK); }