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