From 320039a23d96d9cc417ced27b39076594283693d Mon Sep 17 00:00:00 2001 From: Salvadore Swiss Date: Tue, 15 Jan 2013 17:19:15 +0000 Subject: [PATCH] allow rtorrent to run as a daemon without screen. check for available terminal before initializing ncurses by calling initscr. if no terminal available assume rtorrent is daemon and disable terminal functionality in display::Canvas so program does not crash and i/o can be done with rpc calls. --- src/control.cc | 12 ++++-- src/display/canvas.cc | 96 ++++++++++++++++++++++++------------------- src/display/canvas.h | 79 ++++++++++++++++++++--------------- 3 files changed, 107 insertions(+), 80 deletions(-) diff --git a/src/control.cc b/src/control.cc index e18938834..cda41f83b 100644 --- a/src/control.cc +++ b/src/control.cc @@ -115,7 +115,9 @@ Control::initialize() { m_ui->init(this); - m_inputStdin->insert(torrent::main_thread()->poll()); + if(display::Canvas::have_term()) { + m_inputStdin->insert(torrent::main_thread()->poll()); + } } void @@ -124,9 +126,11 @@ Control::cleanup() { rpc::xmlrpc.cleanup(); priority_queue_erase(&taskScheduler, &m_taskShutdown); - - m_inputStdin->remove(torrent::main_thread()->poll()); - + + if(display::Canvas::have_term()) { + m_inputStdin->remove(torrent::main_thread()->poll()); + } + m_core->download_store()->disable(); m_ui->cleanup(); diff --git a/src/display/canvas.cc b/src/display/canvas.cc index 4394b8945..d5dae671b 100644 --- a/src/display/canvas.cc +++ b/src/display/canvas.cc @@ -46,49 +46,55 @@ namespace display { bool Canvas::m_isInitialized = false; +bool Canvas::m_haveTerm = false; -Canvas::Canvas(int x, int y, int width, int height) : - m_window(newwin(height, width, y, x)) { - - if (m_window == NULL) - throw torrent::internal_error("Could not allocate ncurses canvas."); +Canvas::Canvas(int x, int y, int width, int height) { + if(m_haveTerm) { + m_window = newwin(height, width, y, x); + if (m_window == NULL) + throw torrent::internal_error("Could not allocate ncurses canvas."); + } } void Canvas::resize(int x, int y, int w, int h) { - wresize(m_window, h, w); - mvwin(m_window, y, x); + if(m_haveTerm) { + wresize(m_window, h, w); + mvwin(m_window, y, x); + } } void Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes) { - move(x, y); - - attr_t org_attr; - short org_pair; - wattr_get(m_window, &org_attr, &org_pair, NULL); - - attributes_list::const_iterator attrItr = attributes->begin(); - wattr_set(m_window, Attributes::a_normal, Attributes::color_default, NULL); + if(m_haveTerm) { + move(x, y); + + attr_t org_attr; + short org_pair; + wattr_get(m_window, &org_attr, &org_pair, NULL); + + attributes_list::const_iterator attrItr = attributes->begin(); + wattr_set(m_window, Attributes::a_normal, Attributes::color_default, NULL); - while (first != last) { - const char* next = last; + while (first != last) { + const char* next = last; - if (attrItr != attributes->end()) { - next = attrItr->position(); + if (attrItr != attributes->end()) { + next = attrItr->position(); - if (first >= next) { - wattr_set(m_window, attrItr->attributes(), attrItr->colors(), NULL); - ++attrItr; + if (first >= next) { + wattr_set(m_window, attrItr->attributes(), attrItr->colors(), NULL); + ++attrItr; + } } + + print("%.*s", next - first, first); + first = next; } - print("%.*s", next - first, first); - first = next; + // Reset the color. + wattr_set(m_window, org_attr, org_pair, NULL); } - - // Reset the color. - wattr_set(m_window, org_attr, org_pair, NULL); } void @@ -96,35 +102,41 @@ Canvas::initialize() { if (m_isInitialized) return; + struct termios termios_info_str; + m_haveTerm = tcgetattr(STDIN_FILENO, &termios_info_str) == 0; + m_isInitialized = true; - initscr(); - raw(); - noecho(); - nodelay(stdscr, TRUE); - keypad(stdscr, TRUE); - curs_set(0); + if(m_haveTerm) { + initscr(); + raw(); + noecho(); + nodelay(stdscr, TRUE); + keypad(stdscr, TRUE); + curs_set(0); + } } void Canvas::cleanup() { if (!m_isInitialized) return; - - m_isInitialized = false; + if(m_haveTerm) { + m_isInitialized = false; - noraw(); - endwin(); + noraw(); + endwin(); + } } std::pair Canvas::term_size() { struct winsize ws; - - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0) - return std::pair(ws.ws_col, ws.ws_row); - else - return std::pair(80, 24); + if(m_haveTerm) { + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0) + return std::pair(ws.ws_col, ws.ws_row); + } + return std::pair(80, 24); } } diff --git a/src/display/canvas.h b/src/display/canvas.h index 7023cadac..6637afa7a 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -49,37 +49,37 @@ class Canvas { typedef std::vector attributes_list; Canvas(int x = 0, int y = 0, int width = 0, int height = 0); - ~Canvas() { delwin(m_window); } + ~Canvas() { if(m_haveTerm){ delwin(m_window); } } - void refresh() { wnoutrefresh(m_window); } - static void refresh_std() { wnoutrefresh(stdscr); } - void redraw() { redrawwin(m_window); } - static void redraw_std() { redrawwin(stdscr); } + void refresh() { if(m_haveTerm){ wnoutrefresh(m_window); } } + static void refresh_std() { if(m_haveTerm){ wnoutrefresh(stdscr); } } + void redraw() { if(m_haveTerm){ redrawwin(m_window); } } + static void redraw_std() { if(m_haveTerm){ redrawwin(stdscr); } } - void resize(int w, int h) { wresize(m_window, h, w); } + void resize(int w, int h) { if(m_haveTerm){ wresize(m_window, h, w); } } void resize(int x, int y, int w, int h); - static void resize_term(int x, int y) { resizeterm(y, x); } - static void resize_term(std::pair dim) { resizeterm(dim.second, dim.first); } + static void resize_term(int x, int y) { if(m_haveTerm){ resizeterm(y, x); } } + static void resize_term(std::pair dim) { if(m_haveTerm){ resizeterm(dim.second, dim.first); } } - unsigned int get_x() { int x, __UNUSED y; getyx(m_window, y, x); return x; } - unsigned int get_y() { int x, y; getyx(m_window, y, x); return y; } + unsigned int get_x() { int x, __UNUSED y; if(m_haveTerm){ getyx(m_window, y, x); } else { y=1; } return x; } + unsigned int get_y() { int x, y; if(m_haveTerm){ getyx(m_window, y, x); } else { y=1; } return y; } - unsigned int width() { int x, __UNUSED y; getmaxyx(m_window, y, x); return x; } - unsigned int height() { int x, y; getmaxyx(m_window, y, x); return y; } + unsigned int width() { int x, __UNUSED y; if(m_haveTerm){ getmaxyx(m_window, y, x); } else { x=80; } return x; } + unsigned int height() { int x, y; if(m_haveTerm){ getmaxyx(m_window, y, x); } else { y=24; } return y; } - void move(unsigned int x, unsigned int y) { wmove(m_window, y, x); } + void move(unsigned int x, unsigned int y) { if(m_haveTerm){ wmove(m_window, y, x); } } - chtype get_background() { return getbkgd(m_window); } - void set_background(chtype c) { return wbkgdset(m_window, c); } + chtype get_background() { chtype bg=0; if(m_haveTerm){ bg=getbkgd(m_window); } return bg; } + void set_background(chtype c) { if(m_haveTerm){ wbkgdset(m_window, c); } } - void erase() { werase(m_window); } - static void erase_std() { werase(stdscr); } + void erase() { if(m_haveTerm){ werase(m_window); } } + static void erase_std() { if(m_haveTerm){ werase(stdscr); } } void print_border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, - chtype bl, chtype br) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } + chtype bl, chtype br) { if(m_haveTerm){ wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } } // The format string is non-const, but that will not be a problem // since the string shall always be a C string choosen at @@ -90,50 +90,61 @@ class Canvas { void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes); - void print_char(const chtype ch) { waddch(m_window, ch); } - void print_char(unsigned int x, unsigned int y, const chtype ch) { mvwaddch(m_window, y, x, ch); } + void print_char(const chtype ch) { if(m_haveTerm){ waddch(m_window, ch); } } + void print_char(unsigned int x, unsigned int y, const chtype ch) { if(m_haveTerm){ mvwaddch(m_window, y, x, ch); } } - void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { mvwchgat(m_window, y, x, n, attr, color, NULL); } + void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { if(m_haveTerm){ mvwchgat(m_window, y, x, n, attr, color, NULL); } } - void set_default_attributes(int attr) { (void)wattrset(m_window, attr); } + void set_default_attributes(int attr) { if(m_haveTerm){ (void)wattrset(m_window, attr); } } // Initialize stdscr. static void initialize(); static void cleanup(); - static int get_screen_width() { int x, __UNUSED y; getmaxyx(stdscr, y, x); return x; } - static int get_screen_height() { int x, y; getmaxyx(stdscr, y, x); return y; } + static int get_screen_width() { int x, __UNUSED y; if(m_haveTerm){ getmaxyx(stdscr, y, x); } else { x=80; } return x; } + static int get_screen_height() { int x, y; if(m_haveTerm){ getmaxyx(stdscr, y, x); } else { y=24;} return y; } static std::pair term_size(); - static void do_update() { doupdate(); } + static void do_update() { if(m_haveTerm){ doupdate(); } } + + static bool have_term() { return m_haveTerm; } private: Canvas(const Canvas&); void operator = (const Canvas&); static bool m_isInitialized; - + + static bool m_haveTerm; + WINDOW* m_window; + + + }; inline void Canvas::print(const char* str, ...) { va_list arglist; - - va_start(arglist, str); - vw_printw(m_window, const_cast(str), arglist); - va_end(arglist); + + if(m_haveTerm) { + va_start(arglist, str); + vw_printw(m_window, const_cast(str), arglist); + va_end(arglist); + } } inline void Canvas::print(unsigned int x, unsigned int y, const char* str, ...) { va_list arglist; - va_start(arglist, str); - wmove(m_window, y, x); - vw_printw(m_window, const_cast(str), arglist); - va_end(arglist); + if(m_haveTerm) { + va_start(arglist, str); + wmove(m_window, y, x); + vw_printw(m_window, const_cast(str), arglist); + va_end(arglist); + } } }