xref: /openbsd/lib/libcurses/tinfo/lib_options.c (revision 09467b48)
1 /* $OpenBSD: lib_options.c,v 1.10 2010/01/12 23:22:06 nicm Exp $ */
2 
3 /****************************************************************************
4  * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
5  *                                                                          *
6  * Permission is hereby granted, free of charge, to any person obtaining a  *
7  * copy of this software and associated documentation files (the            *
8  * "Software"), to deal in the Software without restriction, including      *
9  * without limitation the rights to use, copy, modify, merge, publish,      *
10  * distribute, distribute with modifications, sublicense, and/or sell       *
11  * copies of the Software, and to permit persons to whom the Software is    *
12  * furnished to do so, subject to the following conditions:                 *
13  *                                                                          *
14  * The above copyright notice and this permission notice shall be included  *
15  * in all copies or substantial portions of the Software.                   *
16  *                                                                          *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
20  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
23  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
24  *                                                                          *
25  * Except as contained in this notice, the name(s) of the above copyright   *
26  * holders shall not be used in advertising or otherwise to promote the     *
27  * sale, use or other dealings in this Software without prior written       *
28  * authorization.                                                           *
29  ****************************************************************************/
30 
31 /****************************************************************************
32  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
33  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
34  *     and: Thomas E. Dickey                        1996-on                 *
35  ****************************************************************************/
36 
37 /*
38 **	lib_options.c
39 **
40 **	The routines to handle option setting.
41 **
42 */
43 
44 #include <curses.priv.h>
45 
46 #include <term.h>
47 
48 MODULE_ID("$Id: lib_options.c,v 1.10 2010/01/12 23:22:06 nicm Exp $")
49 
50 static int _nc_curs_set(SCREEN *, int);
51 static int _nc_meta(SCREEN *, bool);
52 
53 NCURSES_EXPORT(int)
54 idlok(WINDOW *win, bool flag)
55 {
56     T((T_CALLED("idlok(%p,%d)"), win, flag));
57 
58     if (win) {
59 	_nc_idlok = win->_idlok = (flag && (has_il() || change_scroll_region));
60 	returnCode(OK);
61     } else
62 	returnCode(ERR);
63 }
64 
65 NCURSES_EXPORT(void)
66 idcok(WINDOW *win, bool flag)
67 {
68     T((T_CALLED("idcok(%p,%d)"), win, flag));
69 
70     if (win)
71 	_nc_idcok = win->_idcok = (flag && has_ic());
72 
73     returnVoid;
74 }
75 
76 NCURSES_EXPORT(int)
77 halfdelay(int t)
78 {
79     T((T_CALLED("halfdelay(%d)"), t));
80 
81     if (t < 1 || t > 255 || SP == 0)
82 	returnCode(ERR);
83 
84     cbreak();
85     SP->_cbreak = t + 1;
86     returnCode(OK);
87 }
88 
89 NCURSES_EXPORT(int)
90 nodelay(WINDOW *win, bool flag)
91 {
92     T((T_CALLED("nodelay(%p,%d)"), win, flag));
93 
94     if (win) {
95 	if (flag == TRUE)
96 	    win->_delay = 0;
97 	else
98 	    win->_delay = -1;
99 	returnCode(OK);
100     } else
101 	returnCode(ERR);
102 }
103 
104 NCURSES_EXPORT(int)
105 notimeout(WINDOW *win, bool f)
106 {
107     T((T_CALLED("notimeout(%p,%d)"), win, f));
108 
109     if (win) {
110 	win->_notimeout = f;
111 	returnCode(OK);
112     } else
113 	returnCode(ERR);
114 }
115 
116 NCURSES_EXPORT(void)
117 wtimeout(WINDOW *win, int delay)
118 {
119     T((T_CALLED("wtimeout(%p,%d)"), win, delay));
120 
121     if (win) {
122 	win->_delay = delay;
123     }
124     returnVoid;
125 }
126 
127 NCURSES_EXPORT(int)
128 keypad(WINDOW *win, bool flag)
129 {
130     T((T_CALLED("keypad(%p,%d)"), win, flag));
131 
132     if (win) {
133 	win->_use_keypad = flag;
134 	returnCode(_nc_keypad(SP, flag));
135     } else
136 	returnCode(ERR);
137 }
138 
139 NCURSES_EXPORT(int)
140 meta(WINDOW *win GCC_UNUSED, bool flag)
141 {
142     int result;
143 
144     /* Ok, we stay relaxed and don't signal an error if win is NULL */
145     T((T_CALLED("meta(%p,%d)"), win, flag));
146     result = _nc_meta(SP, flag);
147     returnCode(result);
148 }
149 
150 /* curs_set() moved here to narrow the kernel interface */
151 
152 NCURSES_EXPORT(int)
153 curs_set(int vis)
154 {
155     int result;
156 
157     T((T_CALLED("curs_set(%d)"), vis));
158     result = _nc_curs_set(SP, vis);
159     returnCode(result);
160 }
161 
162 NCURSES_EXPORT(int)
163 typeahead(int fd)
164 {
165     T((T_CALLED("typeahead(%d)"), fd));
166     if (SP != 0) {
167 	SP->_checkfd = fd;
168 	returnCode(OK);
169     } else {
170 	returnCode(ERR);
171     }
172 }
173 
174 /*
175 **      has_key()
176 **
177 **      Return TRUE if the current terminal has the given key
178 **
179 */
180 
181 #if NCURSES_EXT_FUNCS
182 static int
183 has_key_internal(int keycode, TRIES * tp)
184 {
185     if (tp == 0)
186 	return (FALSE);
187     else if (tp->value == keycode)
188 	return (TRUE);
189     else
190 	return (has_key_internal(keycode, tp->child)
191 		|| has_key_internal(keycode, tp->sibling));
192 }
193 
194 NCURSES_EXPORT(int)
195 has_key(int keycode)
196 {
197     T((T_CALLED("has_key(%d)"), keycode));
198     returnCode(SP != 0 ? has_key_internal(keycode, SP->_keytry) : FALSE);
199 }
200 #endif /* NCURSES_EXT_FUNCS */
201 
202 /*
203  * Internal entrypoints use SCREEN* parameter to obtain capabilities rather
204  * than cur_term.
205  */
206 #undef CUR
207 #define CUR (sp->_term)->type.
208 
209 static int
210 _nc_putp(const char *name GCC_UNUSED, const char *value)
211 {
212     int rc = ERR;
213 
214     if (value) {
215 	TPUTS_TRACE(name);
216 	rc = putp(value);
217     }
218     return rc;
219 }
220 
221 static int
222 _nc_putp_flush(const char *name, const char *value)
223 {
224     int rc = _nc_putp(name, value);
225     if (rc != ERR) {
226 	_nc_flush();
227     }
228     return rc;
229 }
230 
231 /* Turn the keypad on/off
232  *
233  * Note:  we flush the output because changing this mode causes some terminals
234  * to emit different escape sequences for cursor and keypad keys.  If we don't
235  * flush, then the next wgetch may get the escape sequence that corresponds to
236  * the terminal state _before_ switching modes.
237  */
238 NCURSES_EXPORT(int)
239 _nc_keypad(SCREEN *sp, bool flag)
240 {
241     int rc = ERR;
242 
243     if (sp != 0) {
244 #ifdef USE_PTHREADS
245 	/*
246 	 * We might have this situation in a multithreaded application that
247 	 * has wgetch() reading in more than one thread.  putp() and below
248 	 * may use SP explicitly.
249 	 */
250 	if (_nc_use_pthreads && sp != SP) {
251 	    SCREEN *save_sp;
252 
253 	    /* cannot use use_screen(), since that is not in tinfo library */
254 	    _nc_lock_global(curses);
255 	    save_sp = SP;
256 	    _nc_set_screen(sp);
257 	    rc = _nc_keypad(sp, flag);
258 	    _nc_set_screen(save_sp);
259 	    _nc_unlock_global(curses);
260 	} else
261 #endif
262 	{
263 	    if (flag) {
264 		(void) _nc_putp_flush("keypad_xmit", keypad_xmit);
265 	    } else if (!flag && keypad_local) {
266 		(void) _nc_putp_flush("keypad_local", keypad_local);
267 	    }
268 
269 	    if (flag && !sp->_tried) {
270 		_nc_init_keytry(sp);
271 		sp->_tried = TRUE;
272 	    }
273 	    sp->_keypad_on = flag;
274 	    rc = OK;
275 	}
276     }
277     return (rc);
278 }
279 
280 static int
281 _nc_curs_set(SCREEN *sp, int vis)
282 {
283     int result = ERR;
284 
285     T((T_CALLED("curs_set(%d)"), vis));
286     if (sp != 0 && vis >= 0 && vis <= 2) {
287 	int cursor = sp->_cursor;
288 
289 	if (vis == cursor) {
290 	    result = cursor;
291 	} else {
292 	    switch (vis) {
293 	    case 2:
294 		result = _nc_putp_flush("cursor_visible", cursor_visible);
295 		break;
296 	    case 1:
297 		result = _nc_putp_flush("cursor_normal", cursor_normal);
298 		break;
299 	    case 0:
300 		result = _nc_putp_flush("cursor_invisible", cursor_invisible);
301 		break;
302 	    }
303 	    if (result != ERR)
304 		result = (cursor == -1 ? 1 : cursor);
305 	    sp->_cursor = vis;
306 	}
307     }
308     returnCode(result);
309 }
310 
311 static int
312 _nc_meta(SCREEN *sp, bool flag)
313 {
314     int result = ERR;
315 
316     /* Ok, we stay relaxed and don't signal an error if win is NULL */
317 
318     if (SP != 0) {
319 	SP->_use_meta = flag;
320 
321 	if (flag) {
322 	    _nc_putp("meta_on", meta_on);
323 	} else {
324 	    _nc_putp("meta_off", meta_off);
325 	}
326 	result = OK;
327     }
328     return result;
329 }
330