lib_options.c revision 262629
1/****************************************************************************
2 * Copyright (c) 1998-2008,2009 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 *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
31 *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32 *     and: Thomas E. Dickey                        1996-on                 *
33 *     and: Juergen Pfeifer                         2009                    *
34 ****************************************************************************/
35
36/*
37**	lib_options.c
38**
39**	The routines to handle option setting.
40**
41*/
42
43#include <curses.priv.h>
44
45#ifndef CUR
46#define CUR SP_TERMTYPE
47#endif
48
49MODULE_ID("$Id: lib_options.c,v 1.71 2009/10/24 21:56:15 tom Exp $")
50
51NCURSES_EXPORT(int)
52idlok(WINDOW *win, bool flag)
53{
54    int res = ERR;
55    T((T_CALLED("idlok(%p,%d)"), (void *) win, flag));
56
57    if (win) {
58	SCREEN *sp = _nc_screen_of(win);
59	if (sp && IsTermInfo(sp)) {
60	    sp->_nc_sp_idlok =
61		win->_idlok = (flag && (NCURSES_SP_NAME(has_il) (NCURSES_SP_ARG)
62					|| change_scroll_region));
63	    res = OK;
64	}
65    }
66    returnCode(res);
67}
68
69NCURSES_EXPORT(void)
70idcok(WINDOW *win, bool flag)
71{
72    T((T_CALLED("idcok(%p,%d)"), (void *) win, flag));
73
74    if (win) {
75	SCREEN *sp = _nc_screen_of(win);
76	sp->_nc_sp_idcok = win->_idcok = (flag && NCURSES_SP_NAME(has_ic) (NCURSES_SP_ARG));
77    }
78    returnVoid;
79}
80
81NCURSES_EXPORT(int)
82NCURSES_SP_NAME(halfdelay) (NCURSES_SP_DCLx int t)
83{
84    T((T_CALLED("halfdelay(%p,%d)"), (void *) SP_PARM, t));
85
86    if (t < 1 || t > 255 || !IsValidTIScreen(SP_PARM))
87	returnCode(ERR);
88
89    NCURSES_SP_NAME(cbreak) (NCURSES_SP_ARG);
90    SP_PARM->_cbreak = t + 1;
91    returnCode(OK);
92}
93
94#if NCURSES_SP_FUNCS
95NCURSES_EXPORT(int)
96halfdelay(int t)
97{
98    return NCURSES_SP_NAME(halfdelay) (CURRENT_SCREEN, t);
99}
100#endif
101
102NCURSES_EXPORT(int)
103nodelay(WINDOW *win, bool flag)
104{
105    T((T_CALLED("nodelay(%p,%d)"), (void *) win, flag));
106
107    if (win) {
108	if (flag == TRUE)
109	    win->_delay = 0;
110	else
111	    win->_delay = -1;
112	returnCode(OK);
113    } else
114	returnCode(ERR);
115}
116
117NCURSES_EXPORT(int)
118notimeout(WINDOW *win, bool f)
119{
120    T((T_CALLED("notimeout(%p,%d)"), (void *) win, f));
121
122    if (win) {
123	win->_notimeout = f;
124	returnCode(OK);
125    } else
126	returnCode(ERR);
127}
128
129NCURSES_EXPORT(void)
130wtimeout(WINDOW *win, int delay)
131{
132    T((T_CALLED("wtimeout(%p,%d)"), (void *) win, delay));
133
134    if (win) {
135	win->_delay = delay;
136    }
137    returnVoid;
138}
139
140NCURSES_EXPORT(int)
141keypad(WINDOW *win, bool flag)
142{
143    T((T_CALLED("keypad(%p,%d)"), (void *) win, flag));
144
145    if (win) {
146	win->_use_keypad = flag;
147	returnCode(_nc_keypad(_nc_screen_of(win), flag));
148    } else
149	returnCode(ERR);
150}
151
152NCURSES_EXPORT(int)
153meta(WINDOW *win GCC_UNUSED, bool flag)
154{
155    int result = ERR;
156    SCREEN *sp = (win == 0) ? CURRENT_SCREEN : _nc_screen_of(win);
157
158    /* Ok, we stay relaxed and don't signal an error if win is NULL */
159    T((T_CALLED("meta(%p,%d)"), (void *) win, flag));
160
161    /* Ok, we stay relaxed and don't signal an error if win is NULL */
162
163    if (sp != 0) {
164	sp->_use_meta = flag;
165#ifdef USE_TERM_DRIVER
166	if (IsTermInfo(sp)) {
167	    if (flag) {
168		NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_ARGx "meta_on", meta_on);
169	    } else {
170		NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_ARGx "meta_off", meta_off);
171	    }
172	}
173#else
174	if (flag) {
175	    NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_ARGx "meta_on", meta_on);
176	} else {
177	    NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_ARGx "meta_off", meta_off);
178	}
179#endif
180	result = OK;
181    }
182    returnCode(result);
183}
184
185/* curs_set() moved here to narrow the kernel interface */
186
187NCURSES_EXPORT(int)
188NCURSES_SP_NAME(curs_set) (NCURSES_SP_DCLx int vis)
189{
190    int code = ERR;
191    T((T_CALLED("curs_set(%p,%d)"), (void *) SP_PARM, vis));
192
193    if (SP_PARM != 0 && vis >= 0 && vis <= 2) {
194	int cursor = SP_PARM->_cursor;
195	bool bBuiltIn = !IsTermInfo(SP_PARM);
196	if (vis == cursor) {
197	    code = cursor;
198	} else {
199	    if (!bBuiltIn) {
200		switch (vis) {
201		case 2:
202		    code = NCURSES_SP_NAME(_nc_putp_flush) (NCURSES_SP_ARGx
203							    "cursor_visible",
204							    cursor_visible);
205		    break;
206		case 1:
207		    code = NCURSES_SP_NAME(_nc_putp_flush) (NCURSES_SP_ARGx
208							    "cursor_normal",
209							    cursor_normal);
210		    break;
211		case 0:
212		    code = NCURSES_SP_NAME(_nc_putp_flush) (NCURSES_SP_ARGx
213							    "cursor_invisible",
214							    cursor_invisible);
215		    break;
216		}
217	    } else
218		code = ERR;
219	    if (code != ERR)
220		code = (cursor == -1 ? 1 : cursor);
221	    SP_PARM->_cursor = vis;
222	}
223    }
224    returnCode(code);
225}
226
227#if NCURSES_SP_FUNCS
228NCURSES_EXPORT(int)
229curs_set(int vis)
230{
231    return (NCURSES_SP_NAME(curs_set) (CURRENT_SCREEN, vis));
232}
233#endif
234
235NCURSES_EXPORT(int)
236NCURSES_SP_NAME(typeahead) (NCURSES_SP_DCLx int fd)
237{
238    T((T_CALLED("typeahead(%p, %d)"), (void *) SP_PARM, fd));
239    if (IsValidTIScreen(SP_PARM)) {
240	SP_PARM->_checkfd = fd;
241	returnCode(OK);
242    } else {
243	returnCode(ERR);
244    }
245}
246
247#if NCURSES_SP_FUNCS
248NCURSES_EXPORT(int)
249typeahead(int fd)
250{
251    return NCURSES_SP_NAME(typeahead) (CURRENT_SCREEN, fd);
252}
253#endif
254
255/*
256**      has_key()
257**
258**      Return TRUE if the current terminal has the given key
259**
260*/
261
262#if NCURSES_EXT_FUNCS
263static int
264has_key_internal(int keycode, TRIES * tp)
265{
266    if (tp == 0)
267	return (FALSE);
268    else if (tp->value == keycode)
269	return (TRUE);
270    else
271	return (has_key_internal(keycode, tp->child)
272		|| has_key_internal(keycode, tp->sibling));
273}
274
275#ifdef USE_TERM_DRIVER
276NCURSES_EXPORT(int)
277TINFO_HAS_KEY(SCREEN *sp, int keycode)
278{
279    return IsValidTIScreen(sp) ?
280	has_key_internal(keycode, sp->_keytry) : 0;
281}
282#else
283NCURSES_EXPORT(int)
284NCURSES_SP_NAME(has_key) (NCURSES_SP_DCLx int keycode)
285{
286    T((T_CALLED("has_key(%p,%d)"), (void *) SP_PARM, keycode));
287    returnCode(SP != 0 ? has_key_internal(keycode, SP_PARM->_keytry) : FALSE);
288}
289
290#if NCURSES_SP_FUNCS
291NCURSES_EXPORT(int)
292has_key(int keycode)
293{
294    return NCURSES_SP_NAME(has_key) (CURRENT_SCREEN, keycode);
295}
296#endif
297#endif
298#endif /* NCURSES_EXT_FUNCS */
299
300NCURSES_EXPORT(int)
301NCURSES_SP_NAME(_nc_putp_flush) (NCURSES_SP_DCLx
302				 const char *name, const char *value)
303{
304    int rc = NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_ARGx name, value);
305    if (rc != ERR) {
306	_nc_flush();
307    }
308    return rc;
309}
310
311#if 0 && NCURSES_SP_FUNCS
312NCURSES_EXPORT(int)
313_nc_putp_flush(const char *name, const char *value)
314{
315    return NCURSES_SP_NAME(_nc_putp_flush) (CURRENT_SCREEN, name, value);
316}
317#endif
318
319/* Turn the keypad on/off
320 *
321 * Note:  we flush the output because changing this mode causes some terminals
322 * to emit different escape sequences for cursor and keypad keys.  If we don't
323 * flush, then the next wgetch may get the escape sequence that corresponds to
324 * the terminal state _before_ switching modes.
325 */
326NCURSES_EXPORT(int)
327_nc_keypad(SCREEN *sp, bool flag)
328{
329    int rc = ERR;
330
331    if (sp != 0) {
332#ifdef USE_PTHREADS
333	/*
334	 * We might have this situation in a multithreaded application that
335	 * has wgetch() reading in more than one thread.  putp() and below
336	 * may use SP explicitly.
337	 */
338	if (_nc_use_pthreads && sp != CURRENT_SCREEN) {
339	    SCREEN *save_sp;
340
341	    /* cannot use use_screen(), since that is not in tinfo library */
342	    _nc_lock_global(curses);
343	    save_sp = CURRENT_SCREEN;
344	    _nc_set_screen(sp);
345	    rc = _nc_keypad(sp, flag);
346	    _nc_set_screen(save_sp);
347	    _nc_unlock_global(curses);
348	} else
349#endif
350	{
351#ifdef USE_TERM_DRIVER
352	    rc = CallDriver_1(sp, kpad, flag);
353	    if (rc == OK)
354		sp->_keypad_on = flag;
355#else
356	    if (flag) {
357		(void) NCURSES_SP_NAME(_nc_putp_flush) (NCURSES_SP_ARGx
358							"keypad_xmit",
359							keypad_xmit);
360	    } else if (!flag && keypad_local) {
361		(void) NCURSES_SP_NAME(_nc_putp_flush) (NCURSES_SP_ARGx
362							"keypad_local",
363							keypad_local);
364	    }
365
366	    if (flag && !sp->_tried) {
367		_nc_init_keytry(sp);
368		sp->_tried = TRUE;
369	    }
370	    sp->_keypad_on = flag;
371	    rc = OK;
372#endif
373	}
374    }
375    return (rc);
376}
377