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