lib_slk.c revision 166124
150276Speter/****************************************************************************
2166124Srafan * Copyright (c) 1998-2004,2005 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
48166124SrafanMODULE_ID("$Id: lib_slk.c,v 1.30 2005/01/08 21:56:36 tom Exp $")
4950276Speter
5050276Speter/*
5150276Speter * We'd like to move these into the screen context structure, but cannot,
5250276Speter * because slk_init() is called before initscr()/newterm().
5350276Speter */
5476726SpeterNCURSES_EXPORT_VAR(int)
5576726Speter_nc_slk_format = 0;		/* one more than format specified in slk_init() */
5650276Speter
5750276Speter/*
5850276Speter * Paint the info line for the PC style SLK emulation.
5950276Speter *
6050276Speter */
61166124Srafanstatic void
62166124Srafanslk_paint_info(WINDOW *win)
6350276Speter{
6476726Speter    if (win && SP->slk_format == 4) {
6576726Speter	int i;
6650276Speter
6776726Speter	mvwhline(win, 0, 0, 0, getmaxx(win));
6876726Speter	wmove(win, 0, 0);
6950276Speter
7076726Speter	for (i = 0; i < SP->_slk->maxlab; i++) {
71166124Srafan	    mvwprintw(win, 0, SP->_slk->ent[i].ent_x, "F%d", i + 1);
7276726Speter	}
7350276Speter    }
7450276Speter}
7550276Speter
7650276Speter/*
77166124Srafan * Free any memory related to soft labels, return an error.
78166124Srafan */
79166124Srafanstatic int
80166124Srafanslk_failed(void)
81166124Srafan{
82166124Srafan    if (SP->_slk) {
83166124Srafan	FreeIfNeeded(SP->_slk->ent);
84166124Srafan	free(SP->_slk);
85166124Srafan	SP->_slk = (SLK *) 0;
86166124Srafan    }
87166124Srafan    return ERR;
88166124Srafan}
89166124Srafan
90166124Srafan/*
9150276Speter * Initialize soft labels.
9250276Speter * Called from newterm()
9350276Speter */
9476726SpeterNCURSES_EXPORT(int)
9550276Speter_nc_slk_initialize(WINDOW *stwin, int cols)
9650276Speter{
9776726Speter    int i, x;
9876726Speter    int res = OK;
99166124Srafan    unsigned max_length;
10050276Speter
101166124Srafan    T((T_CALLED("_nc_slk_initialize()")));
10250276Speter
10376726Speter    if (SP->_slk) {		/* we did this already, so simply return */
104166124Srafan	returnCode(OK);
10576726Speter    } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0)
106166124Srafan	returnCode(ERR);
10750276Speter
10876726Speter    SP->_slk->ent = NULL;
10950276Speter
110166124Srafan    /*
111166124Srafan     * If we use colors, vidputs() will suppress video attributes that conflict
112166124Srafan     * with colors.  In that case, we're still guaranteed that "reverse" would
113166124Srafan     * work.
114166124Srafan     */
115166124Srafan    if ((no_color_video & 1) == 0)
116166124Srafan	SetAttr(SP->_slk->attr, A_STANDOUT);
117166124Srafan    else
118166124Srafan	SetAttr(SP->_slk->attr, A_REVERSE);
11950276Speter
120166124Srafan    SP->_slk->maxlab = ((num_labels > 0)
121166124Srafan			? num_labels
122166124Srafan			: MAX_SKEY(_nc_slk_format));
123166124Srafan    SP->_slk->maxlen = ((num_labels > 0)
124166124Srafan			? label_width * label_height
125166124Srafan			: MAX_SKEY_LEN(_nc_slk_format));
126166124Srafan    SP->_slk->labcnt = ((SP->_slk->maxlab < MAX_SKEY(_nc_slk_format))
127166124Srafan			? MAX_SKEY(_nc_slk_format)
128166124Srafan			: SP->_slk->maxlab);
12950276Speter
130166124Srafan    if (SP->_slk->maxlen <= 0
131166124Srafan	|| SP->_slk->labcnt <= 0
132166124Srafan	|| (SP->_slk->ent = typeCalloc(slk_ent,
133166124Srafan				       (unsigned) SP->_slk->labcnt)) == NULL)
134166124Srafan	returnCode(slk_failed());
13550276Speter
136166124Srafan    max_length = SP->_slk->maxlen;
13776726Speter    for (i = 0; i < SP->_slk->labcnt; i++) {
138166124Srafan	size_t used = max_length + 1;
139166124Srafan
140166124Srafan	if ((SP->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used)) == 0)
141166124Srafan	    returnCode(slk_failed());
142166124Srafan	memset(SP->_slk->ent[i].ent_text, 0, used);
143166124Srafan
144166124Srafan	if ((SP->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used)) == 0)
145166124Srafan	    returnCode(slk_failed());
146166124Srafan	memset(SP->_slk->ent[i].form_text, 0, used);
147166124Srafan
148166124Srafan	memset(SP->_slk->ent[i].form_text, ' ', max_length);
14976726Speter	SP->_slk->ent[i].visible = (i < SP->_slk->maxlab);
15076726Speter    }
15176726Speter    if (_nc_slk_format >= 3) {	/* PC style */
152166124Srafan	int gap = (cols - 3 * (3 + 4 * max_length)) / 2;
15350276Speter
15476726Speter	if (gap < 1)
15576726Speter	    gap = 1;
15650276Speter
15776726Speter	for (i = x = 0; i < SP->_slk->maxlab; i++) {
158166124Srafan	    SP->_slk->ent[i].ent_x = x;
159166124Srafan	    x += max_length;
16076726Speter	    x += (i == 3 || i == 7) ? gap : 1;
16176726Speter	}
162166124Srafan	slk_paint_info(stwin);
16376726Speter    } else {
16476726Speter	if (_nc_slk_format == 2) {	/* 4-4 */
165166124Srafan	    int gap = cols - (SP->_slk->maxlab * max_length) - 6;
16650276Speter
16750276Speter	    if (gap < 1)
16876726Speter		gap = 1;
16950276Speter	    for (i = x = 0; i < SP->_slk->maxlab; i++) {
170166124Srafan		SP->_slk->ent[i].ent_x = x;
171166124Srafan		x += max_length;
17276726Speter		x += (i == 3) ? gap : 1;
17350276Speter	    }
17476726Speter	} else {
17576726Speter	    if (_nc_slk_format == 1) {	/* 1 -> 3-2-3 */
176166124Srafan		int gap = (cols - (SP->_slk->maxlab * max_length) - 5)
17776726Speter		/ 2;
17850276Speter
17950276Speter		if (gap < 1)
18076726Speter		    gap = 1;
18150276Speter		for (i = x = 0; i < SP->_slk->maxlab; i++) {
182166124Srafan		    SP->_slk->ent[i].ent_x = x;
183166124Srafan		    x += max_length;
18476726Speter		    x += (i == 2 || i == 4) ? gap : 1;
18550276Speter		}
18676726Speter	    } else
187166124Srafan		returnCode(slk_failed());
18850276Speter	}
18976726Speter    }
19076726Speter    SP->_slk->dirty = TRUE;
19176726Speter    if ((SP->_slk->win = stwin) == NULL) {
192166124Srafan	returnCode(slk_failed());
19376726Speter    }
19450276Speter
19576726Speter    /* We now reset the format so that the next newterm has again
19676726Speter     * per default no SLK keys and may call slk_init again to
19776726Speter     * define a new layout. (juergen 03-Mar-1999)
19876726Speter     */
19976726Speter    SP->slk_format = _nc_slk_format;
20076726Speter    _nc_slk_format = 0;
201166124Srafan    returnCode(res);
20250276Speter}
20350276Speter
20450276Speter/*
20550276Speter * Restore the soft labels on the screen.
20650276Speter */
20776726SpeterNCURSES_EXPORT(int)
20850276Speterslk_restore(void)
20950276Speter{
21076726Speter    T((T_CALLED("slk_restore()")));
21150276Speter
21276726Speter    if (SP->_slk == NULL)
21376726Speter	return (ERR);
21476726Speter    SP->_slk->hidden = FALSE;
21576726Speter    SP->_slk->dirty = TRUE;
21676726Speter    /* we have to repaint info line eventually */
21776726Speter    slk_paint_info(SP->_slk->win);
21850276Speter
21976726Speter    returnCode(slk_refresh());
22050276Speter}
221