150276Speter/****************************************************************************
2178866Srafan * Copyright (c) 1998-2006,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/****************************************************************************
3050276Speter *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3150276Speter *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32166124Srafan *     and: Thomas E. Dickey                        1996-on                 *
3350276Speter ****************************************************************************/
3450276Speter
3550276Speter/*
3650276Speter**	lib_options.c
3750276Speter**
3850276Speter**	The routines to handle option setting.
3950276Speter**
4050276Speter*/
4150276Speter
4250276Speter#include <curses.priv.h>
4350276Speter
4462449Speter#include <term.h>
4550276Speter
46184989SrafanMODULE_ID("$Id: lib_options.c,v 1.58 2008/08/16 21:20:48 Werner.Fink Exp $")
4750276Speter
48184989Srafanstatic int _nc_curs_set(SCREEN *, int);
49184989Srafanstatic int _nc_meta(SCREEN *, bool);
50184989Srafan
5176726SpeterNCURSES_EXPORT(int)
5262449Speteridlok(WINDOW *win, bool flag)
5350276Speter{
5462449Speter    T((T_CALLED("idlok(%p,%d)"), win, flag));
5550276Speter
5662449Speter    if (win) {
5762449Speter	_nc_idlok = win->_idlok = (flag && (has_il() || change_scroll_region));
5862449Speter	returnCode(OK);
5962449Speter    } else
6062449Speter	returnCode(ERR);
6150276Speter}
6250276Speter
6376726SpeterNCURSES_EXPORT(void)
6462449Speteridcok(WINDOW *win, bool flag)
6550276Speter{
6662449Speter    T((T_CALLED("idcok(%p,%d)"), win, flag));
6750276Speter
6862449Speter    if (win)
6962449Speter	_nc_idcok = win->_idcok = (flag && has_ic());
7050276Speter
7162449Speter    returnVoid;
7250276Speter}
7350276Speter
7476726SpeterNCURSES_EXPORT(int)
7562449Speterhalfdelay(int t)
7650276Speter{
7762449Speter    T((T_CALLED("halfdelay(%d)"), t));
7850276Speter
79166124Srafan    if (t < 1 || t > 255 || SP == 0)
8062449Speter	returnCode(ERR);
8150276Speter
8262449Speter    cbreak();
8362449Speter    SP->_cbreak = t + 1;
8462449Speter    returnCode(OK);
8550276Speter}
8650276Speter
8776726SpeterNCURSES_EXPORT(int)
8862449Speternodelay(WINDOW *win, bool flag)
8950276Speter{
9062449Speter    T((T_CALLED("nodelay(%p,%d)"), win, flag));
9150276Speter
9262449Speter    if (win) {
9362449Speter	if (flag == TRUE)
9450276Speter	    win->_delay = 0;
9550276Speter	else
9662449Speter	    win->_delay = -1;
9762449Speter	returnCode(OK);
9862449Speter    } else
9962449Speter	returnCode(ERR);
10050276Speter}
10150276Speter
10276726SpeterNCURSES_EXPORT(int)
10362449Speternotimeout(WINDOW *win, bool f)
10450276Speter{
105166124Srafan    T((T_CALLED("notimeout(%p,%d)"), win, f));
10650276Speter
10762449Speter    if (win) {
10862449Speter	win->_notimeout = f;
10962449Speter	returnCode(OK);
11062449Speter    } else
11162449Speter	returnCode(ERR);
11250276Speter}
11350276Speter
11476726SpeterNCURSES_EXPORT(void)
11562449Speterwtimeout(WINDOW *win, int delay)
11650276Speter{
11762449Speter    T((T_CALLED("wtimeout(%p,%d)"), win, delay));
11850276Speter
11962449Speter    if (win) {
12062449Speter	win->_delay = delay;
12162449Speter    }
12297049Speter    returnVoid;
12350276Speter}
12450276Speter
12576726SpeterNCURSES_EXPORT(int)
12662449Speterkeypad(WINDOW *win, bool flag)
12750276Speter{
12862449Speter    T((T_CALLED("keypad(%p,%d)"), win, flag));
12950276Speter
13062449Speter    if (win) {
13162449Speter	win->_use_keypad = flag;
132178866Srafan	returnCode(_nc_keypad(SP, flag));
13362449Speter    } else
13462449Speter	returnCode(ERR);
13550276Speter}
13650276Speter
13776726SpeterNCURSES_EXPORT(int)
13862449Spetermeta(WINDOW *win GCC_UNUSED, bool flag)
13950276Speter{
140184989Srafan    int result;
141166124Srafan
14262449Speter    /* Ok, we stay relaxed and don't signal an error if win is NULL */
14362449Speter    T((T_CALLED("meta(%p,%d)"), win, flag));
144184989Srafan    result = _nc_meta(SP, flag);
145166124Srafan    returnCode(result);
14650276Speter}
14750276Speter
14850276Speter/* curs_set() moved here to narrow the kernel interface */
14950276Speter
15076726SpeterNCURSES_EXPORT(int)
15162449Spetercurs_set(int vis)
15250276Speter{
153184989Srafan    int result;
15450276Speter
15562449Speter    T((T_CALLED("curs_set(%d)"), vis));
156184989Srafan    result = _nc_curs_set(SP, vis);
157166124Srafan    returnCode(result);
15850276Speter}
15950276Speter
16076726SpeterNCURSES_EXPORT(int)
16162449Spetertypeahead(int fd)
16250276Speter{
16362449Speter    T((T_CALLED("typeahead(%d)"), fd));
164166124Srafan    if (SP != 0) {
165166124Srafan	SP->_checkfd = fd;
166166124Srafan	returnCode(OK);
167166124Srafan    } else {
168166124Srafan	returnCode(ERR);
169166124Srafan    }
17050276Speter}
17150276Speter
17250276Speter/*
17350276Speter**      has_key()
17450276Speter**
17550276Speter**      Return TRUE if the current terminal has the given key
17650276Speter**
17750276Speter*/
17850276Speter
17966963Speter#if NCURSES_EXT_FUNCS
18062449Speterstatic int
181178866Srafanhas_key_internal(int keycode, TRIES * tp)
18250276Speter{
18350276Speter    if (tp == 0)
18462449Speter	return (FALSE);
18550276Speter    else if (tp->value == keycode)
18662449Speter	return (TRUE);
18750276Speter    else
18862449Speter	return (has_key_internal(keycode, tp->child)
18976726Speter		|| has_key_internal(keycode, tp->sibling));
19050276Speter}
19150276Speter
19276726SpeterNCURSES_EXPORT(int)
19362449Speterhas_key(int keycode)
19450276Speter{
19550276Speter    T((T_CALLED("has_key(%d)"), keycode));
196166124Srafan    returnCode(SP != 0 ? has_key_internal(keycode, SP->_keytry) : FALSE);
19750276Speter}
19850276Speter#endif /* NCURSES_EXT_FUNCS */
19950276Speter
200184989Srafan/*
201184989Srafan * Internal entrypoints use SCREEN* parameter to obtain capabilities rather
202184989Srafan * than cur_term.
203184989Srafan */
204184989Srafan#undef CUR
205184989Srafan#define CUR (sp->_term)->type.
206184989Srafan
207184989Srafanstatic int
208184989Srafan_nc_putp(const char *name GCC_UNUSED, const char *value)
209184989Srafan{
210184989Srafan    int rc = ERR;
211184989Srafan
212184989Srafan    if (value) {
213184989Srafan	TPUTS_TRACE(name);
214184989Srafan	rc = putp(value);
215184989Srafan    }
216184989Srafan    return rc;
217184989Srafan}
218184989Srafan
219184989Srafanstatic int
220184989Srafan_nc_putp_flush(const char *name, const char *value)
221184989Srafan{
222184989Srafan    int rc = _nc_putp(name, value);
223184989Srafan    if (rc != ERR) {
224184989Srafan	_nc_flush();
225184989Srafan    }
226184989Srafan    return rc;
227184989Srafan}
228184989Srafan
22950276Speter/* Turn the keypad on/off
23050276Speter *
23150276Speter * Note:  we flush the output because changing this mode causes some terminals
23250276Speter * to emit different escape sequences for cursor and keypad keys.  If we don't
23350276Speter * flush, then the next wgetch may get the escape sequence that corresponds to
23450276Speter * the terminal state _before_ switching modes.
23550276Speter */
23676726SpeterNCURSES_EXPORT(int)
237178866Srafan_nc_keypad(SCREEN *sp, bool flag)
23850276Speter{
239184989Srafan    int rc = ERR;
24050276Speter
241178866Srafan    if (sp != 0) {
242184989Srafan#ifdef USE_PTHREADS
243184989Srafan	/*
244184989Srafan	 * We might have this situation in a multithreaded application that
245184989Srafan	 * has wgetch() reading in more than one thread.  putp() and below
246184989Srafan	 * may use SP explicitly.
247184989Srafan	 */
248184989Srafan	if (_nc_use_pthreads && sp != SP) {
249184989Srafan	    SCREEN *save_sp;
250184989Srafan
251184989Srafan	    /* cannot use use_screen(), since that is not in tinfo library */
252184989Srafan	    _nc_lock_global(curses);
253184989Srafan	    save_sp = SP;
254184989Srafan	    _nc_set_screen(sp);
255184989Srafan	    rc = _nc_keypad(sp, flag);
256184989Srafan	    _nc_set_screen(save_sp);
257184989Srafan	    _nc_unlock_global(curses);
258184989Srafan	} else
259184989Srafan#endif
260184989Srafan	{
261184989Srafan	    if (flag) {
262184989Srafan		(void) _nc_putp_flush("keypad_xmit", keypad_xmit);
263184989Srafan	    } else if (!flag && keypad_local) {
264184989Srafan		(void) _nc_putp_flush("keypad_local", keypad_local);
265184989Srafan	    }
266184989Srafan
267184989Srafan	    if (flag && !sp->_tried) {
268184989Srafan		_nc_init_keytry(sp);
269184989Srafan		sp->_tried = TRUE;
270184989Srafan	    }
271184989Srafan	    sp->_keypad_on = flag;
272184989Srafan	    rc = OK;
273166124Srafan	}
27462449Speter    }
275184989Srafan    return (rc);
27650276Speter}
277184989Srafan
278184989Srafanstatic int
279184989Srafan_nc_curs_set(SCREEN *sp, int vis)
280184989Srafan{
281184989Srafan    int result = ERR;
282184989Srafan
283184989Srafan    T((T_CALLED("curs_set(%d)"), vis));
284184989Srafan    if (sp != 0 && vis >= 0 && vis <= 2) {
285184989Srafan	int cursor = sp->_cursor;
286184989Srafan
287184989Srafan	if (vis == cursor) {
288184989Srafan	    result = cursor;
289184989Srafan	} else {
290184989Srafan	    switch (vis) {
291184989Srafan	    case 2:
292184989Srafan		result = _nc_putp_flush("cursor_visible", cursor_visible);
293184989Srafan		break;
294184989Srafan	    case 1:
295184989Srafan		result = _nc_putp_flush("cursor_normal", cursor_normal);
296184989Srafan		break;
297184989Srafan	    case 0:
298184989Srafan		result = _nc_putp_flush("cursor_invisible", cursor_invisible);
299184989Srafan		break;
300184989Srafan	    }
301184989Srafan	    if (result != ERR)
302184989Srafan		result = (cursor == -1 ? 1 : cursor);
303184989Srafan	    sp->_cursor = vis;
304184989Srafan	}
305184989Srafan    }
306184989Srafan    returnCode(result);
307184989Srafan}
308184989Srafan
309184989Srafanstatic int
310184989Srafan_nc_meta(SCREEN *sp, bool flag)
311184989Srafan{
312184989Srafan    int result = ERR;
313184989Srafan
314184989Srafan    /* Ok, we stay relaxed and don't signal an error if win is NULL */
315184989Srafan
316184989Srafan    if (SP != 0) {
317184989Srafan	SP->_use_meta = flag;
318184989Srafan
319184989Srafan	if (flag) {
320184989Srafan	    _nc_putp("meta_on", meta_on);
321184989Srafan	} else {
322184989Srafan	    _nc_putp("meta_off", meta_off);
323184989Srafan	}
324184989Srafan	result = OK;
325184989Srafan    }
326184989Srafan    return result;
327184989Srafan}
328