150276Speter/****************************************************************************
2176187Srafan * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
3050276Speter *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3150276Speter *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32166124Srafan *     and: Thomas E. Dickey                        1996-on                 *
3350276Speter ****************************************************************************/
3450276Speter
3550276Speter/*
3650276Speter**	lib_data.c
3750276Speter**
3850276Speter**	Common data that may/may not be allocated, but is referenced globally
3950276Speter**
4050276Speter*/
4150276Speter
4250276Speter#include <curses.priv.h>
4350276Speter
44184989SrafanMODULE_ID("$Id: lib_data.c,v 1.52 2008/08/23 22:16:15 tom Exp $")
4550276Speter
4650276Speter/*
4750276Speter * OS/2's native linker complains if we don't initialize public data when
4850276Speter * constructing a dll (reported by J.J.G.Ripoll).
4950276Speter */
50174993Srafan#if USE_REENTRANT
51174993SrafanNCURSES_EXPORT(WINDOW *)
52174993SrafanNCURSES_PUBLIC_VAR(stdscr) (void)
53174993Srafan{
54174993Srafan    return SP ? SP->_stdscr : 0;
55174993Srafan}
56174993SrafanNCURSES_EXPORT(WINDOW *)
57174993SrafanNCURSES_PUBLIC_VAR(curscr) (void)
58174993Srafan{
59174993Srafan    return SP ? SP->_curscr : 0;
60174993Srafan}
61174993SrafanNCURSES_EXPORT(WINDOW *)
62174993SrafanNCURSES_PUBLIC_VAR(newscr) (void)
63174993Srafan{
64174993Srafan    return SP ? SP->_newscr : 0;
65174993Srafan}
66174993Srafan#else
67166124SrafanNCURSES_EXPORT_VAR(WINDOW *) stdscr = 0;
68166124SrafanNCURSES_EXPORT_VAR(WINDOW *) curscr = 0;
69166124SrafanNCURSES_EXPORT_VAR(WINDOW *) newscr = 0;
70174993Srafan#endif
7150276Speter
7276726SpeterNCURSES_EXPORT_VAR(SCREEN *) _nc_screen_chain = 0;
7350276Speter
7450276Speter/*
7550276Speter * The variable 'SP' will be defined as a function on systems that cannot link
7650276Speter * data-only modules, since it is used in a lot of places within ncurses and we
7750276Speter * cannot guarantee that any application will use any particular function.  We
7850276Speter * put the WINDOW variables in this module, because it appears that any
7950276Speter * application that uses them will also use 'SP'.
8050276Speter *
8150276Speter * This module intentionally does not reference other ncurses modules, to avoid
8250276Speter * module coupling that increases the size of the executable.
8350276Speter */
8450276Speter#if BROKEN_LINKER
85166124Srafanstatic SCREEN *my_screen;
8650276Speter
8776726SpeterNCURSES_EXPORT(SCREEN *)
8876726Speter_nc_screen(void)
8950276Speter{
9076726Speter    return my_screen;
9150276Speter}
9250276Speter
9376726SpeterNCURSES_EXPORT(int)
9476726Speter_nc_alloc_screen(void)
9550276Speter{
9676726Speter    return ((my_screen = typeCalloc(SCREEN, 1)) != 0);
9750276Speter}
9850276Speter
9976726SpeterNCURSES_EXPORT(void)
100166124Srafan_nc_set_screen(SCREEN *sp)
10150276Speter{
10276726Speter    my_screen = sp;
10350276Speter}
10476726Speter
10550276Speter#else
106166124SrafanNCURSES_EXPORT_VAR(SCREEN *) SP = NULL; /* Some linkers require initialized data... */
10750276Speter#endif
108174993Srafan/* *INDENT-OFF* */
109174993Srafan#define CHARS_0s { '\0' }
110174993Srafan
111174993Srafan#define TGETENT_0 { 0L, FALSE, NULL, NULL, NULL }
112178866Srafan#define TGETENT_0s { TGETENT_0, TGETENT_0, TGETENT_0, TGETENT_0 }
113174993Srafan
114174993SrafanNCURSES_EXPORT_VAR(NCURSES_GLOBALS) _nc_globals = {
115174993Srafan    0,				/* have_sigwinch */
116174993Srafan    0,				/* cleanup_nested */
117174993Srafan
118174993Srafan    FALSE,			/* init_signals */
119174993Srafan    FALSE,			/* init_screen */
120174993Srafan
121174993Srafan    NULL,			/* comp_sourcename */
122174993Srafan    NULL,			/* comp_termtype */
123174993Srafan
124174993Srafan    FALSE,			/* have_tic_directory */
125174993Srafan    FALSE,			/* keep_tic_directory */
126174993Srafan    TERMINFO,			/* tic_directory */
127174993Srafan
128174993Srafan    NULL,			/* dbi_list */
129174993Srafan    0,				/* dbi_size */
130174993Srafan
131174993Srafan    NULL,			/* first_name */
132174993Srafan    NULL,			/* keyname_table */
133174993Srafan
134176187Srafan    0,				/* slk_format */
135176187Srafan
136174993Srafan    NULL,			/* safeprint_buf */
137174993Srafan    0,				/* safeprint_used */
138174993Srafan
139174993Srafan    TGETENT_0s,			/* tgetent_cache */
140174993Srafan    0,				/* tgetent_index */
141174993Srafan    0,				/* tgetent_sequence */
142174993Srafan
143178866Srafan    0,				/* _nc_windowlist */
144178866Srafan
145174993Srafan#if USE_HOME_TERMINFO
146174993Srafan    NULL,			/* home_terminfo */
147174993Srafan#endif
148174993Srafan
149174993Srafan#if !USE_SAFE_SPRINTF
150174993Srafan    0,				/* safeprint_cols */
151174993Srafan    0,				/* safeprint_rows */
152174993Srafan#endif
153174993Srafan
154174993Srafan#ifdef TRACE
155174993Srafan    FALSE,			/* init_trace */
156174993Srafan    CHARS_0s,			/* trace_fname */
157174993Srafan    0,				/* trace_level */
158174993Srafan    NULL,			/* trace_fp */
159174993Srafan
160174993Srafan    NULL,			/* tracearg_buf */
161174993Srafan    0,				/* tracearg_used */
162174993Srafan
163174993Srafan    NULL,			/* tracebuf_ptr */
164174993Srafan    0,				/* tracebuf_used */
165174993Srafan
166174993Srafan    CHARS_0s,			/* tracechr_buf */
167174993Srafan
168174993Srafan    NULL,			/* tracedmp_buf */
169174993Srafan    0,				/* tracedmp_used */
170174993Srafan
171174993Srafan    NULL,			/* tracetry_buf */
172174993Srafan    0,				/* tracetry_used */
173174993Srafan
174174993Srafan    { CHARS_0s, CHARS_0s },	/* traceatr_color_buf */
175174993Srafan    0,				/* traceatr_color_sel */
176174993Srafan    -1,				/* traceatr_color_last */
177174993Srafan
178174993Srafan#endif /* TRACE */
179174993Srafan#ifdef USE_PTHREADS
180184989Srafan    PTHREAD_MUTEX_INITIALIZER,	/* mutex_curses */
181174993Srafan    PTHREAD_MUTEX_INITIALIZER,	/* mutex_tst_tracef */
182174993Srafan    PTHREAD_MUTEX_INITIALIZER,	/* mutex_tracef */
183174993Srafan    0,				/* nested_tracef */
184184989Srafan    0,				/* use_pthreads */
185174993Srafan#endif
186174993Srafan};
187174993Srafan
188174993Srafan#define STACK_FRAME_0	{ { 0 }, 0 }
189174993Srafan#define STACK_FRAME_0s	{ STACK_FRAME_0 }
190174993Srafan#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 }
191174993Srafan
192176187Srafan#define RIPOFF_0	{ 0,0,0 }
193174993Srafan#define RIPOFF_0s	{ RIPOFF_0 }
194174993Srafan
195174993SrafanNCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = {
196174993Srafan    TRUE,			/* use_env */
197174993Srafan    FALSE,			/* filter_mode */
198174993Srafan    A_NORMAL,			/* previous_attr */
199174993Srafan    RIPOFF_0s,			/* ripoff */
200174993Srafan    NULL,			/* rsp */
201174993Srafan    {				/* tparm_state */
202174993Srafan#ifdef TRACE
203174993Srafan	NULL,			/* tname */
204174993Srafan#endif
205174993Srafan	NULL,			/* tparam_base */
206174993Srafan
207174993Srafan	STACK_FRAME_0s,		/* stack */
208174993Srafan	0,			/* stack_ptr */
209174993Srafan
210174993Srafan	NULL,			/* out_buff */
211174993Srafan	0,			/* out_size */
212174993Srafan	0,			/* out_used */
213174993Srafan
214174993Srafan	NULL,			/* fmt_buff */
215174993Srafan	0,			/* fmt_size */
216174993Srafan
217174993Srafan	NUM_VARS_0s,		/* dynamic_var */
218174993Srafan	NUM_VARS_0s,		/* static_vars */
219174993Srafan    },
220174993Srafan    NULL,			/* saved_tty */
221184989Srafan#if NCURSES_NO_PADDING
222184989Srafan    FALSE,			/* flag to set if padding disabled  */
223184989Srafan#endif
224174993Srafan#if BROKEN_LINKER || USE_REENTRANT
225174993Srafan    NULL,			/* real_acs_map */
226174993Srafan    0,				/* LINES */
227174993Srafan    0,				/* COLS */
228184989Srafan    0,				/* cur_term */
229174993Srafan#ifdef TRACE
230174993Srafan    0L,				/* _outchars */
231174993Srafan    NULL,			/* _tputs_trace */
232174993Srafan#endif
233174993Srafan#endif
234174993Srafan};
235174993Srafan/* *INDENT-ON* */
236176187Srafan
237176187Srafan/******************************************************************************/
238176187Srafan#ifdef USE_PTHREADS
239178866Srafanstatic void
240178866Srafaninit_global_mutexes(void)
241178866Srafan{
242178866Srafan    static bool initialized = FALSE;
243178866Srafan
244178866Srafan    if (!initialized) {
245178866Srafan	initialized = TRUE;
246184989Srafan	_nc_mutex_init(&_nc_globals.mutex_curses);
247178866Srafan	_nc_mutex_init(&_nc_globals.mutex_tst_tracef);
248178866Srafan	_nc_mutex_init(&_nc_globals.mutex_tracef);
249178866Srafan    }
250178866Srafan}
251178866Srafan
252184989SrafanNCURSES_EXPORT(void)
253184989Srafan_nc_init_pthreads(void)
254184989Srafan{
255184989Srafan    if (_nc_use_pthreads)
256184989Srafan	return;
257184989Srafan# if USE_WEAK_SYMBOLS
258184989Srafan    if ((pthread_mutex_init) == 0)
259184989Srafan	return;
260184989Srafan    if ((pthread_mutex_lock) == 0)
261184989Srafan	return;
262184989Srafan    if ((pthread_mutex_unlock) == 0)
263184989Srafan	return;
264184989Srafan    if ((pthread_mutex_trylock) == 0)
265184989Srafan	return;
266184989Srafan    if ((pthread_mutexattr_settype) == 0)
267184989Srafan	return;
268184989Srafan# endif
269184989Srafan    _nc_use_pthreads = 1;
270184989Srafan    init_global_mutexes();
271184989Srafan}
272184989Srafan
273178866Srafan/*
274178866Srafan * Use recursive mutexes if we have them - they're part of Unix98.
275178866Srafan * For the cases where we do not, _nc_mutex_trylock() is used to avoid a
276178866Srafan * deadlock, at the expense of memory leaks and unexpected failures that
277178866Srafan * may not be handled by typical clients.
278178866Srafan *
279178866Srafan * FIXME - need configure check for PTHREAD_MUTEX_RECURSIVE, define it to
280178866Srafan * PTHREAD_MUTEX_NORMAL if not supported.
281178866Srafan */
282178866SrafanNCURSES_EXPORT(void)
283178866Srafan_nc_mutex_init(pthread_mutex_t * obj)
284178866Srafan{
285178866Srafan    pthread_mutexattr_t recattr;
286178866Srafan
287184989Srafan    if (_nc_use_pthreads) {
288184989Srafan	pthread_mutexattr_init(&recattr);
289184989Srafan	pthread_mutexattr_settype(&recattr, PTHREAD_MUTEX_RECURSIVE);
290184989Srafan	pthread_mutex_init(obj, &recattr);
291184989Srafan    }
292178866Srafan}
293178866Srafan
294176187SrafanNCURSES_EXPORT(int)
295178866Srafan_nc_mutex_lock(pthread_mutex_t * obj)
296176187Srafan{
297184989Srafan    if (_nc_use_pthreads == 0)
298184989Srafan	return 0;
299176187Srafan    return pthread_mutex_lock(obj);
300176187Srafan}
301176187Srafan
302176187SrafanNCURSES_EXPORT(int)
303178866Srafan_nc_mutex_trylock(pthread_mutex_t * obj)
304176187Srafan{
305184989Srafan    if (_nc_use_pthreads == 0)
306184989Srafan	return 0;
307176187Srafan    return pthread_mutex_trylock(obj);
308176187Srafan}
309176187Srafan
310176187SrafanNCURSES_EXPORT(int)
311178866Srafan_nc_mutex_unlock(pthread_mutex_t * obj)
312176187Srafan{
313184989Srafan    if (_nc_use_pthreads == 0)
314184989Srafan	return 0;
315176187Srafan    return pthread_mutex_unlock(obj);
316176187Srafan}
317184989Srafan
318184989Srafan#if USE_WEAK_SYMBOLS
319184989Srafan/*
320184989Srafan * NB: sigprocmask(2) is global but pthread_sigmask(3p)
321184989Srafan * only for the calling thread.
322184989Srafan */
323184989SrafanNCURSES_EXPORT(int)
324184989Srafan_nc_sigprocmask(int how, const sigset_t * newmask, sigset_t * oldmask)
325184989Srafan{
326184989Srafan    if ((pthread_sigmask))
327184989Srafan	return pthread_sigmask(how, newmask, oldmask);
328184989Srafan    else
329184989Srafan	return sigprocmask(how, newmask, oldmask);
330184989Srafan}
331184989Srafan#endif
332176187Srafan#endif /* USE_PTHREADS */
333