Commit 7af774a7 authored by Wichert Akkerman's avatar Wichert Akkerman
Browse files

Add configurable colours to dselect

parent dce573c7
Mon Jul 16 01:50:58 CEST 2001 Wichert Akkerman <wakkerma@debian.org>
* Merge a reworked version of a patch from Joey Hess
+ dselect/dselect.8: Document new colour options
+ dselect/basecmds.cc: properly draw the background using helpscreen_attr
+ dselect/baselist.cc: change drawing code to use new changeable colours
+ dselect/dselect.h: Add all the colour structures
+ dselect/main.cc: Parse --colour options
Mon Jul 16 00:01:24 CEST 2001 Wichert Akkerman <wakkerma@debian.org>
* dselect/baselist.cc: include unistd.h which is needed to get the
......
......@@ -19,6 +19,7 @@ dpkg (1.10) unstable; urgency=low
* Split dselect into its own package. dpkg Pre-Depends on it
to make sure no weird things happen during an upgrade but this
will allow us to make dselect option at some point in the future.
* Make colours in dselect user-configurable. Closes: Bug#103994
-- Wichert Akkerman <wakkerma@debian.org> UNRELEASED
......
......@@ -119,12 +119,13 @@ void baselist::displayhelp(const struct helpmenuentry *helpmenu, int key) {
int maxx, maxy, i, y, x, nextkey;
getmaxyx(stdscr,maxy,maxx);
wbkgdset(stdscr, ' ' | helpscreen_attr);
clearok(stdscr,TRUE);
for (;;) {
werase(stdscr);
for (hme= helpmenu; hme->key && hme->key != key; hme++);
if (hme->key) {
attrset(list_attr);
attrset(helpscreen_attr);
mvaddstr(1,0, gettext(hme->msg->text));
attrset(title_attr);
mvaddstr(0,0, _("Help: "));
......
......@@ -115,19 +115,28 @@ void baselist::startdisplay() {
clear(); wnoutrefresh(stdscr);
// find attributes
if (has_colors() && start_color()==OK && COLOR_PAIRS >= 3) {
if (init_pair(1,COLOR_WHITE,COLOR_BLACK) != OK ||
init_pair(2,COLOR_WHITE,COLOR_RED) != OK ||
init_pair(3,COLOR_WHITE,COLOR_BLUE) != OK)
ohshite(_("failed to allocate colour pairs"));
list_attr= COLOR_PAIR(1);
listsel_attr= list_attr|A_REVERSE;
title_attr= COLOR_PAIR(2);
thisstate_attr= COLOR_PAIR(3);
selstate_attr= list_attr|A_BOLD;
selstatesel_attr= listsel_attr|A_BOLD;
colheads_attr= COLOR_PAIR(3);
if (has_colors() && start_color()==OK && COLOR_PAIRS >= numscreenparts) {
int i;
printf("allocing\n");
for (i = 1; i < numscreenparts; i++) {
if (init_pair(i, color[i].fore, color[i].back) != OK)
ohshite(_("failed to allocate colour pair"));
}
/* TODO: should use an array of attr's, indexed by attr name. Oh well. */
list_attr= COLOR_PAIR(list) | color[list].attr;
listsel_attr= COLOR_PAIR(listsel) | color[listsel].attr;
title_attr= COLOR_PAIR(title) | color[title].attr;
thisstate_attr= COLOR_PAIR(thisstate) | color[thisstate].attr;
selstate_attr= COLOR_PAIR(selstate) | color[selstate].attr;
selstatesel_attr= COLOR_PAIR(selstatesel) | color[selstatesel].attr;
colheads_attr= COLOR_PAIR(colheads) | color[colheads].attr;
query_attr= COLOR_PAIR(query) | color[query].attr;
info_attr= COLOR_PAIR(info) | color[info].attr;
info_headattr= COLOR_PAIR(info_head) | color[info_head].attr;
whatinfo_attr= COLOR_PAIR(whatinfo) | color[whatinfo].attr;
helpscreen_attr= COLOR_PAIR(helpscreen) | color[helpscreen].attr;
} else {
/* User defined attributes for B&W mode are not currently supported. */
title_attr= A_REVERSE;
thisstate_attr= A_STANDOUT;
list_attr= 0;
......@@ -135,11 +144,11 @@ void baselist::startdisplay() {
selstate_attr= A_BOLD;
selstatesel_attr= A_STANDOUT;
colheads_attr= A_BOLD;
query_attr= title_attr;
info_attr= list_attr;
info_headattr= A_BOLD;
whatinfo_attr= thisstate_attr;
}
query_attr= title_attr;
info_attr= list_attr;
info_headattr= A_BOLD;
whatinfo_attr= thisstate_attr;
// set up windows and pads, based on screen size
getmaxyx(stdscr,ymax,xmax);
......@@ -172,9 +181,11 @@ void baselist::startdisplay() {
infopad= newpad(MAX_DISPLAY_INFO, total_width);
if (!infopad) ohshite(_("failed to create info pad"));
wattrset(infopad,info_attr);
wbkgdset(infopad, ' ' | info_attr);
querywin= newwin(1,xmax,ymax-1,0);
if (!querywin) ohshite(_("failed to create query window"));
wbkgdset(querywin, ' ' | query_attr);
if (cursorline >= topofscreen + list_height) topofscreen= cursorline;
if (topofscreen > nitems - list_height) topofscreen= nitems - list_height;
......
......@@ -5,6 +5,7 @@ dselect \- Debian package management frontend
.B dselect
[\-\-admindir <directory>] [\-\-help] [\-\-version] [\-\-licence | \-\-license]
[\-\-expert] [\-\-debug | \-D <file>] [\fI<action>\fP]
[\-\-colour | \-\-color screenpart:[foreground],[background][:attr[+attr+..]]]
.SH DESCRIPTION
.B dselect
is the primary user interface for managing packages on a Debian system.
......@@ -51,6 +52,64 @@ Turn on debugging. Debugging information is sent to \fI<file>\fP.
Turns on expert mode, i.e. doesn't display possibly annoying help
messages.
.TP
.TP
.B --colour | --color screenpart:[foreground],[background][:attr[+attr+..]]
Configures screen colors. This works only if your display supports colors.
This option may be used multiple times (and is best used in
\fIdselect.cfg\fP). Each use changes the color (and optionally, other
attributes) of one part of the screen.
The parts of the screen (from top to bottom) are:
.RS
.TP
.B title
The screen title.
.TP
.B listhead
The header line above the list of packages.
.TP
.B list
The scrolling list of packages (and also some help text).
.TP
.B listsel
The selected item in the list.
.TP
.B pkgstate
In the list of packages, the text indicating the current state of each
package.
.TP
.B pkgstatesel
In the list of packages, the text indicating the current state of the
currently selected package.
.TP
.B infohead
The header line that displays the state of the currently selected package.
.TP
.B infodesc
The package's short description.
.TP
.B info
Used to display package info such as the package's description.
.TP
.B infofoot
The last line of the screen when selecting packages.
.TP
.B query
Used to display query lines
.TP
.B helpscreen
Color of help screens.
.RE
.P
After the part of the screen comes a colon and the color specification. You
can specify either the foreground color, the background color, or both,
overriding the compiled-in colors. Use standard curses color names.
.P
Optionally, after the color specification is another colon, and an
attribute specification. This is a list of one or more attributes,
separated by plus ("+") characters. Available attributes include (not all
of these will work on all terminals): normal, standout, underline, reverse,
blink, bright, dim, bold
.P
.B --help
Print a brief help text and exit successfully.
.TP
......
......@@ -47,7 +47,8 @@ protected:
int info_headattr, whatinfo_attr;
int thisstate_attr, query_attr;
int selstate_attr, selstatesel_attr;
int helpscreen_attr;
int total_width;
// (n)curses stuff
......@@ -142,6 +143,30 @@ extern const char *admindir;
extern FILE *debug;
extern int expertmode;
enum screenparts {
background,
list,
listsel,
title,
thisstate,
selstate,
selstatesel,
colheads,
query,
info,
info_head,
whatinfo,
helpscreen,
numscreenparts,
};
struct colordata {
int fore;
int back;
int attr;
};
extern colordata color[];
/* Evil recommends flag variable. */
extern int manual_install;
......
......@@ -56,10 +56,75 @@ const char printforhelp[]= N_("Type dselect --help for help.");
modstatdb_rw readwrite;
const char *admindir= ADMINDIR;
FILE *debug;
int expertmode = 0;
int expertmode= 0;
static keybindings packagelistbindings(packagelist_kinterps,packagelist_korgbindings);
struct table_t {
const char *name;
const int num;
};
static const struct table_t colourtable[]= {
{"black", COLOR_BLACK },
{"red", COLOR_RED },
{"green", COLOR_GREEN },
{"yellow", COLOR_YELLOW },
{"blue", COLOR_BLUE },
{"magenta", COLOR_MAGENTA },
{"cyan", COLOR_CYAN },
{"white", COLOR_WHITE },
{NULL, 0},
};
static const struct table_t attrtable[]= {
{"normal", A_NORMAL },
{"standout", A_STANDOUT },
{"underline", A_UNDERLINE },
{"reverse", A_REVERSE },
{"blink", A_BLINK },
{"bright", A_BLINK }, // on some terminals
{"dim", A_DIM },
{"bold", A_BOLD },
{NULL, 0},
};
/* A slightly confusing mapping from dselect's internal names to
* the user-visible names.*/
static const struct table_t screenparttable[]= {
{"list", list },
{"listsel", listsel },
{"title", title },
{"infohead", thisstate },
{"pkgstate", selstate },
{"pkgstatesel", selstatesel },
{"listhead", colheads },
{"query", query },
{"info", info },
{"infodesc", info_head },
{"infofoot", whatinfo },
{"helpscreen", helpscreen },
{NULL, 0},
};
/* Historical (patriotic?) colours. */
struct colordata color[]= {
/* fore back attr */
{COLOR_WHITE, COLOR_BLACK, 0 }, // default, not used
{COLOR_WHITE, COLOR_BLACK, 0 }, // list
{COLOR_WHITE, COLOR_BLACK, A_REVERSE }, // listsel
{COLOR_WHITE, COLOR_RED, 0 }, // title
{COLOR_WHITE, COLOR_BLUE, 0 }, // thisstate
{COLOR_WHITE, COLOR_BLACK, A_BOLD }, // selstate
{COLOR_WHITE, COLOR_BLACK, A_REVERSE | A_BOLD }, // selstatesel
{COLOR_WHITE, COLOR_BLUE, 0 }, // colheads
{COLOR_WHITE, COLOR_RED, 0 }, // query
{COLOR_WHITE, COLOR_BLACK, 0 }, // info
{COLOR_WHITE, COLOR_BLACK, A_BOLD }, // info_head
{COLOR_WHITE, COLOR_BLUE, 0 }, // whatinfo
{COLOR_WHITE, COLOR_BLACK, 0 }, // help
};
struct menuentry {
const char *command;
const char *key;
......@@ -98,13 +163,30 @@ static void printversion(void) {
}
static void usage(void) {
int i;
if (!fputs(
_("Usage: dselect [options]\n"
" dselect [options] action ...\n"
"Options: --admindir <directory> (default is /var/lib/dpkg)\n"
" --help --version --licence --expert --debug <file> | -D<file>\n"
"Actions: access update select install config remove quit menu\n"),
" --colour screenpart:[foreground],[background][:attr[+attr+..]]\n"
"Actions: access update select install config remove quit\n"),
stdout)) werr("stdout");
printf(_("Screenparts:\n"));
for (i=0; screenparttable[i].name; i++)
printf(" %s", screenparttable[i].name);
if (!fputs("\n", stdout)) werr("stdout");
printf(_("Colours:\n"));
for (i=0; colourtable[i].name; i++)
printf(" %s", colourtable[i].name);
if (!fputs("\n", stdout)) werr("stdout");
printf(_("Attributes:\n"));
for (i=0; attrtable[i].name; i++)
printf(" %s", attrtable[i].name);
if (!fputs("\n", stdout)) werr("stdout");
}
/* These are called by C code, so need to have C calling convention */
......@@ -126,20 +208,82 @@ extern "C" {
}
static void setexpert(const struct cmdinfo*, const char *v) {
expertmode = 1;
expertmode= 1;
}
int findintable(const struct table_t *table, const char *item, const char *tablename) {
int i;
for (i= 0; item && (table[i].name!=NULL); i++)
if (strcasecmp(item, table[i].name) == 0)
return table[i].num;
ohshit(_("Invalid %s `%s'\n"), tablename, item);
}
/*
* The string's format is:
* screenpart:[forecolor][,backcolor][:[<attr>, ...]
* Examples: --color title:black,cyan:bright+underline
* --color list:red,yellow
* --color colheads:,green:bright
* --color selstate::reverse // doesn't work FIXME
*/
static void setcolor(const struct cmdinfo*, const char *string) {
char *s= (char *) malloc((strlen(string) + 1) * sizeof(char));
char *colours, *attributes, *attrib, *colourname;
int screenpart, aval;
strcpy(s, string); // strtok modifies strings, keep string const
screenpart= findintable(screenparttable, strtok(s, ":"), _("screen part"));
colours= strtok(NULL, ":");
attributes= strtok(NULL, ":");
if ((colours == NULL || ! strlen(colours)) &&
(attributes == NULL || ! strlen(attributes))) {
ohshit(_("Null color specificaton\n"));
}
if (colours != NULL && strlen(colours)) {
colourname= strtok(colours, ",");
if (colourname != NULL && strlen(colourname)) {
// normalize attributes to prevent confusion
color[screenpart].attr= A_NORMAL;
color[screenpart].fore=findintable(colourtable, colourname, _("color"));
}
colourname= strtok(NULL, ",");
if (colourname != NULL && strlen(colourname)) {
color[screenpart].attr= A_NORMAL;
color[screenpart].back=findintable(colourtable, colourname, _("color"));
}
}
if (attributes != NULL && strlen(attributes)) {
for (attrib= strtok(attributes, "+");
attrib != NULL && strlen(attrib);
attrib= strtok(NULL, "+")) {
aval=findintable(attrtable, attrib, _("color attribute"));
if (aval == A_NORMAL) // set to normal
color[screenpart].attr= aval;
else // add to existing attribs
color[screenpart].attr= color[screenpart].attr | aval;
}
}
}
} /* End of extern "C" */
static const struct cmdinfo cmdinfos[]= {
{ "admindir", 0, 1, 0, &admindir, 0 },
{ "debug", 'D', 1, 0, 0, setdebug },
{ "expert", 'E', 0, 0, 0, setexpert },
{ "help", 'h', 0, 0, 0, helponly },
{ "version", 0, 0, 0, 0, versiononly },
{ "licence", 0, 0, 0, 0, showcopyright }, /* UK spelling */
{ "license", 0, 0, 0, 0, showcopyright }, /* US spelling */
{ 0, 0, 0, 0, 0, 0 }
{ "admindir", 0, 1, 0, &admindir, 0 },
{ "debug", 'D', 1, 0, 0, setdebug },
{ "expert", 'E', 0, 0, 0, setexpert },
{ "help", 'h', 0, 0, 0, helponly },
{ "version", 0, 0, 0, 0, versiononly },
{ "licence", 0, 0, 0, 0, showcopyright }, /* UK spelling */
{ "license", 0, 0, 0, 0, showcopyright }, /* US spelling */
{ "color", 0, 1, 0, 0, setcolor }, /* US spelling */
{ "colour", 0, 1, 0, 0, setcolor }, /* UK spelling */
{ 0, 0, 0, 0, 0, 0 }
};
static int cursesareon= 0;
......@@ -244,11 +388,11 @@ int refreshmenu(void) {
sprintf(buf,gettext(copyrightstring),DPKG_VERSION_ARCH);
addstr(buf);
l = strlen(admindir);
lockfile = new char[l+sizeof(LOCKFILE)+2];
l= strlen(admindir);
lockfile= new char[l+sizeof(LOCKFILE)+2];
strcpy(lockfile,admindir);
strcpy(lockfile+l, "/" LOCKFILE);
lockfd = open(lockfile, O_RDWR|O_CREAT|O_TRUNC, 0660);
lockfd= open(lockfile, O_RDWR|O_CREAT|O_TRUNC, 0660);
if (errno == EACCES || errno == EPERM)
addstr(_("\n\n"
"Read-only access: only preview of selections is available!"));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment