33 #include <yui/Libyui_config.h> 35 #define YUILogComponent "ncurses" 36 #include <yui/YUILog.h> 43 #include <sys/types.h> 52 std::set<NCDialog*> NCurses::_knownDlgs;
53 const NCursesEvent NCursesEvent::Activated( NCursesEvent::button, YEvent::Activated );
54 const NCursesEvent NCursesEvent::SelectionChanged( NCursesEvent::button, YEvent::SelectionChanged );
55 const NCursesEvent NCursesEvent::ValueChanged( NCursesEvent::button, YEvent::ValueChanged );
60 #define CONVERR(n,p) \ 66 errmsg_t = vform( p, ap, ap1 ); \ 70 NCursesError::NCursesError(
const char * msg, ... )
76 NCursesError::NCursesError(
int val,
const char * msg, ... )
82 NCursesError & NCursesError::NCError(
const char * msg, ... )
88 NCursesError & NCursesError::NCError(
int val,
const char * msg, ... )
97 std::ostream & operator<<( std::ostream & str,
const NCursesError & obj )
99 str << form(
"%s: (%d) %s" 102 , obj.errmsg_t.c_str() );
107 std::ostream & operator<<( std::ostream & str,
const NCursesEvent & obj )
109 #define ENUM_OUT(v) case NCursesEvent::v: return str << "Ev::" << #v 123 return str <<
"Ev::unknown";
135 const char * term = getenv(
"TERM" );
145 yuiMilestone() <<
"Shutdown NCurses..." << std::endl;
149 setenv(
"TERM", envTerm.c_str(), 1 );
157 ::delwin( status_w );
162 ::delscreen( theTerm );
164 yuiMilestone() <<
"NCurses down" << std::endl;
169 WINDOW * NCurses::ripped_w_top = 0;
170 WINDOW * NCurses::ripped_w_bottom = 0;
172 int NCurses::ripinit_top( WINDOW * w,
int c )
179 int NCurses::ripinit_bottom( WINDOW * w,
int c )
188 yuiMilestone() <<
"Launch NCurses..." 190 <<
"(ui-ncurses-" << VERSION <<
")" 193 yuiMilestone() <<
"TERM=" << envTerm << std::endl;
195 signal( SIGINT, SIG_IGN );
199 if ( title_line() && ::ripoffline( 1, ripinit_top ) != OK )
203 if ( ::ripoffline( -1, ripinit_bottom ) != OK )
206 yuiMilestone() <<
"isatty(stdin)" << ( isatty( 0 ) ?
"yes" :
"no" ) << std::endl;
210 char * mytty = ttyname( 0 );
214 yuiMilestone() <<
"mytty: " << mytty << std::endl;
215 FILE * fdi = fopen( mytty,
"r" );
219 yuiError() <<
"fdi: (" << errno <<
") " << strerror( errno ) << std::endl;
222 FILE * fdo = fopen( mytty,
"w" );
226 yuiError() <<
"fdo: (" << errno <<
") " << strerror( errno ) << std::endl;
231 theTerm = newterm( 0, fdo, fdi );
235 if ( theTerm == NULL )
241 std::string fallbackTerm =
"";
244 if ( ! fnmatch(
"xterm*", envTerm.c_str(), 0 ) )
245 fallbackTerm =
"xterm";
247 fallbackTerm =
"vt100";
249 yuiWarning() <<
"newterm() failed, using generic " << fallbackTerm <<
" as a fallback" << std::endl;
252 setenv(
"TERM", fallbackTerm.c_str(), 1 );
255 theTerm = newterm( 0, fdo, fdi );
257 if ( theTerm == NULL )
261 if ( set_term( theTerm ) == NULL )
271 stdout_save = dup( 1 );
272 stderr_save = dup( 2 );
278 yuiMilestone() <<
"no term so fall back to initscr" << std::endl;
280 if ( ::initscr() == NULL )
284 yuiMilestone() <<
"have color = " << ::has_colors() << std::endl;
286 if ( want_colors() && ::has_colors() )
288 if ( ::start_color() != OK )
291 NCattribute::init_colors();
299 title_w = ripped_w_top;
302 if ( !ripped_w_bottom )
305 status_w = ripped_w_bottom;
309 yuiMilestone() << form(
"screen size %d x %d\n", lines(), cols() );
312 styleset =
new NCstyle( envTerm );
314 stdpan->
bkgd( style()( NCstyle::AppText ) );
318 SetStatusLine( myself->status_line );
321 yuiMilestone() <<
"NCurses ready" << std::endl;
326 void NCurses::setup_screen()
330 ::keypad( ::stdscr,
true );
331 ::meta( ::stdscr,
true );
332 ::leaveok( ::stdscr,
true );
335 ::define_key(
"\e[Z", KEY_BTAB );
336 ::define_key(
"\e\t", KEY_BTAB );
337 ::define_key(
"\030\t", KEY_BTAB );
342 void NCurses::init_title()
344 ::wbkgd( title_w, style()( NCstyle::AppTitle ) );
345 ::wnoutrefresh( title_w );
346 ::wbkgd( status_w, style()( NCstyle::AppTitle ) );
347 ::wnoutrefresh( status_w );
352 void NCurses::init_screen()
354 bool redefine =
false;
356 char *value = getenv(
"Y2NCPSEUDO" );
363 if ( value != NULL && strcmp( value,
"1" ) == 0 )
372 NCattribute::setChar( cch,
'+' );
383 NCattribute::setChar( cch,
'|' );
386 NCattribute::setChar( cch,
'-' );
389 NCattribute::setChar( cch,
'#' );
394 NCattribute::setChar( cch,
'<' );
397 NCattribute::setChar( cch,
'>' );
400 NCattribute::setChar( cch,
'v' );
403 NCattribute::setChar( cch,
'^' );
409 const NCstyle & NCurses::style()
411 return *myself->styleset;
415 void NCurses::Update()
417 if ( myself && myself->initialized() )
425 void NCurses::Refresh()
427 if ( myself && myself->initialized() )
429 yuiMilestone() <<
"start refresh ..." << std::endl;
430 SetTitle( myself->title_t );
431 SetStatusLine( myself->status_line );
432 ::clearok( ::stdscr,
true );
434 yuiMilestone() <<
"done refresh ..." << std::endl;
439 void NCurses::Redraw()
441 if ( myself && myself->initialized() )
443 yuiMilestone() <<
"start redraw ..." << std::endl;
446 PANEL * pan = ::panel_above( NULL );
457 pan = ::panel_above( pan );
463 yuiMilestone() <<
"done redraw ..." << std::endl;
468 void NCurses::SetTitle(
const std::string & str )
470 if ( myself && myself->title_w )
472 myself->title_t = str;
473 ::wbkgd( myself->title_w, myself->style()( NCstyle::AppTitle ) );
474 ::wclear( myself->title_w );
476 yuiMilestone() <<
"Draw title called" << std::endl;
478 ::mvwaddstr( myself->title_w, 0, 1, myself->title_t.c_str() );
479 ::wnoutrefresh( myself->title_w );
484 void NCurses::SetStatusLine( std::map <int, NCstring> fkeys )
487 if ( myself && myself->status_w )
489 myself->status_line = fkeys;
490 ::wbkgd( myself->status_w, myself->style()( NCstyle::AppTitle ) );
491 ::werase( myself->status_w );
496 std::map<int, NCstring>::iterator it;
498 for ( it = fkeys.begin(); it != fkeys.end(); ++it )
500 sprintf( key,
" F%d ", ( *it ).first );
502 ::wattron( myself->status_w, A_REVERSE );
503 ::waddstr( myself->status_w, key );
504 ::wattroff( myself->status_w, A_REVERSE );
506 value = (*it ).second.str();
507 if ( NCstring::terminalEncoding() !=
"UTF-8" )
510 NCstring::RecodeFromWchar( value, NCstring::terminalEncoding(), &out );
511 ::waddstr( myself->status_w, (
char *)out.c_str() );
515 ::waddwstr( myself->status_w, (
wchar_t *)value.c_str() );
517 ::waddch( myself->status_w,
' ' );
520 ::wnoutrefresh( myself->status_w );
526 void NCurses::drawTitle()
528 if ( myself && myself->title_w )
530 SetTitle( myself->title_t );
536 void NCurses::RememberDlg(
NCDialog * dlg_r )
540 _knownDlgs.insert( dlg_r );
546 void NCurses::ForgetDlg(
NCDialog * dlg_r )
550 _knownDlgs.erase( dlg_r );
561 void NCurses::RedirectToLog()
563 std::string log =
"/dev/null";
565 yuiMilestone() <<
"isatty(stderr)" << ( isatty( 2 ) ?
"yes" :
"no" ) << std::endl;
567 if ( isatty( 2 ) && theTerm )
571 open( log.c_str(), O_APPEND | O_CREAT | O_WRONLY, 0666 );
574 yuiMilestone() <<
"isatty(stdout)" << ( isatty( 1 ) ?
"yes" :
"no" ) << std::endl;
576 if ( isatty( 1 ) && theTerm )
580 open( log.c_str(), O_APPEND | O_CREAT | O_WRONLY, 0666 );
586 void NCurses::ResizeEvent()
588 if ( myself && myself->initialized() )
590 yuiMilestone() <<
"start resize to " << NCurses::lines() <<
'x' << NCurses::cols() <<
"..." << std::endl;
594 std::list<NCDialog*> dlgStack;
596 for ( PANEL * pan = ::panel_above( NULL ); pan; pan = ::panel_above( pan ) )
602 dlgStack.push_back( dlg );
607 for ( std::list<NCDialog*>::iterator it = dlgStack.begin(); it != dlgStack.end(); ++it )
609 ( *it )->getInvisible();
617 for ( std::set<NCDialog*>::iterator it = _knownDlgs.begin(); it != _knownDlgs.end(); ++it )
619 ( *it )->resizeEvent();
623 for ( std::list<NCDialog*>::iterator it = dlgStack.begin(); it != dlgStack.end(); ++it )
625 ( *it )->getVisible();
632 ::mvwin( myself->status_w, NCurses::lines(), 0 );
633 SetStatusLine( myself->status_line );
635 ::touchwin( myself->status_w );
638 yuiMilestone() <<
"done resize ..." << std::endl;
644 void NCurses::ScreenShot(
const std::string & name )
650 std::ostream & out( yuiMilestone() );
652 int curscrlines = myself->title_line() ? lines() + 1 : lines();
654 for (
int l = 0; l < curscrlines; ++l )
656 for (
int c = 0; c < cols(); ++c )
659 chtype al = ::mvwinch( ::curscr, l, c ) & ( A_ALTCHARSET | A_CHARTEXT );
661 if ( al & A_ALTCHARSET )
663 if ( al == ACS_ULCORNER
664 || al == ACS_LLCORNER
665 || al == ACS_URCORNER
666 || al == ACS_LRCORNER
675 else if ( al == ACS_HLINE )
679 else if ( al == ACS_VLINE )
683 else if ( al == ACS_DIAMOND
689 else if ( al == ACS_LARROW )
693 else if ( al == ACS_RARROW )
697 else if ( al == ACS_DARROW ) 701 else if ( al == ACS_UARROW ) 707 out << ( char )( al & A_CHARTEXT ); 712 out << ( char )( al & A_CHARTEXT ); 722 std::ostream & operator<<( std::ostream & str, const NCurses & obj ) 724 str << form( "NC - %d x %d - colors %d - pairs %d\n" 725 , obj.lines(), obj.cols() 726 , NCattribute::colors(), NCattribute::color_pairs() ); 728 WINDOW * cw = ::stdscr; 729 str << form( "NC - rootw %p", cw ); 732 str << form( " - (%2hd,%2hd)%2hdx%2hd - {%p - (%2d,%2d)}\n" 733 , cw->_begy, cw->_begx 734 , cw->_maxy, cw->_maxx 736 , cw->_pary, cw->_parx 743 str << form( "NC - title %p", cw ); 746 str << form( " - (%2hd,%2hd)%2hdx%2hd - {%p - (%2d,%2d)}\n" 747 , cw->_begy, cw->_begx 748 , cw->_maxy, cw->_maxx 750 , cw->_pary, cw->_parx
static void redraw()
Redraw all panels.
int bkgd(const chtype ch)
Set the background property and apply it to the window.
virtual int refresh()
Propagate all panel changes to the virtual screen and update the physical screen. ...
static T * UserDataOf(const PANEL &pan)
Retrieve the user data if associated with the PANEL.