lib_slk.c revision 76726
150276Speter/****************************************************************************
276726Speter * Copyright (c) 1998,1999,2000 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/****************************************************************************
3050276Speter *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3150276Speter *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
3250276Speter ****************************************************************************/
3350276Speter
3450276Speter/*
3550276Speter *	lib_slk.c
3650276Speter *	Soft key routines.
3750276Speter */
3850276Speter
3950276Speter#include <curses.priv.h>
4050276Speter
4150276Speter#include <ctype.h>
4276726Speter#include <term.h>		/* num_labels, label_*, plab_norm */
4350276Speter
4476726SpeterMODULE_ID("$Id: lib_slk.c,v 1.20 2000/12/10 02:43:27 tom Exp $")
4550276Speter
4650276Speter/*
4750276Speter * We'd like to move these into the screen context structure, but cannot,
4850276Speter * because slk_init() is called before initscr()/newterm().
4950276Speter */
5076726SpeterNCURSES_EXPORT_VAR(int)
5176726Speter_nc_slk_format = 0;		/* one more than format specified in slk_init() */
5250276Speter
5350276Speter/*
5450276Speter * Paint the info line for the PC style SLK emulation.
5550276Speter *
5650276Speter */
5776726Speter     static void
5876726Speter       slk_paint_info(WINDOW *win)
5950276Speter{
6076726Speter    if (win && SP->slk_format == 4) {
6176726Speter	int i;
6250276Speter
6376726Speter	mvwhline(win, 0, 0, 0, getmaxx(win));
6476726Speter	wmove(win, 0, 0);
6550276Speter
6676726Speter	for (i = 0; i < SP->_slk->maxlab; i++) {
6776726Speter	    if (win && SP->slk_format == 4) {
6876726Speter		mvwaddch(win, 0, SP->_slk->ent[i].x, (chtype) 'F');
6976726Speter		if (i < 9)
7076726Speter		    waddch(win, (chtype) '1' + i);
7176726Speter		else {
7276726Speter		    waddch(win, (chtype) '1');
7376726Speter		    waddch(win, (chtype) '0' + (i - 9));
7476726Speter		}
7576726Speter	    }
7676726Speter	}
7750276Speter    }
7850276Speter}
7950276Speter
8050276Speter/*
8150276Speter * Initialize soft labels.
8250276Speter * Called from newterm()
8350276Speter */
8476726SpeterNCURSES_EXPORT(int)
8550276Speter_nc_slk_initialize(WINDOW *stwin, int cols)
8650276Speter{
8776726Speter    int i, x;
8876726Speter    int res = OK;
8976726Speter    char *p;
9050276Speter
9176726Speter    T(("slk_initialize()"));
9250276Speter
9376726Speter    if (SP->_slk) {		/* we did this already, so simply return */
9476726Speter	return (OK);
9576726Speter    } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0)
9676726Speter	return (ERR);
9750276Speter
9876726Speter    SP->_slk->ent = NULL;
9976726Speter    SP->_slk->buffer = NULL;
10076726Speter    SP->_slk->attr = A_STANDOUT;
10150276Speter
10276726Speter    SP->_slk->maxlab = (num_labels > 0) ?
10376726Speter	num_labels : MAX_SKEY(_nc_slk_format);
10476726Speter    SP->_slk->maxlen = (num_labels > 0) ?
10576726Speter	label_width * label_height : MAX_SKEY_LEN(_nc_slk_format);
10676726Speter    SP->_slk->labcnt = (SP->_slk->maxlab < MAX_SKEY(_nc_slk_format)) ?
10776726Speter	MAX_SKEY(_nc_slk_format) : SP->_slk->maxlab;
10850276Speter
10976726Speter    SP->_slk->ent = typeCalloc(slk_ent, SP->_slk->labcnt);
11076726Speter    if (SP->_slk->ent == NULL)
11176726Speter	goto exception;
11250276Speter
11376726Speter    p = SP->_slk->buffer = (char *) calloc(2 * SP->_slk->labcnt, (1 + SP->_slk->maxlen));
11476726Speter    if (SP->_slk->buffer == NULL)
11576726Speter	goto exception;
11650276Speter
11776726Speter    for (i = 0; i < SP->_slk->labcnt; i++) {
11876726Speter	SP->_slk->ent[i].text = p;
11976726Speter	p += (1 + SP->_slk->maxlen);
12076726Speter	SP->_slk->ent[i].form_text = p;
12176726Speter	p += (1 + SP->_slk->maxlen);
12276726Speter	memset(SP->_slk->ent[i].form_text, ' ', (unsigned) (SP->_slk->maxlen));
12376726Speter	SP->_slk->ent[i].visible = (i < SP->_slk->maxlab);
12476726Speter    }
12576726Speter    if (_nc_slk_format >= 3) {	/* PC style */
12676726Speter	int gap = (cols - 3 * (3 + 4 * SP->_slk->maxlen)) / 2;
12750276Speter
12876726Speter	if (gap < 1)
12976726Speter	    gap = 1;
13050276Speter
13176726Speter	for (i = x = 0; i < SP->_slk->maxlab; i++) {
13276726Speter	    SP->_slk->ent[i].x = x;
13376726Speter	    x += SP->_slk->maxlen;
13476726Speter	    x += (i == 3 || i == 7) ? gap : 1;
13576726Speter	}
13676726Speter	if (_nc_slk_format == 4)
13776726Speter	    slk_paint_info(stwin);
13876726Speter    } else {
13976726Speter	if (_nc_slk_format == 2) {	/* 4-4 */
14050276Speter	    int gap = cols - (SP->_slk->maxlab * SP->_slk->maxlen) - 6;
14150276Speter
14250276Speter	    if (gap < 1)
14376726Speter		gap = 1;
14450276Speter	    for (i = x = 0; i < SP->_slk->maxlab; i++) {
14576726Speter		SP->_slk->ent[i].x = x;
14676726Speter		x += SP->_slk->maxlen;
14776726Speter		x += (i == 3) ? gap : 1;
14850276Speter	    }
14976726Speter	} else {
15076726Speter	    if (_nc_slk_format == 1) {	/* 1 -> 3-2-3 */
15176726Speter		int gap = (cols - (SP->_slk->maxlab * SP->_slk->maxlen) - 5)
15276726Speter		/ 2;
15350276Speter
15450276Speter		if (gap < 1)
15576726Speter		    gap = 1;
15650276Speter		for (i = x = 0; i < SP->_slk->maxlab; i++) {
15776726Speter		    SP->_slk->ent[i].x = x;
15876726Speter		    x += SP->_slk->maxlen;
15976726Speter		    x += (i == 2 || i == 4) ? gap : 1;
16050276Speter		}
16176726Speter	    } else
16250276Speter		goto exception;
16350276Speter	}
16476726Speter    }
16576726Speter    SP->_slk->dirty = TRUE;
16676726Speter    if ((SP->_slk->win = stwin) == NULL) {
16776726Speter      exception:
16876726Speter	if (SP->_slk) {
16976726Speter	    FreeIfNeeded(SP->_slk->buffer);
17076726Speter	    FreeIfNeeded(SP->_slk->ent);
17176726Speter	    free(SP->_slk);
17276726Speter	    SP->_slk = (SLK *) 0;
17376726Speter	    res = (ERR);
17450276Speter	}
17576726Speter    }
17650276Speter
17776726Speter    /* We now reset the format so that the next newterm has again
17876726Speter     * per default no SLK keys and may call slk_init again to
17976726Speter     * define a new layout. (juergen 03-Mar-1999)
18076726Speter     */
18176726Speter    SP->slk_format = _nc_slk_format;
18276726Speter    _nc_slk_format = 0;
18376726Speter    return (res);
18450276Speter}
18550276Speter
18650276Speter/*
18750276Speter * Restore the soft labels on the screen.
18850276Speter */
18976726SpeterNCURSES_EXPORT(int)
19050276Speterslk_restore(void)
19150276Speter{
19276726Speter    T((T_CALLED("slk_restore()")));
19350276Speter
19476726Speter    if (SP->_slk == NULL)
19576726Speter	return (ERR);
19676726Speter    SP->_slk->hidden = FALSE;
19776726Speter    SP->_slk->dirty = TRUE;
19876726Speter    /* we have to repaint info line eventually */
19976726Speter    slk_paint_info(SP->_slk->win);
20050276Speter
20176726Speter    returnCode(slk_refresh());
20250276Speter}
203