lib_slk.c revision 176187
1/****************************************************************************
2 * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc.              *
3 *                                                                          *
4 * Permission is hereby granted, free of charge, to any person obtaining a  *
5 * copy of this software and associated documentation files (the            *
6 * "Software"), to deal in the Software without restriction, including      *
7 * without limitation the rights to use, copy, modify, merge, publish,      *
8 * distribute, distribute with modifications, sublicense, and/or sell       *
9 * copies of the Software, and to permit persons to whom the Software is    *
10 * furnished to do so, subject to the following conditions:                 *
11 *                                                                          *
12 * The above copyright notice and this permission notice shall be included  *
13 * in all copies or substantial portions of the Software.                   *
14 *                                                                          *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22 *                                                                          *
23 * Except as contained in this notice, the name(s) of the above copyright   *
24 * holders shall not be used in advertising or otherwise to promote the     *
25 * sale, use or other dealings in this Software without prior written       *
26 * authorization.                                                           *
27 ****************************************************************************/
28
29/****************************************************************************
30 *  Authors:                                                                *
31 *          Gerhard Fuernkranz                      1993 (original)         *
32 *          Zeyd M. Ben-Halim                       1992,1995 (sic)         *
33 *          Eric S. Raymond                                                 *
34 *          Juergen Pfeifer                         1996-on                 *
35 *          Thomas E. Dickey                                                *
36 ****************************************************************************/
37
38/*
39 *	lib_slk.c
40 *	Soft key routines.
41 */
42
43#include <curses.priv.h>
44
45#include <ctype.h>
46#include <term.h>		/* num_labels, label_*, plab_norm */
47
48MODULE_ID("$Id: lib_slk.c,v 1.31 2008/01/12 20:21:00 tom Exp $")
49
50/*
51 * We'd like to move these into the screen context structure, but cannot,
52 * because slk_init() is called before initscr()/newterm().
53 */
54NCURSES_EXPORT_VAR(int)
55_nc_slk_format = 0;		/* one more than format specified in slk_init() */
56
57/*
58 * Paint the info line for the PC style SLK emulation.
59 */
60static void
61slk_paint_info(WINDOW *win)
62{
63    if (win && SP->slk_format == 4) {
64	int i;
65
66	mvwhline(win, 0, 0, 0, getmaxx(win));
67	wmove(win, 0, 0);
68
69	for (i = 0; i < SP->_slk->maxlab; i++) {
70	    mvwprintw(win, 0, SP->_slk->ent[i].ent_x, "F%d", i + 1);
71	}
72    }
73}
74
75/*
76 * Free any memory related to soft labels, return an error.
77 */
78static int
79slk_failed(void)
80{
81    if (SP->_slk) {
82	FreeIfNeeded(SP->_slk->ent);
83	free(SP->_slk);
84	SP->_slk = (SLK *) 0;
85    }
86    return ERR;
87}
88
89/*
90 * Initialize soft labels.
91 * Called from newterm()
92 */
93NCURSES_EXPORT(int)
94_nc_slk_initialize(WINDOW *stwin, int cols)
95{
96    int i, x;
97    int res = OK;
98    unsigned max_length;
99
100    T((T_CALLED("_nc_slk_initialize()")));
101
102    if (SP->_slk) {		/* we did this already, so simply return */
103	returnCode(OK);
104    } else if ((SP->_slk = typeCalloc(SLK, 1)) == 0)
105	returnCode(ERR);
106
107    SP->_slk->ent = NULL;
108
109    /*
110     * If we use colors, vidputs() will suppress video attributes that conflict
111     * with colors.  In that case, we're still guaranteed that "reverse" would
112     * work.
113     */
114    if ((no_color_video & 1) == 0)
115	SetAttr(SP->_slk->attr, A_STANDOUT);
116    else
117	SetAttr(SP->_slk->attr, A_REVERSE);
118
119    SP->_slk->maxlab = ((num_labels > 0)
120			? num_labels
121			: MAX_SKEY(_nc_globals.slk_format));
122    SP->_slk->maxlen = ((num_labels > 0)
123			? label_width * label_height
124			: MAX_SKEY_LEN(_nc_globals.slk_format));
125    SP->_slk->labcnt = ((SP->_slk->maxlab < MAX_SKEY(_nc_globals.slk_format))
126			? MAX_SKEY(_nc_globals.slk_format)
127			: SP->_slk->maxlab);
128
129    if (SP->_slk->maxlen <= 0
130	|| SP->_slk->labcnt <= 0
131	|| (SP->_slk->ent = typeCalloc(slk_ent,
132				       (unsigned) SP->_slk->labcnt)) == NULL)
133	returnCode(slk_failed());
134
135    max_length = SP->_slk->maxlen;
136    for (i = 0; i < SP->_slk->labcnt; i++) {
137	size_t used = max_length + 1;
138
139	if ((SP->_slk->ent[i].ent_text = (char *) _nc_doalloc(0, used)) == 0)
140	    returnCode(slk_failed());
141	memset(SP->_slk->ent[i].ent_text, 0, used);
142
143	if ((SP->_slk->ent[i].form_text = (char *) _nc_doalloc(0, used)) == 0)
144	    returnCode(slk_failed());
145	memset(SP->_slk->ent[i].form_text, 0, used);
146
147	memset(SP->_slk->ent[i].form_text, ' ', max_length);
148	SP->_slk->ent[i].visible = (i < SP->_slk->maxlab);
149    }
150    if (_nc_globals.slk_format >= 3) {	/* PC style */
151	int gap = (cols - 3 * (3 + 4 * max_length)) / 2;
152
153	if (gap < 1)
154	    gap = 1;
155
156	for (i = x = 0; i < SP->_slk->maxlab; i++) {
157	    SP->_slk->ent[i].ent_x = x;
158	    x += max_length;
159	    x += (i == 3 || i == 7) ? gap : 1;
160	}
161	slk_paint_info(stwin);
162    } else {
163	if (_nc_globals.slk_format == 2) {	/* 4-4 */
164	    int gap = cols - (SP->_slk->maxlab * max_length) - 6;
165
166	    if (gap < 1)
167		gap = 1;
168	    for (i = x = 0; i < SP->_slk->maxlab; i++) {
169		SP->_slk->ent[i].ent_x = x;
170		x += max_length;
171		x += (i == 3) ? gap : 1;
172	    }
173	} else {
174	    if (_nc_globals.slk_format == 1) {	/* 1 -> 3-2-3 */
175		int gap = (cols - (SP->_slk->maxlab * max_length) - 5)
176		/ 2;
177
178		if (gap < 1)
179		    gap = 1;
180		for (i = x = 0; i < SP->_slk->maxlab; i++) {
181		    SP->_slk->ent[i].ent_x = x;
182		    x += max_length;
183		    x += (i == 2 || i == 4) ? gap : 1;
184		}
185	    } else
186		returnCode(slk_failed());
187	}
188    }
189    SP->_slk->dirty = TRUE;
190    if ((SP->_slk->win = stwin) == NULL) {
191	returnCode(slk_failed());
192    }
193
194    /* We now reset the format so that the next newterm has again
195     * per default no SLK keys and may call slk_init again to
196     * define a new layout. (juergen 03-Mar-1999)
197     */
198    SP->slk_format = _nc_globals.slk_format;
199    _nc_globals.slk_format = 0;
200    returnCode(res);
201}
202
203/*
204 * Restore the soft labels on the screen.
205 */
206NCURSES_EXPORT(int)
207slk_restore(void)
208{
209    T((T_CALLED("slk_restore()")));
210
211    if (SP->_slk == NULL)
212	return (ERR);
213    SP->_slk->hidden = FALSE;
214    SP->_slk->dirty = TRUE;
215    /* we have to repaint info line eventually */
216    slk_paint_info(SP->_slk->win);
217
218    returnCode(slk_refresh());
219}
220