xref: /openbsd/lib/libcurses/tinfo/lib_data.c (revision 73471bf0)
1 /* $OpenBSD: lib_data.c,v 1.4 2010/01/12 23:22:06 nicm Exp $ */
2 
3 /****************************************************************************
4  * Copyright (c) 1998-2007,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_data.c
39 **
40 **	Common data that may/may not be allocated, but is referenced globally
41 **
42 */
43 
44 #include <curses.priv.h>
45 
46 MODULE_ID("$Id: lib_data.c,v 1.4 2010/01/12 23:22:06 nicm Exp $")
47 
48 /*
49  * OS/2's native linker complains if we don't initialize public data when
50  * constructing a dll (reported by J.J.G.Ripoll).
51  */
52 #if USE_REENTRANT
53 NCURSES_EXPORT(WINDOW *)
54 NCURSES_PUBLIC_VAR(stdscr) (void)
55 {
56     return SP ? SP->_stdscr : 0;
57 }
58 NCURSES_EXPORT(WINDOW *)
59 NCURSES_PUBLIC_VAR(curscr) (void)
60 {
61     return SP ? SP->_curscr : 0;
62 }
63 NCURSES_EXPORT(WINDOW *)
64 NCURSES_PUBLIC_VAR(newscr) (void)
65 {
66     return SP ? SP->_newscr : 0;
67 }
68 #else
69 NCURSES_EXPORT_VAR(WINDOW *) stdscr = 0;
70 NCURSES_EXPORT_VAR(WINDOW *) curscr = 0;
71 NCURSES_EXPORT_VAR(WINDOW *) newscr = 0;
72 #endif
73 
74 NCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain = 0;
75 
76 /*
77  * The variable 'SP' will be defined as a function on systems that cannot link
78  * data-only modules, since it is used in a lot of places within ncurses and we
79  * cannot guarantee that any application will use any particular function.  We
80  * put the WINDOW variables in this module, because it appears that any
81  * application that uses them will also use 'SP'.
82  *
83  * This module intentionally does not reference other ncurses modules, to avoid
84  * module coupling that increases the size of the executable.
85  */
86 #if BROKEN_LINKER
87 static SCREEN *my_screen;
88 
89 NCURSES_EXPORT(SCREEN *)
90 _nc_screen(void)
91 {
92     return my_screen;
93 }
94 
95 NCURSES_EXPORT(int)
96 _nc_alloc_screen(void)
97 {
98     return ((my_screen = typeCalloc(SCREEN, 1)) != 0);
99 }
100 
101 NCURSES_EXPORT(void)
102 _nc_set_screen(SCREEN *sp)
103 {
104     my_screen = sp;
105 }
106 
107 #else
108 NCURSES_EXPORT_VAR(SCREEN *) SP = NULL; /* Some linkers require initialized data... */
109 #endif
110 /* *INDENT-OFF* */
111 #define CHARS_0s { '\0' }
112 
113 #define TGETENT_0 { 0L, FALSE, NULL, NULL, NULL }
114 #define TGETENT_0s { TGETENT_0, TGETENT_0, TGETENT_0, TGETENT_0 }
115 
116 NCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
117     0,				/* have_sigwinch */
118     0,				/* cleanup_nested */
119 
120     FALSE,			/* init_signals */
121     FALSE,			/* init_screen */
122 
123     NULL,			/* comp_sourcename */
124     NULL,			/* comp_termtype */
125 
126     FALSE,			/* have_tic_directory */
127     FALSE,			/* keep_tic_directory */
128     TERMINFO,			/* tic_directory */
129 
130     NULL,			/* dbi_list */
131     0,				/* dbi_size */
132 
133     NULL,			/* first_name */
134     NULL,			/* keyname_table */
135 
136     0,				/* slk_format */
137 
138     NULL,			/* safeprint_buf */
139     0,				/* safeprint_used */
140 
141     TGETENT_0s,			/* tgetent_cache */
142     0,				/* tgetent_index */
143     0,				/* tgetent_sequence */
144 
145     0,				/* _nc_windowlist */
146 
147 #if USE_HOME_TERMINFO
148     NULL,			/* home_terminfo */
149 #endif
150 
151 #if !USE_SAFE_SPRINTF
152     0,				/* safeprint_cols */
153     0,				/* safeprint_rows */
154 #endif
155 
156 #ifdef TRACE
157     FALSE,			/* init_trace */
158     CHARS_0s,			/* trace_fname */
159     0,				/* trace_level */
160     NULL,			/* trace_fp */
161 
162     NULL,			/* tracearg_buf */
163     0,				/* tracearg_used */
164 
165     NULL,			/* tracebuf_ptr */
166     0,				/* tracebuf_used */
167 
168     CHARS_0s,			/* tracechr_buf */
169 
170     NULL,			/* tracedmp_buf */
171     0,				/* tracedmp_used */
172 
173     NULL,			/* tracetry_buf */
174     0,				/* tracetry_used */
175 
176     { CHARS_0s, CHARS_0s },	/* traceatr_color_buf */
177     0,				/* traceatr_color_sel */
178     -1,				/* traceatr_color_last */
179 
180 #endif /* TRACE */
181 #ifdef USE_PTHREADS
182     PTHREAD_MUTEX_INITIALIZER,	/* mutex_curses */
183     PTHREAD_MUTEX_INITIALIZER,	/* mutex_tst_tracef */
184     PTHREAD_MUTEX_INITIALIZER,	/* mutex_tracef */
185     0,				/* nested_tracef */
186     0,				/* use_pthreads */
187 #endif
188 };
189 
190 #define STACK_FRAME_0	{ { 0 }, 0 }
191 #define STACK_FRAME_0s	{ STACK_FRAME_0 }
192 #define NUM_VARS_0s	{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
193 
194 #define RIPOFF_0	{ 0,0,0 }
195 #define RIPOFF_0s	{ RIPOFF_0 }
196 
197 NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = {
198     TRUE,			/* use_env */
199     FALSE,			/* filter_mode */
200     A_NORMAL,			/* previous_attr */
201     RIPOFF_0s,			/* ripoff */
202     NULL,			/* rsp */
203     {				/* tparm_state */
204 #ifdef TRACE
205 	NULL,			/* tname */
206 #endif
207 	NULL,			/* tparam_base */
208 
209 	STACK_FRAME_0s,		/* stack */
210 	0,			/* stack_ptr */
211 
212 	NULL,			/* out_buff */
213 	0,			/* out_size */
214 	0,			/* out_used */
215 
216 	NULL,			/* fmt_buff */
217 	0,			/* fmt_size */
218 
219 	NUM_VARS_0s,		/* dynamic_var */
220 	NUM_VARS_0s,		/* static_vars */
221     },
222     NULL,			/* saved_tty */
223 #if NCURSES_NO_PADDING
224     FALSE,			/* flag to set if padding disabled  */
225 #endif
226 #if BROKEN_LINKER || USE_REENTRANT
227     NULL,			/* real_acs_map */
228     0,				/* LINES */
229     0,				/* COLS */
230     0,				/* cur_term */
231 #ifdef TRACE
232     0L,				/* _outchars */
233     NULL,			/* _tputs_trace */
234 #endif
235 #endif
236 };
237 /* *INDENT-ON* */
238 
239 /******************************************************************************/
240 #ifdef USE_PTHREADS
241 static void
242 init_global_mutexes(void)
243 {
244     static bool initialized = FALSE;
245 
246     if (!initialized) {
247 	initialized = TRUE;
248 	_nc_mutex_init(&_nc_globals.mutex_curses);
249 	_nc_mutex_init(&_nc_globals.mutex_tst_tracef);
250 	_nc_mutex_init(&_nc_globals.mutex_tracef);
251     }
252 }
253 
254 NCURSES_EXPORT(void)
255 _nc_init_pthreads(void)
256 {
257     if (_nc_use_pthreads)
258 	return;
259 # if USE_WEAK_SYMBOLS
260     if ((pthread_mutex_init) == 0)
261 	return;
262     if ((pthread_mutex_lock) == 0)
263 	return;
264     if ((pthread_mutex_unlock) == 0)
265 	return;
266     if ((pthread_mutex_trylock) == 0)
267 	return;
268     if ((pthread_mutexattr_settype) == 0)
269 	return;
270 # endif
271     _nc_use_pthreads = 1;
272     init_global_mutexes();
273 }
274 
275 /*
276  * Use recursive mutexes if we have them - they're part of Unix98.
277  * For the cases where we do not, _nc_mutex_trylock() is used to avoid a
278  * deadlock, at the expense of memory leaks and unexpected failures that
279  * may not be handled by typical clients.
280  *
281  * FIXME - need configure check for PTHREAD_MUTEX_RECURSIVE, define it to
282  * PTHREAD_MUTEX_NORMAL if not supported.
283  */
284 NCURSES_EXPORT(void)
285 _nc_mutex_init(pthread_mutex_t * obj)
286 {
287     pthread_mutexattr_t recattr;
288 
289     if (_nc_use_pthreads) {
290 	pthread_mutexattr_init(&recattr);
291 	pthread_mutexattr_settype(&recattr, PTHREAD_MUTEX_RECURSIVE);
292 	pthread_mutex_init(obj, &recattr);
293     }
294 }
295 
296 NCURSES_EXPORT(int)
297 _nc_mutex_lock(pthread_mutex_t * obj)
298 {
299     if (_nc_use_pthreads == 0)
300 	return 0;
301     return pthread_mutex_lock(obj);
302 }
303 
304 NCURSES_EXPORT(int)
305 _nc_mutex_trylock(pthread_mutex_t * obj)
306 {
307     if (_nc_use_pthreads == 0)
308 	return 0;
309     return pthread_mutex_trylock(obj);
310 }
311 
312 NCURSES_EXPORT(int)
313 _nc_mutex_unlock(pthread_mutex_t * obj)
314 {
315     if (_nc_use_pthreads == 0)
316 	return 0;
317     return pthread_mutex_unlock(obj);
318 }
319 
320 #if USE_WEAK_SYMBOLS
321 /*
322  * NB: sigprocmask(2) is global but pthread_sigmask(3p)
323  * only for the calling thread.
324  */
325 NCURSES_EXPORT(int)
326 _nc_sigprocmask(int how, const sigset_t * newmask, sigset_t * oldmask)
327 {
328     if ((pthread_sigmask))
329 	return pthread_sigmask(how, newmask, oldmask);
330     else
331 	return sigprocmask(how, newmask, oldmask);
332 }
333 #endif
334 #endif /* USE_PTHREADS */
335