150276Speter/****************************************************************************
2176187Srafan * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
30166124Srafan *  Authors:                                                                *
31166124Srafan *          Gerhard Fuernkranz                      1993 (original)         *
32166124Srafan *          Zeyd M. Ben-Halim                       1992,1995 (sic)         *
33166124Srafan *          Eric S. Raymond                                                 *
34166124Srafan *          Juergen Pfeifer                         1996-on                 *
35166124Srafan *          Thomas E. Dickey                                                *
3650276Speter ****************************************************************************/
3750276Speter
3850276Speter/*
3950276Speter *	lib_slk.c
4050276Speter *	Soft key routines.
4150276Speter */
4250276Speter
4350276Speter#include <curses.priv.h>
4450276Speter
4550276Speter#include <ctype.h>
4676726Speter#include <term.h>		/* num_labels, label_*, plab_norm */
4750276Speter
48184989SrafanMODULE_ID("$Id: lib_slk.c,v 1.35 2008/09/27 14:07:33 juergen Exp $")
4950276Speter
5050276Speter/*
51166124Srafan * Free any memory related to soft labels, return an error.
52166124Srafan */
53166124Srafanstatic int
54166124Srafanslk_failed(void)
55166124Srafan{
56166124Srafan    if (SP->_slk) {
57166124Srafan	FreeIfNeeded(SP->_slk->ent);
58166124Srafan	free(SP->_slk);
59166124Srafan	SP->_slk = (SLK *) 0;
60166124Srafan    }
61166124Srafan    return ERR;
62166124Srafan}
63166124Srafan
64166124Srafan/*
6550276Speter * Initialize soft labels.
6650276Speter * Called from newterm()
6750276Speter */
6876726SpeterNCURSES_EXPORT(int)
6950276Speter_nc_slk_initialize(WINDOW *stwin, int cols)
7050276Speter{
7176726Speter    int i, x;
7276726Speter    int res = OK;
73166124Srafan    unsigned max_length;
7450276Speter
75166124Srafan    T((T_CALLED("_nc_slk_initialize()")));
7650276Speter
7776726Speter    if (SP->_slk) {		/* we did this already, so simply return */
78166124Srafan	returnCode(OK);
7976726Speter    } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0)
80166124Srafan	returnCode(ERR);
8150276Speter
8276726Speter    SP->_slk->ent = NULL;
8350276Speter
84166124Srafan    /*
85166124Srafan     * If we use colors, vidputs() will suppress video attributes that conflict
86166124Srafan     * with colors.  In that case, we're still guaranteed that "reverse" would
87166124Srafan     * work.
88166124Srafan     */
89166124Srafan    if ((no_color_video & 1) == 0)
90166124Srafan	SetAttr(SP->_slk->attr, A_STANDOUT);
91166124Srafan    else
92166124Srafan	SetAttr(SP->_slk->attr, A_REVERSE);
9350276Speter
94166124Srafan    SP->_slk->maxlab = ((num_labels > 0)
95166124Srafan			? num_labels
96176187Srafan			: MAX_SKEY(_nc_globals.slk_format));
97166124Srafan    SP->_slk->maxlen = ((num_labels > 0)
98166124Srafan			? label_width * label_height
99176187Srafan			: MAX_SKEY_LEN(_nc_globals.slk_format));
100176187Srafan    SP->_slk->labcnt = ((SP->_slk->maxlab < MAX_SKEY(_nc_globals.slk_format))
101176187Srafan			? MAX_SKEY(_nc_globals.slk_format)
102166124Srafan			: SP->_slk->maxlab);
10350276Speter
104166124Srafan    if (SP->_slk->maxlen <= 0
105166124Srafan	|| SP->_slk->labcnt <= 0
106166124Srafan	|| (SP->_slk->ent = typeCalloc(slk_ent,
107166124Srafan				       (unsigned) SP->_slk->labcnt)) == NULL)
108166124Srafan	returnCode(slk_failed());
10950276Speter
110166124Srafan    max_length = SP->_slk->maxlen;
11176726Speter    for (i = 0; i < SP->_slk->labcnt; i++) {
112166124Srafan	size_t used = max_length + 1;
113166124Srafan
114166124Srafan	if ((SP->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used)) == 0)
115166124Srafan	    returnCode(slk_failed());
116166124Srafan	memset(SP->_slk->ent[i].ent_text, 0, used);
117166124Srafan
118166124Srafan	if ((SP->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used)) == 0)
119166124Srafan	    returnCode(slk_failed());
120166124Srafan	memset(SP->_slk->ent[i].form_text, 0, used);
121166124Srafan
122166124Srafan	memset(SP->_slk->ent[i].form_text, ' ', max_length);
123184989Srafan	SP->_slk->ent[i].visible = (char) (i < SP->_slk->maxlab);
12476726Speter    }
125176187Srafan    if (_nc_globals.slk_format >= 3) {	/* PC style */
126166124Srafan	int gap = (cols - 3 * (3 + 4 * max_length)) / 2;
12750276Speter
12876726Speter	if (gap < 1)
12976726Speter	    gap = 1;
13050276Speter
13176726Speter	for (i = x = 0; i < SP->_slk->maxlab; i++) {
132166124Srafan	    SP->_slk->ent[i].ent_x = x;
133166124Srafan	    x += max_length;
13476726Speter	    x += (i == 3 || i == 7) ? gap : 1;
13576726Speter	}
13676726Speter    } else {
137176187Srafan	if (_nc_globals.slk_format == 2) {	/* 4-4 */
138166124Srafan	    int gap = cols - (SP->_slk->maxlab * max_length) - 6;
13950276Speter
14050276Speter	    if (gap < 1)
14176726Speter		gap = 1;
14250276Speter	    for (i = x = 0; i < SP->_slk->maxlab; i++) {
143166124Srafan		SP->_slk->ent[i].ent_x = x;
144166124Srafan		x += max_length;
14576726Speter		x += (i == 3) ? gap : 1;
14650276Speter	    }
14776726Speter	} else {
148176187Srafan	    if (_nc_globals.slk_format == 1) {	/* 1 -> 3-2-3 */
149166124Srafan		int gap = (cols - (SP->_slk->maxlab * max_length) - 5)
15076726Speter		/ 2;
15150276Speter
15250276Speter		if (gap < 1)
15376726Speter		    gap = 1;
15450276Speter		for (i = x = 0; i < SP->_slk->maxlab; i++) {
155166124Srafan		    SP->_slk->ent[i].ent_x = x;
156166124Srafan		    x += max_length;
15776726Speter		    x += (i == 2 || i == 4) ? gap : 1;
15850276Speter		}
15976726Speter	    } else
160166124Srafan		returnCode(slk_failed());
16150276Speter	}
16276726Speter    }
16376726Speter    SP->_slk->dirty = TRUE;
16476726Speter    if ((SP->_slk->win = stwin) == NULL) {
165166124Srafan	returnCode(slk_failed());
16676726Speter    }
16750276Speter
16876726Speter    /* We now reset the format so that the next newterm has again
16976726Speter     * per default no SLK keys and may call slk_init again to
17076726Speter     * define a new layout. (juergen 03-Mar-1999)
17176726Speter     */
172176187Srafan    SP->slk_format = _nc_globals.slk_format;
173176187Srafan    _nc_globals.slk_format = 0;
174166124Srafan    returnCode(res);
17550276Speter}
17650276Speter
17750276Speter/*
17850276Speter * Restore the soft labels on the screen.
17950276Speter */
18076726SpeterNCURSES_EXPORT(int)
18150276Speterslk_restore(void)
18250276Speter{
18376726Speter    T((T_CALLED("slk_restore()")));
18450276Speter
18576726Speter    if (SP->_slk == NULL)
18676726Speter	return (ERR);
18776726Speter    SP->_slk->hidden = FALSE;
18876726Speter    SP->_slk->dirty = TRUE;
18950276Speter
19076726Speter    returnCode(slk_refresh());
19150276Speter}
192