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