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