1 /**************************************************************************** 2 * Copyright (c) 1998-2009,2010 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.61 2010/05/15 22:06:56 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_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 #ifndef USE_SP_WINDOWLIST 146 0, /* _nc_windowlist */ 147 #endif 148 149 #if USE_HOME_TERMINFO 150 NULL, /* home_terminfo */ 151 #endif 152 153 #if !USE_SAFE_SPRINTF 154 0, /* safeprint_cols */ 155 0, /* safeprint_rows */ 156 #endif 157 158 #ifdef USE_TERM_DRIVER 159 0, /* term_driver */ 160 #endif 161 162 #ifdef TRACE 163 FALSE, /* init_trace */ 164 CHARS_0s, /* trace_fname */ 165 0, /* trace_level */ 166 NULL, /* trace_fp */ 167 168 NULL, /* tracearg_buf */ 169 0, /* tracearg_used */ 170 171 NULL, /* tracebuf_ptr */ 172 0, /* tracebuf_used */ 173 174 CHARS_0s, /* tracechr_buf */ 175 176 NULL, /* tracedmp_buf */ 177 0, /* tracedmp_used */ 178 179 NULL, /* tracetry_buf */ 180 0, /* tracetry_used */ 181 182 { CHARS_0s, CHARS_0s }, /* traceatr_color_buf */ 183 0, /* traceatr_color_sel */ 184 -1, /* traceatr_color_last */ 185 #if !defined(USE_PTHREADS) && USE_REENTRANT 186 0, /* nested_tracef */ 187 #endif 188 #endif /* TRACE */ 189 #ifdef USE_PTHREADS 190 PTHREAD_MUTEX_INITIALIZER, /* mutex_curses */ 191 PTHREAD_MUTEX_INITIALIZER, /* mutex_tst_tracef */ 192 PTHREAD_MUTEX_INITIALIZER, /* mutex_tracef */ 193 0, /* nested_tracef */ 194 0, /* use_pthreads */ 195 #endif 196 #if USE_PTHREADS_EINTR 197 0, /* read_thread */ 198 #endif 199 }; 200 201 #define STACK_FRAME_0 { { 0 }, 0 } 202 #define STACK_FRAME_0s { STACK_FRAME_0 } 203 #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 } 204 205 #define RIPOFF_0 { 0,0,0 } 206 #define RIPOFF_0s { RIPOFF_0 } 207 208 NCURSES_EXPORT_VAR(NCURSES_PRESCREEN) _nc_prescreen = { 209 TRUE, /* use_env */ 210 FALSE, /* filter_mode */ 211 A_NORMAL, /* previous_attr */ 212 #ifndef USE_SP_RIPOFF 213 RIPOFF_0s, /* ripoff */ 214 NULL, /* rsp */ 215 #endif 216 { /* tparm_state */ 217 #ifdef TRACE 218 NULL, /* tname */ 219 #endif 220 NULL, /* tparam_base */ 221 222 STACK_FRAME_0s, /* stack */ 223 0, /* stack_ptr */ 224 225 NULL, /* out_buff */ 226 0, /* out_size */ 227 0, /* out_used */ 228 229 NULL, /* fmt_buff */ 230 0, /* fmt_size */ 231 232 NUM_VARS_0s, /* dynamic_var */ 233 NUM_VARS_0s, /* static_vars */ 234 }, 235 NULL, /* saved_tty */ 236 #if NCURSES_NO_PADDING 237 FALSE, /* flag to set if padding disabled */ 238 #endif 239 0, /* _outch */ 240 #if BROKEN_LINKER || USE_REENTRANT 241 NULL, /* real_acs_map */ 242 0, /* LINES */ 243 0, /* COLS */ 244 8, /* TABSIZE */ 245 1000, /* ESCDELAY */ 246 0, /* cur_term */ 247 #ifdef TRACE 248 0L, /* _outchars */ 249 NULL, /* _tputs_trace */ 250 #endif 251 #endif 252 }; 253 /* *INDENT-ON* */ 254 255 /* 256 * wgetch() and other functions with a WINDOW* parameter may use a SCREEN* 257 * internally, and it is useful to allow those to be invoked without switching 258 * SCREEN's, e.g., for multi-threaded applications. 259 */ 260 NCURSES_EXPORT(SCREEN *) 261 _nc_screen_of(WINDOW *win) 262 { 263 SCREEN *sp = 0; 264 265 if (win != 0) { 266 sp = WINDOW_EXT(win, screen); 267 } 268 return (sp); 269 } 270 271 /******************************************************************************/ 272 #ifdef USE_PTHREADS 273 static void 274 init_global_mutexes(void) 275 { 276 static bool initialized = FALSE; 277 278 if (!initialized) { 279 initialized = TRUE; 280 _nc_mutex_init(&_nc_globals.mutex_curses); 281 _nc_mutex_init(&_nc_globals.mutex_tst_tracef); 282 _nc_mutex_init(&_nc_globals.mutex_tracef); 283 } 284 } 285 286 NCURSES_EXPORT(void) 287 _nc_init_pthreads(void) 288 { 289 if (_nc_use_pthreads) 290 return; 291 # if USE_WEAK_SYMBOLS 292 if ((pthread_mutex_init) == 0) 293 return; 294 if ((pthread_mutex_lock) == 0) 295 return; 296 if ((pthread_mutex_unlock) == 0) 297 return; 298 if ((pthread_mutex_trylock) == 0) 299 return; 300 if ((pthread_mutexattr_settype) == 0) 301 return; 302 # endif 303 _nc_use_pthreads = 1; 304 init_global_mutexes(); 305 } 306 307 /* 308 * Use recursive mutexes if we have them - they're part of Unix98. 309 * For the cases where we do not, _nc_mutex_trylock() is used to avoid a 310 * deadlock, at the expense of memory leaks and unexpected failures that 311 * may not be handled by typical clients. 312 * 313 * FIXME - need configure check for PTHREAD_MUTEX_RECURSIVE, define it to 314 * PTHREAD_MUTEX_NORMAL if not supported. 315 */ 316 NCURSES_EXPORT(void) 317 _nc_mutex_init(pthread_mutex_t * obj) 318 { 319 pthread_mutexattr_t recattr; 320 321 if (_nc_use_pthreads) { 322 pthread_mutexattr_init(&recattr); 323 pthread_mutexattr_settype(&recattr, PTHREAD_MUTEX_RECURSIVE); 324 pthread_mutex_init(obj, &recattr); 325 } 326 } 327 328 NCURSES_EXPORT(int) 329 _nc_mutex_lock(pthread_mutex_t * obj) 330 { 331 if (_nc_use_pthreads == 0) 332 return 0; 333 return pthread_mutex_lock(obj); 334 } 335 336 NCURSES_EXPORT(int) 337 _nc_mutex_trylock(pthread_mutex_t * obj) 338 { 339 if (_nc_use_pthreads == 0) 340 return 0; 341 return pthread_mutex_trylock(obj); 342 } 343 344 NCURSES_EXPORT(int) 345 _nc_mutex_unlock(pthread_mutex_t * obj) 346 { 347 if (_nc_use_pthreads == 0) 348 return 0; 349 return pthread_mutex_unlock(obj); 350 } 351 #endif /* USE_PTHREADS */ 352 353 #if defined(USE_PTHREADS) || USE_PTHREADS_EINTR 354 #if USE_WEAK_SYMBOLS 355 /* 356 * NB: sigprocmask(2) is global but pthread_sigmask(3p) 357 * only for the calling thread. 358 */ 359 NCURSES_EXPORT(int) 360 _nc_sigprocmask(int how, const sigset_t * newmask, sigset_t * oldmask) 361 { 362 if ((pthread_sigmask)) 363 return pthread_sigmask(how, newmask, oldmask); 364 else 365 return sigprocmask(how, newmask, oldmask); 366 } 367 #endif 368 #endif /* USE_PTHREADS */ 369