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