mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-11 00:29:22 +00:00
+120
-43
@@ -1,45 +1,9 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
@@ -48,14 +12,16 @@
|
||||
namespace display {
|
||||
|
||||
bool Canvas::m_isInitialized = false;
|
||||
bool Canvas::m_isDaemon = false;
|
||||
bool Canvas::m_isDaemon = false;
|
||||
// Maps ncurses color IDs to a ncurses attribute int
|
||||
std::unordered_map<int, int> Canvas::m_attr_map = {};
|
||||
|
||||
Canvas::Canvas(int x, int y, int width, int height) {
|
||||
if (!m_isDaemon) {
|
||||
m_window = newwin(height, width, y, x);
|
||||
m_window = newwin(height, width, y, x);
|
||||
|
||||
if (m_window == NULL)
|
||||
throw torrent::internal_error("Could not allocate ncurses canvas.");
|
||||
if (m_window == NULL)
|
||||
throw torrent::internal_error("Could not allocate ncurses canvas.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +39,7 @@ Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, cons
|
||||
move(x, y);
|
||||
|
||||
attr_t org_attr;
|
||||
short org_pair;
|
||||
short org_pair;
|
||||
wattr_get(m_window, &org_attr, &org_pair, NULL);
|
||||
|
||||
attributes_list::const_iterator attrItr = attributes->begin();
|
||||
@@ -111,6 +77,9 @@ Canvas::initialize() {
|
||||
|
||||
if (!m_isDaemon) {
|
||||
initscr();
|
||||
start_color();
|
||||
use_default_colors();
|
||||
Canvas::build_colors();
|
||||
raw();
|
||||
noecho();
|
||||
nodelay(stdscr, TRUE);
|
||||
@@ -119,6 +88,114 @@ Canvas::initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
// Function wrapper for what possibly is a macro
|
||||
int
|
||||
get_colors() {
|
||||
return COLORS;
|
||||
}
|
||||
|
||||
// Turns the string color definitions from the "ui.color.*" RPC
|
||||
// commands into valid ncurses color pairs
|
||||
void
|
||||
Canvas::build_colors() {
|
||||
|
||||
// This may get called early in the start process by the config
|
||||
// file, so we need to delay building until initscr() has a chance
|
||||
// to run
|
||||
if (!m_isInitialized || m_isDaemon)
|
||||
return;
|
||||
|
||||
// basic color names, index maps to ncurses COLOR_*
|
||||
static const char* color_names[] = {
|
||||
"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"};
|
||||
|
||||
// Those hold the background colors of "odd" and "even"
|
||||
int bg_odd = -1;
|
||||
int bg_even = -1;
|
||||
|
||||
for (int k = 1; k < RCOLOR_MAX; k++) {
|
||||
init_pair(k, -1, -1);
|
||||
std::string color_def = rpc::call_command_string(color_vars[k]);
|
||||
if (color_def.empty())
|
||||
continue; // Use terminal default if definition is empty
|
||||
|
||||
short color[2] = {-1, -1}; // fg, bg
|
||||
short color_idx = 0; // 0 = fg; 1 = bg
|
||||
short bright = 0;
|
||||
unsigned long attr = A_NORMAL;
|
||||
|
||||
// Process string as space-separated words
|
||||
size_t start = 0, end = 0;
|
||||
while (true) {
|
||||
end = color_def.find(' ', start);
|
||||
std::string word = color_def.substr(start, end - start);
|
||||
|
||||
if (word == "bold")
|
||||
attr |= A_BOLD;
|
||||
else if (word == "standout")
|
||||
attr |= A_STANDOUT;
|
||||
else if (word == "underline")
|
||||
attr |= A_UNDERLINE;
|
||||
else if (word == "reverse")
|
||||
attr |= A_REVERSE;
|
||||
else if (word == "blink")
|
||||
attr |= A_BLINK;
|
||||
else if (word == "dim")
|
||||
attr |= A_DIM;
|
||||
else if (word == "on") {
|
||||
color_idx = 1;
|
||||
bright = 0;
|
||||
} // Switch to background color
|
||||
else if (word == "gray" || word == "grey")
|
||||
color[color_idx] = bright ? 7 : 8; // Bright gray is white
|
||||
else if (word == "bright")
|
||||
bright = 8;
|
||||
else if (word.find_first_not_of("0123456789") == std::string::npos) {
|
||||
// Handle numeric index
|
||||
short c = -1;
|
||||
sscanf(word.c_str(), "%hd", &c);
|
||||
color[color_idx] = c;
|
||||
} else
|
||||
for (short c = 0; c < 8; c++) { // Check for basic color names
|
||||
if (word == color_names[c]) {
|
||||
color[color_idx] = bright + c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (end == std::string::npos)
|
||||
break;
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
// Check that fg & bg color index is valid
|
||||
if ((color[0] != -1 && color[0] >= get_colors()) || (color[1] != -1 && color[1] >= get_colors())) {
|
||||
char buf[33];
|
||||
sprintf(buf, "%d", get_colors());
|
||||
Canvas::cleanup();
|
||||
throw torrent::input_error(color_def + ": your terminal only supports " + buf + " colors.");
|
||||
}
|
||||
|
||||
m_attr_map[k] = attr; // overwrite or insert the value
|
||||
init_pair(k, color[0], color[1]);
|
||||
if (k == RCOLOR_EVEN)
|
||||
bg_even = color[1];
|
||||
if (k == RCOLOR_ODD)
|
||||
bg_odd = color[1];
|
||||
}
|
||||
|
||||
// Now make copies of the basic colors with the "odd" and "even" definitions mixed in
|
||||
for (int k = 1; k < RCOLOR_MAX; k++) {
|
||||
short fg, bg;
|
||||
pair_content(k, &fg, &bg);
|
||||
|
||||
// Replace the background color, and mix in the attributes
|
||||
m_attr_map[k + 1 * RCOLOR_MAX] = m_attr_map[k] | m_attr_map[RCOLOR_EVEN];
|
||||
m_attr_map[k + 2 * RCOLOR_MAX] = m_attr_map[k] | m_attr_map[RCOLOR_ODD];
|
||||
init_pair(k + 1 * RCOLOR_MAX, fg, bg == -1 ? bg_even : bg);
|
||||
init_pair(k + 2 * RCOLOR_MAX, fg, bg == -1 ? bg_odd : bg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Canvas::cleanup() {
|
||||
if (!m_isInitialized)
|
||||
@@ -143,4 +220,4 @@ Canvas::term_size() {
|
||||
return std::pair<int, int>(80, 24);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace display
|
||||
|
||||
Reference in New Issue
Block a user