#include <ctype.h>
#include <ncurses.h>
#include <panel.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "curses_util.h"
unsigned int ymax, xmax;
int monochrome = 1;
int allocated_colors = 0;
struct curses_attr {
int pair_no;
int bold;
};
struct curses_attr colors_tab[CURSES_COLORS_MAX];
int colors[8] = {
COLOR_BLACK,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW,
COLOR_BLUE,
COLOR_MAGENTA,
COLOR_CYAN,
COLOR_WHITE
};
static int
curses_colors_find(int fg, int bg)
{
int pair_no;
short fge, bge;
for (pair_no = 0;
pair_no <= allocated_colors && pair_no < COLOR_PAIRS;
pair_no++) {
pair_content(pair_no, &fge, &bge);
if (fg == fge && bg == bge)
return(pair_no);
}
if (allocated_colors < (COLOR_PAIRS-1)) {
allocated_colors++;
init_pair(allocated_colors, fg, bg);
return(allocated_colors);
}
return(-1);
}
static void
curses_colors_cfg(int role, int fg, int bg, int bold)
{
int pair_no;
pair_no = curses_colors_find(fg, bg);
if (pair_no != -1) {
colors_tab[role].pair_no = pair_no;
colors_tab[role].bold = bold;
} else {
colors_tab[role].pair_no = 0;
colors_tab[role].bold = bold;
}
}
void
curses_colors_init(int force_monochrome)
{
if (!force_monochrome) {
if (has_colors()) {
monochrome = 0;
start_color();
}
}
curses_colors_cfg(CURSES_COLORS_NORMAL, COLOR_BLACK, COLOR_GREY, 0);
curses_colors_cfg(CURSES_COLORS_BACKDROP, COLOR_WHITE, COLOR_BLUE, 0);
curses_colors_cfg(CURSES_COLORS_MENUBAR, COLOR_BLACK, COLOR_GREY, 0);
curses_colors_cfg(CURSES_COLORS_STATUSBAR, COLOR_BLACK, COLOR_GREY, 0);
curses_colors_cfg(CURSES_COLORS_BORDER, COLOR_WHITE, COLOR_GREY, 1);
curses_colors_cfg(CURSES_COLORS_FORMTITLE, COLOR_YELLOW, COLOR_GREY, 1);
curses_colors_cfg(CURSES_COLORS_LABEL, COLOR_BLACK, COLOR_GREY, 0);
curses_colors_cfg(CURSES_COLORS_CONTROL, COLOR_BLACK, COLOR_GREY, 0);
curses_colors_cfg(CURSES_COLORS_TEXT, COLOR_BLACK, COLOR_GREY, 0);
curses_colors_cfg(CURSES_COLORS_FOCUS, COLOR_WHITE, COLOR_BLUE, 1);
curses_colors_cfg(CURSES_COLORS_SCROLLAREA,COLOR_GREY, COLOR_BLACK, 0);
curses_colors_cfg(CURSES_COLORS_SCROLLBAR, COLOR_WHITE, COLOR_BLUE, 1);
curses_colors_cfg(CURSES_COLORS_ACCEL, COLOR_WHITE, COLOR_GREY, 1);
curses_colors_cfg(CURSES_COLORS_ACCELFOCUS,COLOR_YELLOW, COLOR_BLUE, 1);
}
void
curses_colors_set(WINDOW *w, int a)
{
if (!monochrome)
wattrset(w, COLOR_PAIR(colors_tab[a].pair_no));
if (colors_tab[a].bold)
wattron(w, A_BOLD);
else
wattroff(w, A_BOLD);
}
void
curses_window_blank(WINDOW *w)
{
unsigned int i;
for (i = 0; i <= ymax; i++) {
wmove(w, i, 0);
whline(w, ' ', xmax);
}
wrefresh(w);
}
void
curses_frame_draw(int x, int y, int width, int height)
{
int i;
mvaddch(y, x, ACS_ULCORNER);
hline(ACS_HLINE, width - 2);
mvaddch(y, x + width - 1, ACS_URCORNER);
mvaddch(y + height - 1, x, ACS_LLCORNER);
hline(ACS_HLINE, width - 2);
mvaddch(y + height - 1, x + width - 1, ACS_LRCORNER);
move(y + 1, x);
vline(ACS_VLINE, height - 2);
move(y + 1, x + width - 1);
vline(ACS_VLINE, height - 2);
for (i = y + 1; i < y + height - 1; i++) {
move(i, x + 1);
hline(' ', width - 2);
}
}
void
curses_load_backdrop(WINDOW *w, const char *filename)
{
FILE *f;
char line[80];
int row = 1;
int my, mx;
getmaxyx(w, my, mx);
wclear(w);
curses_colors_set(w, CURSES_COLORS_BACKDROP);
curses_window_blank(w);
if ((f = fopen(filename, "r")) != NULL) {
while (fgets(line, 79, f) != NULL) {
if (row > my)
break;
if (line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = '\0';
mvwaddnstr(w, row++, 0, line, mx);
}
fclose(f);
}
}
void
curses_debug_str(const char *s)
{
char b[256];
move(1, 0);
sprintf(b, "[%77s]", s);
addstr(b);
refresh();
}
void
curses_debug_int(int i)
{
char b[256];
move(1, 0);
sprintf(b, "[%06d]", i);
addstr(b);
refresh();
}
void
curses_debug_key(int i)
{
char b[256];
move(1, 0);
sprintf(b, "[%06d] %s", i, keyname(i));
addstr(b);
refresh();
}
void
curses_debug_float(float f)
{
char b[256];
move(1, 0);
sprintf(b, "[%09.3f]", f);
addstr(b);
refresh();
}
int
extract_wrapped_line(const char *text, char *line, int width, int *spos)
{
int dpos = 0;
int saved_spos, saved_dpos;
for (;;) {
while (isspace(text[*spos]) && text[*spos] != '\0') {
if (text[*spos] == '\n') {
line[dpos] = '\0';
(*spos)++;
return(0);
}
(*spos)++;
}
saved_spos = *spos;
saved_dpos = dpos;
while (!isspace(text[*spos]) &&
text[*spos] != '\0' &&
dpos < width) {
line[dpos++] = text[(*spos)++];
}
if (text[*spos] == '\0') {
line[dpos] = '\0';
return(1);
} else if (dpos >= width) {
if (dpos - saved_dpos >= width) {
line[width - 1] = '\0';
*spos = saved_spos + (dpos - saved_dpos);
return(0);
} else {
*spos = saved_spos;
line[saved_dpos - 1] = '\0';
return(0);
}
} else {
line[dpos++] = ' ';
}
}
}