2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 1995-1999 by Sun Microsystems, Inc.
2N/A * All rights reserved.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/* LINTLIBRARY */
2N/A
2N/A/*
2N/A * slk.c
2N/A *
2N/A * XCurses Library
2N/A *
2N/A * Copyright 1990, 1995 by Mortice Kern Systems Inc. All rights reserved.
2N/A *
2N/A */
2N/A
2N/A#if M_RCSID
2N/A#ifndef lint
2N/Astatic char rcsID[] =
2N/A"$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/"
2N/A"libxcurses/src/libc/xcurses/rcs/slk.c 1.9 1998/05/20 17:26:23 "
2N/A"cbates Exp $";
2N/A#endif
2N/A#endif
2N/A
2N/A#include <private.h>
2N/A#include <string.h>
2N/A
2N/Aint __m_slk_labels_on;
2N/Aint __m_slk_touched = 0;
2N/A/*
2N/A * Flag for initialisation soft label keys once setupterm() has been called.
2N/A */
2N/Aint
2N/Aslk_init(int fmt)
2N/A{
2N/A int code = ERR;
2N/A
2N/A if (0 <= fmt && fmt <= 1) {
2N/A __m_slk_format = fmt;
2N/A __m_slk_labels_on = 1;
2N/A code = OK;
2N/A }
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_attron(const chtype at)
2N/A{
2N/A int code = OK;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wattron(__m_screen->_slk._w, (int) at);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_attroff(const chtype at)
2N/A{
2N/A int code = OK;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wattroff(__m_screen->_slk._w, (int) at);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_attrset(const chtype at)
2N/A{
2N/A int code = OK;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wattrset(__m_screen->_slk._w, (int) at);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_attr_off(const attr_t at, void *opts)
2N/A{
2N/A int code = OK;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wattr_off(__m_screen->_slk._w, at, opts);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_attr_on(const attr_t at, void *opts)
2N/A{
2N/A int code = OK;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wattr_on(__m_screen->_slk._w, at, opts);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_attr_set(const attr_t at, short co, void *opts)
2N/A{
2N/A int code = OK;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wattr_set(__m_screen->_slk._w, at, co, opts);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_color(short co)
2N/A{
2N/A int code = OK;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wcolor_set(__m_screen->_slk._w, co, (void *) 0);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_touch(void)
2N/A{
2N/A int code = OK;
2N/A WINDOW *w = __m_screen->_slk._w;
2N/A
2N/A if (w != NULL) {
2N/A code = wtouchln(w, 0, 1, 1);
2N/A wtouchln_hard(w, 0, 1);
2N/A } else
2N/A __m_slk_touched = 1;
2N/A
2N/A return (code);
2N/A}
2N/A
2N/A/*
2N/A * These label start columns assume 80 columns in order to
2N/A * fit 8 _slk._labels of 8 columns.
2N/A */
2N/Astatic const int format[][8] = {
2N/A { 0, 9, 18, 31, 40, 53, 62, 71 },
2N/A { 0, 9, 18, 27, 44, 53, 62, 71 },
2N/A};
2N/A
2N/A#define _LABEL_LENGTH_MALLOC \
2N/A (MB_LEN_MAX * ((1 + _M_CCHAR_MAX) * 8) + 1)
2N/A
2N/Avoid
2N/A__m_slk_set_all(void)
2N/A{
2N/A int i;
2N/A
2N/A for (i = 0; i < 8; ++i) {
2N/A if (__m_screen->_slk._labels[i] != NULL) {
2N/A (void) slk_set(i + 1, __m_screen->_slk._labels[i],
2N/A __m_screen->_slk._justify[i]);
2N/A }
2N/A }
2N/A}
2N/A
2N/Aint
2N/A__m_slk_clear(int kluge)
2N/A{
2N/A int i;
2N/A int index;
2N/A int code = ERR;
2N/A
2N/A if (__m_screen->_slk._w != NULL) {
2N/A cchar_t _bg = __m_screen->_slk._w->_bg;
2N/A if (kluge) {
2N/A /* Test suite expects spaces to have FG attributes */
2N/A __m_screen->_slk._w->_bg = __m_screen->_slk._w->_fg;
2N/A }
2N/A for (index = 0; index < 8; ++index) {
2N/A i = format[__m_slk_format][index];
2N/A (void) __m_cc_erase(__m_screen->_slk._w,
2N/A 0, i, 0, i + 7);
2N/A }
2N/A __m_screen->_slk._w->_bg = _bg; /* Restore ... */
2N/A
2N/A } else if (plab_norm != NULL) {
2N/A for (index = 0; index < 8; ++index) {
2N/A char *p;
2N/A p = __m_screen->_slk._saved[index];
2N/A if (!p) {
2N/A p = (char *)malloc(_LABEL_LENGTH_MALLOC);
2N/A if (p == NULL)
2N/A goto error;
2N/A __m_screen->_slk._saved[index] = p;
2N/A }
2N/A (void) strcpy(p, (kluge) ? "" : " ");
2N/A }
2N/A }
2N/A if (__m_screen->_slk._w != NULL) {
2N/A code = wrefresh(__m_screen->_slk._w);
2N/A } else {
2N/A __m_slk_labels_on = 0;
2N/A code = slk_refresh();
2N/A }
2N/A
2N/Aerror:
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_clear(void)
2N/A{
2N/A return (__m_slk_clear(0));
2N/A}
2N/A
2N/Aint
2N/Aslk_restore(void)
2N/A{
2N/A int code;
2N/A
2N/A __m_slk_set_all();
2N/A __m_slk_labels_on = 1;
2N/A code = slk_refresh();
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_noutrefresh(void)
2N/A{
2N/A int code;
2N/A
2N/A if (__m_screen->_slk._w != NULL)
2N/A code = wnoutrefresh(__m_screen->_slk._w);
2N/A else {
2N/A if (__m_slk_touched) {
2N/A __m_slk_set_all();
2N/A __m_slk_touched = 0;
2N/A }
2N/A if (__m_slk_labels_on) {
2N/A if (label_on != NULL) {
2N/A (void) TPUTS(label_on, 1, __m_outc);
2N/A }
2N/A } else {
2N/A if (label_off != NULL) {
2N/A (void) TPUTS(label_off, 1, __m_outc);
2N/A }
2N/A }
2N/A (void) fflush(__m_screen->_of);
2N/A code = OK;
2N/A }
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_refresh(void)
2N/A{
2N/A int code;
2N/A
2N/A if ((code = slk_noutrefresh()) == OK)
2N/A code = doupdate();
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Avoid
2N/A__m_slk_doupdate(void)
2N/A{
2N/A if ((__m_screen->_slk._w == NULL) && plab_norm) {
2N/A int index;
2N/A for (index = 0; index < 8; index++) {
2N/A char *s = __m_screen->_slk._saved[index];
2N/A if (s) {
2N/A (void) TPUTS(tparm(plab_norm, (long) index+1,
2N/A (long) s, 0L, 0L, 0L, 0L, 0L, 0L, 0L),
2N/A 1, __m_outc);
2N/A }
2N/A }
2N/A }
2N/A}
2N/A
2N/Achar *
2N/Aslk_label(int index)
2N/A{
2N/A char *label;
2N/A
2N/A if (index < 1 || 8 < index) {
2N/A label = NULL;
2N/A } else {
2N/A label = __m_screen->_slk._labels[index-1];
2N/A }
2N/A return (label);
2N/A}
2N/A
2N/Aint
2N/Aslk_set(int index, const char *label, int justify)
2N/A{
2N/A int code = ERR;
2N/A wchar_t wcs[_M_CCHAR_MAX * 8 + 1];
2N/A
2N/A if ((label == NULL) || *label == '\0')
2N/A label = " ";
2N/A if (mbstowcs(wcs, label, sizeof (wcs)) != (size_t)-1)
2N/A code = slk_wset(index, wcs, justify);
2N/A
2N/A return (code);
2N/A}
2N/A
2N/Aint
2N/Aslk_wset(int index, const wchar_t *label, int justify)
2N/A{
2N/A cchar_t cc;
2N/A int i, width, code = ERR;
2N/A wchar_t wcs[_M_CCHAR_MAX * 8 + 1], *wp;
2N/A char mbs[_LABEL_LENGTH_MALLOC];
2N/A char tmbs[_LABEL_LENGTH_MALLOC];
2N/A int ww = 0;
2N/A int left1, left2;
2N/A static const char *spcs = " ";
2N/A
2N/A if (index < 1 || 8 < index || justify < 0 || 2 < justify)
2N/A goto error1;
2N/A
2N/A index--; /* Shift from {1..8} to {0..7} */
2N/A
2N/A if (label == NULL)
2N/A label = L"";
2N/A
2N/A /* Copy the characters that fill the first 8 columns of the label. */
2N/A for (wp = wcs, width = 0; *label != '\0'; label += i, wp += cc._n) {
2N/A if ((i = __m_wcs_cc(label, A_NORMAL, 0, &cc)) < 0)
2N/A goto error1;
2N/A
2N/A ww += __m_cc_width(&cc);
2N/A if (ww > 8)
2N/A break;
2N/A else
2N/A width = ww;
2N/A
2N/A (void) wcsncpy(wp, cc._wc, cc._n);
2N/A }
2N/A *wp = '\0';
2N/A
2N/A if (wcstombs(tmbs, wcs, sizeof (mbs)) == (size_t) -1)
2N/A goto error1;
2N/A
2N/A if (width == 8) {
2N/A (void) strcpy(mbs, tmbs);
2N/A } else {
2N/A switch (justify) {
2N/A case 0:
2N/A (void) strcpy(mbs, tmbs);
2N/A (void) strncat(mbs, spcs, (8 - width));
2N/A *(mbs + strlen(tmbs) + (8 - width)) = '\0';
2N/A break;
2N/A case 1:
2N/A left1 = (8 - width) / 2;
2N/A (void) strncpy(mbs, spcs, left1);
2N/A (void) strcpy(mbs + left1, tmbs);
2N/A left2 = 8 - width - left1;
2N/A (void) strncat(mbs, spcs, left2);
2N/A *(mbs + left1 + strlen(tmbs) + left2) = '\0';
2N/A break;
2N/A case 2:
2N/A left1 = 8 - width;
2N/A (void) strncpy(mbs, spcs, left1);
2N/A (void) strcpy(mbs + left1, tmbs);
2N/A break;
2N/A }
2N/A }
2N/A
2N/A /* Remember the new label. */
2N/A __m_screen->_slk._justify[index] = (short) justify;
2N/A
2N/A if (__m_screen->_slk._labels[index] != NULL)
2N/A free(__m_screen->_slk._labels[index]);
2N/A if ((__m_screen->_slk._labels[index] = strdup(tmbs)) == NULL)
2N/A goto error1;
2N/A
2N/A if (plab_norm != NULL) {
2N/A char *p;
2N/A p = __m_screen->_slk._saved[index];
2N/A if (!p) {
2N/A p = (char *)malloc(_LABEL_LENGTH_MALLOC);
2N/A if (p == NULL)
2N/A goto error1;
2N/A __m_screen->_slk._saved[index] = p;
2N/A }
2N/A (void) strcpy(p, mbs);
2N/A }
2N/A
2N/A __m_slk_labels_on = 1;
2N/A
2N/A if (__m_screen->_slk._w != NULL) {
2N/A cchar_t _bg = __m_screen->_slk._w->_bg;
2N/A /* Write the justified label into the slk window. */
2N/A i = format[__m_slk_format][index];
2N/A __m_screen->_slk._w->_bg = __m_screen->_slk._w->_fg;
2N/A (void) __m_cc_erase(__m_screen->_slk._w, 0, i, 0, i + 7);
2N/A __m_screen->_slk._w->_bg = _bg; /* Restore ... */
2N/A
2N/A (void) mvwaddstr(__m_screen->_slk._w, 0, i, mbs);
2N/A }
2N/A
2N/A code = OK;
2N/Aerror1:
2N/A return (code);
2N/A}