summaryrefslogtreecommitdiff
path: root/alpine/colorconf.c
diff options
context:
space:
mode:
authorEduardo Chappa <echappa@gmx.com>2013-02-03 00:59:38 -0700
committerEduardo Chappa <echappa@gmx.com>2013-02-03 00:59:38 -0700
commit094ca96844842928810f14844413109fc6cdd890 (patch)
treee60efbb980f38ba9308ccb4fb2b77b87bbc115f3 /alpine/colorconf.c
downloadalpine-094ca96844842928810f14844413109fc6cdd890.tar.xz
Initial Alpine Version
Diffstat (limited to 'alpine/colorconf.c')
-rw-r--r--alpine/colorconf.c2788
1 files changed, 2788 insertions, 0 deletions
diff --git a/alpine/colorconf.c b/alpine/colorconf.c
new file mode 100644
index 00000000..e0aee596
--- /dev/null
+++ b/alpine/colorconf.c
@@ -0,0 +1,2788 @@
+#if !defined(lint) && !defined(DOS)
+static char rcsid[] = "$Id: colorconf.c 934 2008-02-23 00:44:29Z hubert@u.washington.edu $";
+#endif
+
+/*
+ * ========================================================================
+ * Copyright 2006-2008 University of Washington
+ * Copyright 2013 Eduardo Chappa
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * ========================================================================
+ */
+
+
+#include "headers.h"
+#include "colorconf.h"
+#include "keymenu.h"
+#include "status.h"
+#include "confscroll.h"
+#include "radio.h"
+#include "mailview.h"
+#include "../pith/state.h"
+#include "../pith/util.h"
+#include "../pith/color.h"
+#include "../pith/icache.h"
+#include "../pith/mailcmd.h"
+#include "../pith/list.h"
+
+
+/*
+ * Internal prototypes
+ */
+char *color_setting_text_line(struct pine *, struct variable *);
+void revert_to_saved_color_config(struct pine *, SAVED_CONFIG_S *);
+SAVED_CONFIG_S *save_color_config_vars(struct pine *);
+void free_saved_color_config(struct pine *, SAVED_CONFIG_S **);
+void color_config_init_display(struct pine *, CONF_S **, CONF_S **);
+void add_header_color_line(struct pine *, CONF_S **, char *, int);
+int is_rgb_color(char *);
+char *new_color_line(char *, int, int, int);
+int color_text_tool(struct pine *, int, CONF_S **, unsigned);
+int offer_normal_color_for_var(struct pine *, struct variable *);
+int offer_none_color_for_var(struct pine *, struct variable *);
+void color_update_selected(struct pine *, CONF_S *, char *, char *, int);
+int color_edit_screen(struct pine *, CONF_S **);
+
+
+int treat_color_vars_as_text;
+
+
+void
+color_config_screen(struct pine *ps, int edit_exceptions)
+{
+ CONF_S *ctmp = NULL, *first_line = NULL;
+ SAVED_CONFIG_S *vsave;
+ OPT_SCREEN_S screen;
+ int readonly_warning = 0;
+
+ ps->next_screen = SCREEN_FUN_NULL;
+
+ mailcap_free(); /* free resources we won't be using for a while */
+
+ if(ps->fix_fixed_warning)
+ offer_to_fix_pinerc(ps);
+
+ ew = edit_exceptions ? ps_global->ew_for_except_vars : Main;
+
+ if(ps->restricted)
+ readonly_warning = 1;
+ else{
+ PINERC_S *prc = NULL;
+
+ switch(ew){
+ case Main:
+ prc = ps->prc;
+ break;
+ case Post:
+ prc = ps->post_prc;
+ break;
+ default:
+ break;
+ }
+
+ readonly_warning = prc ? prc->readonly : 1;
+ if(prc && prc->quit_to_edit){
+ quit_to_edit_msg(prc);
+ return;
+ }
+ }
+
+ color_config_init_display(ps, &ctmp, &first_line);
+
+ vsave = save_color_config_vars(ps);
+
+ memset(&screen, 0, sizeof(screen));
+ screen.deferred_ro_warning = readonly_warning;
+ switch(conf_scroll_screen(ps, &screen, first_line,
+ edit_exceptions ? _("SETUP COLOR EXCEPTIONS")
+ : _("SETUP COLOR"),
+ /* TRANSLATORS: Print something1 using something2.
+ configuration is something1 */
+ _("configuration"), 0)){
+ case 0:
+ break;
+
+ case 1:
+ write_pinerc(ps, ew, WRP_NONE);
+ break;
+
+ case 10:
+ revert_to_saved_color_config(ps, vsave);
+ break;
+
+ default:
+ q_status_message(SM_ORDER, 7, 10,
+ _("conf_scroll_screen bad ret in color_config"));
+ break;
+ }
+
+ free_saved_color_config(ps, &vsave);
+
+#ifdef _WINDOWS
+ mswin_set_quit_confirm (F_OFF(F_QUIT_WO_CONFIRM, ps_global));
+#endif
+}
+
+
+char *
+sample_text(struct pine *ps, struct variable *v)
+{
+ char *ret = SAMP2;
+ char *pvalfg, *pvalbg;
+
+ pvalfg = PVAL(v, ew);
+ pvalbg = PVAL(v+1, ew);
+
+ if((v && v->name &&
+ srchstr(v->name, "-foreground-color") &&
+ pvalfg && pvalfg[0] && pvalbg && pvalbg[0]) ||
+ (v == &ps->vars[V_VIEW_HDR_COLORS] || v == &ps->vars[V_KW_COLORS]))
+ ret = SAMP1;
+
+ return(ret);
+}
+
+
+char *
+sampleexc_text(struct pine *ps, struct variable *v)
+{
+ char *ret = "";
+ char *pvalfg, *pvalbg;
+
+ pvalfg = PVAL(v, Post);
+ pvalbg = PVAL(v+1, Post);
+ if(v && color_holding_var(ps, v) &&
+ srchstr(v->name, "-foreground-color")){
+ if(ew == Main && pvalfg && pvalfg[0] && pvalbg && pvalbg[0])
+ ret = SAMPEXC;
+ }
+
+ return(ret);
+}
+
+
+char *
+color_setting_text_line(struct pine *ps, struct variable *v)
+{
+ char *p;
+ char tmp[1200];
+
+ p = sampleexc_text(ps, v);
+
+ /*
+ * Don't need to use utf8_snprintf if we're not trying to
+ * control the widths of fields.
+ */
+ snprintf(tmp, sizeof(tmp), "%s %s%*s%s%s", SAMPLE_LEADER,
+ sample_text(ps,v), *p ? SBS : 0, "", p,
+ color_parenthetical(v));
+ return(cpystr(tmp));
+}
+
+
+/*
+ * Compare saved user_val with current user_val to see if it changed.
+ * If any have changed, change it back and take the appropriate action.
+ */
+void
+revert_to_saved_color_config(struct pine *ps, SAVED_CONFIG_S *vsave)
+{
+ struct variable *vreal;
+ SAVED_CONFIG_S *v;
+ int i, n;
+ int changed = 0;
+ char *pval, **apval, **lval, ***alval;
+
+ v = vsave;
+ for(vreal = ps->vars; vreal->name; vreal++,v++){
+ if(!(color_related_var(ps, vreal) || vreal==&ps->vars[V_FEATURE_LIST]))
+ continue;
+
+ if(vreal->is_list){
+ lval = LVAL(vreal, ew);
+ alval = ALVAL(vreal, ew);
+
+ if((v->saved_user_val.l && !lval)
+ || (!v->saved_user_val.l && lval))
+ changed++;
+ else if(!v->saved_user_val.l && !lval)
+ ;/* no change, nothing to do */
+ else
+ for(i = 0; v->saved_user_val.l[i] || lval[i]; i++)
+ if((v->saved_user_val.l[i]
+ && (!lval[i]
+ || strcmp(v->saved_user_val.l[i], lval[i])))
+ ||
+ (!v->saved_user_val.l[i] && lval[i])){
+ changed++;
+ break;
+ }
+
+ if(changed){
+ char **list;
+
+ if(alval){
+ if(*alval)
+ free_list_array(alval);
+
+ /* copy back the original one */
+ if(v->saved_user_val.l){
+ list = v->saved_user_val.l;
+ n = 0;
+ /* count how many */
+ while(list[n])
+ n++;
+
+ *alval = (char **)fs_get((n+1) * sizeof(char *));
+
+ for(i = 0; i < n; i++)
+ (*alval)[i] = cpystr(v->saved_user_val.l[i]);
+
+ (*alval)[n] = NULL;
+ }
+ }
+ }
+ }
+ else{
+ pval = PVAL(vreal, ew);
+ apval = APVAL(vreal, ew);
+
+ if((v->saved_user_val.p &&
+ (!pval || strcmp(v->saved_user_val.p, pval))) ||
+ (!v->saved_user_val.p && pval)){
+ /* It changed, fix it */
+ changed++;
+ if(apval){
+ /* free the changed value */
+ if(*apval)
+ fs_give((void **)apval);
+
+ if(v->saved_user_val.p)
+ *apval = cpystr(v->saved_user_val.p);
+ }
+ }
+ }
+
+ if(changed){
+ if(vreal == &ps->vars[V_FEATURE_LIST])
+ set_feature_list_current_val(vreal);
+ else
+ set_current_val(vreal, TRUE, FALSE);
+
+ fix_side_effects(ps, vreal, 1);
+ }
+ }
+
+ if(changed){
+ set_current_color_vals(ps);
+ ClearScreen();
+ ps->mangled_screen = 1;
+ }
+}
+
+
+SAVED_CONFIG_S *
+save_color_config_vars(struct pine *ps)
+{
+ struct variable *vreal;
+ SAVED_CONFIG_S *vsave, *v;
+
+ vsave = (SAVED_CONFIG_S *)fs_get((V_LAST_VAR+1)*sizeof(SAVED_CONFIG_S));
+ memset((void *)vsave, 0, (V_LAST_VAR+1)*sizeof(SAVED_CONFIG_S));
+ v = vsave;
+ for(vreal = ps->vars; vreal->name; vreal++,v++){
+ if(!(color_related_var(ps, vreal) || vreal==&ps->vars[V_FEATURE_LIST]))
+ continue;
+
+ if(vreal->is_list){
+ int n, i;
+ char **list;
+
+ if(LVAL(vreal, ew)){
+ /* count how many */
+ n = 0;
+ list = LVAL(vreal, ew);
+ while(list[n])
+ n++;
+
+ v->saved_user_val.l = (char **)fs_get((n+1) * sizeof(char *));
+ memset((void *)v->saved_user_val.l, 0, (n+1)*sizeof(char *));
+ for(i = 0; i < n; i++)
+ v->saved_user_val.l[i] = cpystr(list[i]);
+
+ v->saved_user_val.l[n] = NULL;
+ }
+ }
+ else{
+ if(PVAL(vreal, ew))
+ v->saved_user_val.p = cpystr(PVAL(vreal, ew));
+ }
+ }
+
+ return(vsave);
+}
+
+
+void
+free_saved_color_config(struct pine *ps, SAVED_CONFIG_S **vsavep)
+{
+ struct variable *vreal;
+ SAVED_CONFIG_S *v;
+
+ if(vsavep && *vsavep){
+ for(v = *vsavep, vreal = ps->vars; vreal->name; vreal++,v++){
+ if(!(color_related_var(ps, vreal) ||
+ (vreal == &ps->vars[V_FEATURE_LIST])))
+ continue;
+
+ if(vreal->is_list){ /* free saved_user_val.l */
+ if(v && v->saved_user_val.l)
+ free_list_array(&v->saved_user_val.l);
+ }
+ else if(v && v->saved_user_val.p)
+ fs_give((void **)&v->saved_user_val.p);
+ }
+
+ fs_give((void **)vsavep);
+ }
+}
+
+
+void
+color_config_init_display(struct pine *ps, CONF_S **ctmp, CONF_S **first_line)
+{
+ char **lval;
+ int i, saw_first_index = 0;
+ struct variable *vtmp;
+ char *dashes = "--------------";
+
+#ifndef _WINDOWS
+ vtmp = &ps->vars[V_COLOR_STYLE];
+
+ new_confline(ctmp);
+ (*ctmp)->flags |= (CF_NOSELECT | CF_STARTITEM);
+ (*ctmp)->keymenu = &config_radiobutton_keymenu;
+ (*ctmp)->tool = NULL;
+ (*ctmp)->varname = cpystr("Color Style");
+ (*ctmp)->varnamep = *ctmp;
+
+ standard_radio_setup(ps, ctmp, vtmp, first_line);
+
+ new_confline(ctmp);
+ /* Blank line */
+ (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
+
+ if(!pico_usingcolor()){
+ /* add a line explaining that color is not turned on */
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(COLORNOSET);
+
+ new_confline(ctmp);
+ /* Blank line */
+ (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
+ }
+
+#endif
+
+ vtmp = &ps->vars[V_INDEX_COLOR_STYLE];
+
+ new_confline(ctmp);
+ (*ctmp)->flags |= (CF_NOSELECT | CF_STARTITEM);
+ (*ctmp)->keymenu = &config_radiobutton_keymenu;
+ (*ctmp)->tool = NULL;
+ (*ctmp)->varname = cpystr(_("Current Indexline Style"));
+ (*ctmp)->varnamep = *ctmp;
+
+ standard_radio_setup(ps, ctmp, vtmp, NULL);
+
+ new_confline(ctmp);
+ /* Blank line */
+ (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
+
+ vtmp = &ps->vars[V_TITLEBAR_COLOR_STYLE];
+
+ new_confline(ctmp);
+ (*ctmp)->flags |= (CF_NOSELECT | CF_STARTITEM);
+ (*ctmp)->keymenu = &config_radiobutton_keymenu;
+ (*ctmp)->tool = NULL;
+ (*ctmp)->varname = cpystr(_("Titlebar Color Style"));
+ (*ctmp)->varnamep = *ctmp;
+
+ standard_radio_setup(ps, ctmp, vtmp, NULL);
+
+ new_confline(ctmp);
+ /* Blank line */
+ (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
+
+ new_confline(ctmp);
+ /* title before general colors */
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(_("GENERAL COLORS"));
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+
+ for(vtmp = ps->vars; vtmp->name; vtmp++){
+ if(!color_holding_var(ps, vtmp))
+ continue;
+
+ /* If not foreground, skip it */
+ if(!srchstr(vtmp->name, "-foreground-color"))
+ continue;
+
+ /* skip this for now and include it with HEADER COLORS */
+ if(vtmp == &ps->vars[V_HEADER_GENERAL_FORE_COLOR])
+ continue;
+
+ if(!saw_first_index && !struncmp(vtmp->name, "index-", 6)){
+ saw_first_index++;
+ new_confline(ctmp); /* Blank line */
+ (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(_("INDEX COLORS"));
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+ }
+
+ new_confline(ctmp);
+ /* Blank line */
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+
+ new_confline(ctmp)->var = vtmp;
+ if(first_line && !*first_line)
+ *first_line = *ctmp;
+
+ (*ctmp)->varnamep = *ctmp;
+ (*ctmp)->keymenu = &color_setting_keymenu;
+ (*ctmp)->help = config_help(vtmp - ps->vars, 0);
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
+ if(!pico_usingcolor())
+ (*ctmp)->flags |= CF_NOSELECT;
+
+ (*ctmp)->value = pretty_value(ps, *ctmp);
+ (*ctmp)->valoffset = COLOR_INDENT;
+ }
+
+ /*
+ * custom header colors
+ */
+ new_confline(ctmp); /* Blank line */
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(_("HEADER COLORS"));
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+
+ vtmp = &ps->vars[V_HEADER_GENERAL_FORE_COLOR];
+ new_confline(ctmp);
+ /* Blank line */
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+
+ new_confline(ctmp)->var = vtmp;
+
+ (*ctmp)->varnamep = *ctmp;
+ (*ctmp)->keymenu = &color_setting_keymenu;
+ (*ctmp)->help = config_help(vtmp - ps->vars, 0);
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
+ if(!pico_usingcolor())
+ (*ctmp)->flags |= CF_NOSELECT;
+
+ (*ctmp)->value = pretty_value(ps, *ctmp);
+ (*ctmp)->valoffset = COLOR_INDENT;
+
+ vtmp = &ps->vars[V_VIEW_HDR_COLORS];
+ lval = LVAL(vtmp, ew);
+
+ if(lval && lval[0] && lval[0][0]){
+ for(i = 0; lval && lval[i]; i++)
+ add_header_color_line(ps, ctmp, lval[i], i);
+ }
+ else{
+ new_confline(ctmp); /* Blank line */
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(_(ADDHEADER_COMMENT));
+ (*ctmp)->valoffset = COLOR_INDENT;
+ }
+
+
+ /*
+ * custom keyword colors
+ */
+ new_confline(ctmp); /* Blank line */
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(KW_COLORS_HDR);
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(dashes);
+
+
+ if(ps->keywords){
+ KEYWORD_S *kw;
+ char *name, *comment, *word;
+ int j, lv = 0, lc = 0, ltot = 0, eq_col = EQ_COL;
+
+ vtmp = &ps->vars[V_KW_COLORS];
+
+ /* first figure out widths for display */
+ for(kw = ps->keywords; kw; kw = kw->next){
+ word = kw->nick ? kw->nick : kw->kw ? kw->kw : "";
+ i = utf8_width(word);
+ if(lv < i)
+ lv = i;
+
+ j = 0;
+ if(kw->nick && kw->kw && kw->kw[0]){
+ word = kw->kw;
+ j = utf8_width(word) + 2;
+ if(lc < j)
+ lc = j;
+ }
+
+ if(ltot < (i + (j > 2 ? j : 0)))
+ ltot = (i + (j > 2 ? j : 0));
+ }
+
+ lv = MIN(lv, 100);
+ lc = MIN(lc, 100);
+ ltot = MIN(ltot, 100);
+
+ /*
+ * SC is width of " Color"
+ * SS is space between nickname and keyword value
+ * SW is space between words and Sample
+ */
+#define SC 6
+#define SS 1
+#define SW 3
+ if(COLOR_INDENT + SC + ltot + (lc>0?SS:0) > eq_col - SW){
+ eq_col = MIN(MAX(ps->ttyo->screen_cols - 10, 20),
+ COLOR_INDENT + SC + ltot + (lc>0?SS:0) + SW);
+ if(COLOR_INDENT + SC + ltot + (lc>0?SS:0) > eq_col - SW){
+ eq_col = MIN(MAX(ps->ttyo->screen_cols - 10, 20),
+ COLOR_INDENT + SC + lv + (lc>0?SS:0) + lc + SW);
+ if(COLOR_INDENT + SC + lv + (lc>0?SS:0) + lc > eq_col - SW){
+ lc = MIN(lc, MAX(eq_col - SW - COLOR_INDENT - SC - lv - SS, 7));
+ if(COLOR_INDENT + SC + lv + (lc>0?SS:0) + lc > eq_col - SW){
+ lc = 0;
+ if(COLOR_INDENT + SC + lv > eq_col - SW){
+ lv = MAX(eq_col - SW - COLOR_INDENT - SC, 7);
+ }
+ }
+ }
+ }
+ }
+
+ lval = LVAL(vtmp, ew);
+ if(lval && lval[0] && !strcmp(lval[0], INHERIT)){
+ new_confline(ctmp);
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+
+ new_confline(ctmp)->var = vtmp;
+ (*ctmp)->varnamep = *ctmp;
+ (*ctmp)->keymenu = &kw_color_setting_keymenu;
+ (*ctmp)->help = config_help(vtmp - ps->vars, 0);
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->varmem = CFC_SET_COLOR(i, 0);
+ (*ctmp)->valoffset = COLOR_INDENT;
+
+ (*ctmp)->flags = (CF_NOSELECT | CF_INHERIT);
+ }
+
+ /* now create the config lines */
+ for(kw = ps->keywords, i = 0; kw; kw = kw->next, i++){
+ char tmp[2000];
+
+ /* Blank line */
+ new_confline(ctmp);
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+
+ new_confline(ctmp)->var = vtmp;
+ (*ctmp)->varnamep = *ctmp;
+ (*ctmp)->keymenu = &kw_color_setting_keymenu;
+ (*ctmp)->help = config_help(vtmp - ps->vars, 0);
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
+ if(!pico_usingcolor())
+ (*ctmp)->flags |= CF_NOSELECT;
+
+ /*
+ * Not actually a color in this case, it is an index into
+ * the keywords list.
+ */
+ (*ctmp)->varmem = CFC_SET_COLOR(i, 0);
+
+ name = short_str(kw->nick ? kw->nick : kw->kw ? kw->kw : "",
+ tmp_20k_buf+10000, 1000, lv, EndDots);
+ if(lc > 0 && kw->nick && kw->kw && kw->kw[0])
+ comment = short_str(kw->kw, tmp_20k_buf+11000, SIZEOF_20KBUF - 11000, lc, EndDots);
+ else
+ comment = NULL;
+
+ utf8_snprintf(tmp, sizeof(tmp), "%.*w%*s%s%.*w%s Color%*s %s%s",
+ lv, name,
+ (lc > 0 && comment) ? SS : 0, "",
+ (lc > 0 && comment) ? "(" : "",
+ (lc > 0 && comment) ? lc : 0, (lc > 0 && comment) ? comment : "",
+ (lc > 0 && comment) ? ")" : "",
+ MAX(MIN(eq_col - COLOR_INDENT - MIN(lv,utf8_width(name))
+ - SC - 1
+ - ((lc > 0 && comment)
+ ? (SS+2+MIN(lc,utf8_width(comment))) : 0), 100), 0), "",
+ sample_text(ps,vtmp),
+ color_parenthetical(vtmp));
+
+ (*ctmp)->value = cpystr(tmp);
+ (*ctmp)->valoffset = COLOR_INDENT;
+ }
+ }
+ else{
+ new_confline(ctmp); /* Blank line */
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+ new_confline(ctmp);
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->value = cpystr(_("[ Use Setup/Config command to add Keywords ]"));
+ (*ctmp)->valoffset = COLOR_INDENT;
+ }
+}
+
+
+char *
+color_parenthetical(struct variable *var)
+{
+ int norm, exc, exc_inh;
+ char **lval, *ret = "";
+
+ if(var == &ps_global->vars[V_VIEW_HDR_COLORS]
+ || var == &ps_global->vars[V_KW_COLORS]){
+ norm = (LVAL(var, Main) != NULL);
+ exc = (LVAL(var, ps_global->ew_for_except_vars) != NULL);
+ exc_inh = ((lval=LVAL(var, ps_global->ew_for_except_vars)) &&
+ lval[0] && !strcmp(INHERIT, lval[0]));
+
+ /* editing normal but there is an exception config */
+ if((ps_global->ew_for_except_vars != Main) && (ew == Main)){
+ if((exc && !exc_inh))
+ ret = _(" (overridden by exceptions)");
+ else if(exc && exc_inh)
+ ret = _(" (more in exceptions)");
+ }
+ /* editing exception config */
+ else if((ps_global->ew_for_except_vars != Main) &&
+ (ew == ps_global->ew_for_except_vars)){
+ if(exc && exc_inh && norm)
+ ret = _(" (more in main config)");
+ }
+ }
+
+ return(ret);
+}
+
+
+void
+add_header_color_line(struct pine *ps, CONF_S **ctmp, char *val, int which)
+{
+ struct variable *vtmp;
+ SPEC_COLOR_S *hc;
+ char tmp[100+1];
+ int l;
+
+ vtmp = &ps->vars[V_VIEW_HDR_COLORS];
+ l = strlen(HEADER_WORD);
+
+ /* Blank line */
+ new_confline(ctmp);
+ (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
+
+ new_confline(ctmp)->var = vtmp;
+ (*ctmp)->varnamep = *ctmp;
+ (*ctmp)->keymenu = &custom_color_setting_keymenu;
+ (*ctmp)->help = config_help(vtmp - ps->vars, 0);
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
+ if(!pico_usingcolor())
+ (*ctmp)->flags |= CF_NOSELECT;
+
+ /* which is an index into the variable list */
+ (*ctmp)->varmem = CFC_SET_COLOR(which, 0);
+
+ hc = spec_color_from_var(val, 0);
+ if(hc && hc->inherit)
+ (*ctmp)->flags = (CF_NOSELECT | CF_INHERIT);
+ else{
+ /*
+ * This isn't quite right because of the assumption that the
+ * first character of spec fits in one octet. I haven't tried
+ * to figure out what we're really trying to accomplish
+ * with all this. It probably doesn't happen in real life.
+ */
+ utf8_snprintf(tmp, sizeof(tmp), "%s%c%.*w Color%*w %s%s",
+ HEADER_WORD,
+ (hc && hc->spec) ? (islower((unsigned char)hc->spec[0])
+ ? toupper((unsigned char)hc->spec[0])
+ : hc->spec[0]) : '?',
+ MIN(utf8_width((hc && hc->spec && hc->spec[0]) ? hc->spec+1 : ""),30-l),
+ (hc && hc->spec && hc->spec[0]) ? hc->spec+1 : "",
+ MAX(EQ_COL - COLOR_INDENT -1 -
+ MIN(utf8_width((hc && hc->spec && hc->spec[0]) ? hc->spec+1 : ""),30-l)
+ - l - 6 - 1, 0), "",
+ sample_text(ps,vtmp),
+ color_parenthetical(vtmp));
+ tmp[sizeof(tmp)-1] = '\0';
+ (*ctmp)->value = cpystr(tmp);
+ }
+
+ (*ctmp)->valoffset = COLOR_INDENT;
+
+ if(hc)
+ free_spec_colors(&hc);
+}
+
+
+/*
+ * Set up the standard color setting display for one color.
+ *
+ * Args fg -- the current foreground color
+ * bg -- the current background color
+ * def -- default box should be checked
+ */
+void
+add_color_setting_disp(struct pine *ps, CONF_S **ctmp, struct variable *var,
+ CONF_S *varnamep, struct key_menu *km,
+ struct key_menu *cb_km, HelpType help, int indent,
+ int which, char *fg, char *bg, int def)
+{
+ int i, lv, count, trans_is_on, transparent;
+ char tmp[100+1];
+ char *title = _("HELP FOR SETTING UP COLOR");
+ int fg_is_custom = 1, bg_is_custom = 1;
+#ifdef _WINDOWS
+ CONF_S *cl_custom = NULL;
+#else
+ char *pvalfg, *pvalbg;
+#endif
+
+
+ /* find longest value's name */
+ count = pico_count_in_color_table();
+ lv = COLOR_BLOB_LEN;
+
+ trans_is_on = pico_trans_is_on();
+
+ /* put a title before list */
+ new_confline(ctmp);
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = km;
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ (*ctmp)->flags |= CF_NOSELECT;
+ (*ctmp)->varmem = 0;
+
+ /*
+ * The width of Foreground plus the spaces before Background should
+ * be about lv + 5 + SPACE_BETWEEN_DOUBLEVARS.
+ */
+ (*ctmp)->value = cpystr("Foreground Background");
+
+ new_confline(ctmp)->var = var;
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = km;
+ (*ctmp)->help = NO_HELP;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ (*ctmp)->flags |= (CF_COLORSAMPLE | CF_NOSELECT);
+ (*ctmp)->varmem = CFC_SET_COLOR(which, 0);
+ (*ctmp)->value = color_setting_text_line(ps, var);
+
+ for(i = 0; i < count; i++){
+ new_confline(ctmp)->var = var;
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = km;
+ (*ctmp)->help = help;
+ (*ctmp)->help_title = title;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ /* 5 is length of "( ) " */
+ (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
+ (*ctmp)->flags |= CF_DOUBLEVAR;
+ (*ctmp)->varmem = CFC_SET_COLOR(which, i);
+
+ transparent = (trans_is_on && i == count-1);
+ if(transparent)
+ (*ctmp)->help = h_config_usetransparent_color;
+
+ if(fg_is_custom && fg && !strucmp(color_to_canonical_name(fg), colorx(i)))
+ fg_is_custom = 0;
+
+ if(bg_is_custom && bg && !strucmp(color_to_canonical_name(bg), colorx(i)))
+ bg_is_custom = 0;
+
+ (*ctmp)->value = new_color_line(transparent ? COLOR_BLOB_TRAN
+ : COLOR_BLOB,
+ fg &&
+ !strucmp(color_to_canonical_name(fg), colorx(i)),
+ bg &&
+ !strucmp(color_to_canonical_name(bg), colorx(i)),
+ lv);
+ }
+
+#ifdef _WINDOWS
+ new_confline(ctmp)->var = var;
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = (km == &custom_color_changing_keymenu)
+ ? &custom_rgb_keymenu :
+ (km == &kw_color_changing_keymenu)
+ ? &kw_rgb_keymenu : &color_rgb_keymenu;
+ (*ctmp)->help = help;
+ (*ctmp)->help_title = title;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ /* 5 is length of "( ) " */
+ (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
+ (*ctmp)->flags |= CF_DOUBLEVAR;
+ (*ctmp)->varmem = CFC_SET_COLOR(which, i);
+ cl_custom = (*ctmp);
+#endif
+
+ if(offer_normal_color_for_var(ps, var)){
+ new_confline(ctmp)->var = var;
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = km;
+ (*ctmp)->help = h_config_usenormal_color;
+ (*ctmp)->help_title = title;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ /* 5 is length of "( ) " */
+ (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
+ (*ctmp)->flags |= CF_DOUBLEVAR;
+ (*ctmp)->varmem = CFC_SET_COLOR(which, CFC_ICOLOR_NORM);
+ if(fg_is_custom && fg && !struncmp(fg, MATCH_NORM_COLOR, RGBLEN))
+ fg_is_custom = 0;
+
+ if(bg_is_custom && bg && !struncmp(bg, MATCH_NORM_COLOR, RGBLEN))
+ bg_is_custom = 0;
+
+ (*ctmp)->value = new_color_line(COLOR_BLOB_NORM,
+ fg && !struncmp(fg, MATCH_NORM_COLOR, RGBLEN),
+ bg && !struncmp(bg, MATCH_NORM_COLOR, RGBLEN),
+ lv);
+ }
+
+ if(offer_none_color_for_var(ps, var)){
+ new_confline(ctmp)->var = var;
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = km;
+ (*ctmp)->help = h_config_usenone_color;
+ (*ctmp)->help_title = title;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ /* 5 is length of "( ) " */
+ (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
+ (*ctmp)->flags |= CF_DOUBLEVAR;
+ (*ctmp)->varmem = CFC_SET_COLOR(which, CFC_ICOLOR_NONE);
+ if(fg_is_custom && fg && !struncmp(fg, MATCH_NONE_COLOR, RGBLEN))
+ fg_is_custom = 0;
+
+ if(bg_is_custom && bg && !struncmp(bg, MATCH_NONE_COLOR, RGBLEN))
+ bg_is_custom = 0;
+
+ (*ctmp)->value = new_color_line(COLOR_BLOB_NONE,
+ fg && !struncmp(fg, MATCH_NONE_COLOR, RGBLEN),
+ bg && !struncmp(bg, MATCH_NONE_COLOR, RGBLEN),
+ lv);
+ }
+
+#ifdef _WINDOWS
+ if(cl_custom)
+ cl_custom->value = new_color_line("Custom", fg_is_custom, bg_is_custom, lv);
+#endif
+
+ new_confline(ctmp)->var = var;
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = cb_km;
+ (*ctmp)->help = h_config_dflt_color;
+ (*ctmp)->help_title = title;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ (*ctmp)->varmem = CFC_SET_COLOR(which, 0);
+#ifdef _WINDOWS
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ', "Default");
+ tmp[sizeof(tmp)-1] = '\0';
+#else
+ pvalfg = PVAL(var,Main);
+ pvalbg = PVAL(var+1,Main);
+ if(!var->is_list &&
+ ((var == &ps->vars[V_NORM_FORE_COLOR]) ||
+ (ew == Post && pvalfg && pvalfg[0] && pvalbg && pvalbg[0]) ||
+ (var->global_val.p && var->global_val.p[0] &&
+ (var+1)->global_val.p && (var+1)->global_val.p[0])))
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ', "Default");
+ else if(var == &ps->vars[V_REV_FORE_COLOR])
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
+ "Default (terminal's standout mode, usually reverse video)");
+ else if(var == &ps->vars[V_SLCTBL_FORE_COLOR])
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
+ "Default (Bold Normal Color)");
+ else if(var == &ps->vars[V_TITLECLOSED_FORE_COLOR])
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
+ "Default (same as Title Color)");
+ else if(var_defaults_to_rev(var))
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
+ "Default (same as Reverse Color)");
+ else if(km == &kw_color_changing_keymenu)
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
+ "Default (same as Indexline Color)");
+ else
+ snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
+ "Default (same as Normal Color)");
+
+ tmp[sizeof(tmp)-1] = '\0';
+#endif
+ (*ctmp)->value = cpystr(tmp);
+
+ /*
+ * Add a checkbox to turn bold on or off for selectable-item color.
+ */
+ if(var == &ps->vars[V_SLCTBL_FORE_COLOR]){
+ char **lval;
+
+ new_confline(ctmp)->var = var;
+ (*ctmp)->varnamep = varnamep;
+ (*ctmp)->keymenu = &selectable_bold_checkbox_keymenu;
+ (*ctmp)->help = h_config_bold_slctbl;
+ (*ctmp)->help_title = title;
+ (*ctmp)->tool = color_setting_tool;
+ (*ctmp)->valoffset = indent;
+ (*ctmp)->varmem = feature_list_index(F_SLCTBL_ITEM_NOBOLD);
+
+ lval = LVAL(&ps->vars[V_FEATURE_LIST], ew);
+ /*
+ * We don't use checkbox_pretty_value here because we just want
+ * the word Bold instead of the name of the variable and because
+ * we are actually using the negative of the feature. That is,
+ * the feature is really NOBOLD and we are using Bold.
+ */
+ snprintf(tmp, sizeof(tmp), "[%c] %s",
+ test_feature(lval, feature_list_name(F_SLCTBL_ITEM_NOBOLD), 0)
+ ? ' ' : 'X', "Bold");
+ tmp[sizeof(tmp)-1] = '\0';
+
+ (*ctmp)->value = cpystr(tmp);
+ }
+}
+
+
+int
+is_rgb_color(char *color)
+{
+ int i, j;
+
+ for(i = 0; i < 3; i++){
+ if(i && *color++ != ',')
+ return(FALSE);
+
+ for(j = 0; j < 3; j++, color++)
+ if(!isdigit((unsigned char) *color))
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
+char *
+new_color_line(char *color, int fg, int bg, int len)
+{
+ char tmp[256];
+
+ snprintf(tmp, sizeof(tmp), "(%c) %-*.*s%*s(%c) %-*.*s",
+ fg ? R_SELD : ' ', len, len, color, SPACE_BETWEEN_DOUBLEVARS, "",
+ bg ? R_SELD : ' ', len, len, color);
+ tmp[sizeof(tmp)-1] = '\0';
+ return(cpystr(tmp));
+}
+
+
+int
+color_text_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
+{
+ int rv = 0, i;
+ struct variable v, *save_var;
+ SPEC_COLOR_S *hc, *hcolors;
+ char *starting_val, *val, tmp[100], ***alval, **apval;
+
+ if(cmd == MC_EXIT)
+ return(simple_exit_cmd(flags));
+
+ alval = ALVAL((*cl)->var, ew);
+ if(!alval || !*alval)
+ return(rv);
+
+ hcolors = spec_colors_from_varlist(*alval, 0);
+
+ for(hc = hcolors, i=0; hc; hc = hc->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ starting_val = (hc && hc->val) ? pattern_to_string(hc->val) : NULL;
+
+ memset(&v, 0, sizeof(v));
+ v.is_used = 1;
+ v.is_user = 1;
+ snprintf(tmp, sizeof(tmp), "\"%c%s Pattern\"",
+ islower((unsigned char)hc->spec[0])
+ ? toupper((unsigned char)hc->spec[0])
+ : hc->spec[0],
+ hc->spec[1] ? hc->spec + 1 : "");
+ tmp[sizeof(tmp)-1] = '\0';
+ v.name = tmp;
+ /* have to use right part of v so text_tool will work right */
+ apval = APVAL(&v, ew);
+ *apval = starting_val ? cpystr(starting_val) : NULL;
+ set_current_val(&v, FALSE, FALSE);
+
+ save_var = (*cl)->var;
+ (*cl)->var = &v;
+ rv = text_tool(ps, cmd, cl, flags);
+
+ if(rv == 1){
+ val = *apval;
+ *apval = NULL;
+ if(val)
+ removing_leading_and_trailing_white_space(val);
+
+ if(hc->val)
+ fs_give((void **)&hc->val);
+
+ hc->val = string_to_pattern(val);
+
+ (*cl)->var = save_var;
+
+ if((*alval)[CFC_ICUST(*cl)])
+ fs_give((void **)&(*alval)[CFC_ICUST(*cl)]);
+
+ (*alval)[CFC_ICUST(*cl)] = var_from_spec_color(hc);
+ set_current_color_vals(ps);
+ ps->mangled_screen = 1;
+ }
+ else
+ (*cl)->var = save_var;
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+ if(*apval)
+ fs_give((void **)apval);
+ if(v.current_val.p)
+ fs_give((void **)&v.current_val.p);
+ if(starting_val)
+ fs_give((void **)&starting_val);
+
+ return(rv);
+}
+
+
+/*
+ * Test whether or not a var is one of the vars which might have a
+ * color value stored in it.
+ *
+ * returns: 1 if it is a color var, 0 otherwise
+ */
+int
+color_holding_var(struct pine *ps, struct variable *var)
+{
+ if(treat_color_vars_as_text)
+ return(0);
+ else
+ return(var && var->name &&
+ (srchstr(var->name, "-foreground-color") ||
+ srchstr(var->name, "-background-color") ||
+ var == &ps->vars[V_VIEW_HDR_COLORS] ||
+ var == &ps->vars[V_KW_COLORS]));
+}
+
+
+/*
+ * test whether or not a var is one of the vars having to do with color
+ *
+ * returns: 1 if it is a color var, 0 otherwise
+ */
+int
+color_related_var(struct pine *ps, struct variable *var)
+{
+ return(
+#ifndef _WINDOWS
+ var == &ps->vars[V_COLOR_STYLE] ||
+#endif
+ var == &ps->vars[V_INDEX_COLOR_STYLE] ||
+ var == &ps->vars[V_TITLEBAR_COLOR_STYLE] ||
+ color_holding_var(ps, var));
+}
+
+
+int
+offer_normal_color_for_var(struct pine *ps, struct variable *var)
+{
+ return(color_holding_var(ps, var)
+ && var != &ps->vars[V_NORM_FORE_COLOR]
+ && var != &ps->vars[V_NORM_BACK_COLOR]
+ && var != &ps->vars[V_REV_FORE_COLOR]
+ && var != &ps->vars[V_REV_BACK_COLOR]
+ && var != &ps->vars[V_SLCTBL_FORE_COLOR]
+ && var != &ps->vars[V_SLCTBL_BACK_COLOR]);
+}
+
+
+int
+offer_none_color_for_var(struct pine *ps, struct variable *var)
+{
+ return(color_holding_var(ps, var)
+ && (!struncmp(var->name, "index-", 6)
+ || var == &ps->vars[V_KW_COLORS]));
+}
+
+
+int
+color_setting_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
+{
+ int rv = 0, i, cancel = 0, deefault;
+ int curcolor, prevcolor, nextcolor, another;
+ CONF_S *ctmp, *first_line, *beg = NULL, *end = NULL,
+ *cur_beg, *cur_end, *prev_beg, *prev_end,
+ *next_beg, *next_end;
+ struct variable *v, *fgv, *bgv, *setv = NULL, *otherv;
+ SPEC_COLOR_S *hc = NULL, *new_hcolor;
+ SPEC_COLOR_S *hcolors = NULL;
+ KEYWORD_S *kw;
+ char *old_val, *confline = NULL;
+ char prompt[100], sval[MAXPATH+1];
+ char **lval, **apval, ***alval, **t;
+ char **apval1, **apval2;
+ HelpType help;
+ ESCKEY_S opts[3];
+#ifdef _WINDOWS
+ char *pval;
+#endif
+
+ sval[0] = '\0';
+
+ switch(cmd){
+ case MC_CHOICE : /* set a color */
+
+ if(((*cl)->flags & CF_VAR2 && fixed_var((*cl)->var+1, NULL, NULL)) ||
+ (!((*cl)->flags & CF_VAR2) && fixed_var((*cl)->var, NULL, NULL))){
+ if(((*cl)->var->post_user_val.p ||
+ ((*cl)->var+1)->post_user_val.p ||
+ (*cl)->var->main_user_val.p ||
+ ((*cl)->var+1)->main_user_val.p)
+ && want_to(_("Delete old unused personal option setting"),
+ 'y', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
+ delete_user_vals((*cl)->var);
+ delete_user_vals((*cl)->var+1);
+ q_status_message(SM_ORDER, 0, 3, _("Deleted"));
+ rv = 1;
+ }
+
+ return(rv);
+ }
+
+ fgv = (*cl)->var; /* foreground color */
+ bgv = (*cl)->var+1; /* background color */
+ v = ((*cl)->flags & CF_VAR2) ? bgv : fgv; /* var being changed */
+
+ apval = APVAL(v, ew);
+ old_val = apval ? *apval : NULL;
+
+ if(apval){
+ if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
+ *apval = cpystr(colorx(CFC_ICOLOR(*cl)));
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
+ *apval = cpystr(MATCH_NORM_COLOR);
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
+ *apval = cpystr(MATCH_NONE_COLOR);
+ else if(old_val)
+ *apval = cpystr(is_rgb_color(old_val)
+ ? old_val : color_to_asciirgb(old_val));
+ else if(v->current_val.p)
+ *apval = cpystr(is_rgb_color(v->current_val.p)
+ ? v->current_val.p
+ : color_to_asciirgb(v->current_val.p));
+ else if(v == fgv)
+ *apval = cpystr(color_to_asciirgb(colorx(COL_BLACK)));
+ else
+ *apval = cpystr(color_to_asciirgb(colorx(COL_WHITE)));
+ }
+
+ if(old_val)
+ fs_give((void **)&old_val);
+
+ set_current_val(v, TRUE, FALSE);
+
+ /*
+ * If the user sets one of foreground/background and the
+ * other is not yet set, set the other.
+ */
+ if(PVAL(v, ew)){
+ if(v == fgv && !PVAL(bgv, ew)){
+ setv = bgv;
+ otherv = fgv;
+ }
+ else if(v == bgv && !PVAL(fgv, ew)){
+ setv = fgv;
+ otherv = bgv;
+ }
+ }
+
+ if(setv){
+ if((apval = APVAL(setv, ew)) != NULL){
+ if(setv->current_val.p)
+ *apval = cpystr(setv->current_val.p);
+ else if (setv == fgv && ps_global->VAR_NORM_FORE_COLOR)
+ *apval = cpystr(ps_global->VAR_NORM_FORE_COLOR);
+ else if (setv == bgv && ps_global->VAR_NORM_BACK_COLOR)
+ *apval = cpystr(ps_global->VAR_NORM_BACK_COLOR);
+ else if(!strucmp(color_to_canonical_name(otherv->current_val.p),
+ colorx(COL_WHITE)))
+ *apval = cpystr(colorx(COL_BLACK));
+ else
+ *apval = cpystr(colorx(COL_WHITE));
+ }
+
+ set_current_val(setv, TRUE, FALSE);
+ }
+
+ fix_side_effects(ps, v, 0);
+ set_current_color_vals(ps);
+
+ /*
+ * Turn on selected *'s for default selections, if any, and
+ * for ones we forced on.
+ */
+ color_update_selected(ps, *cl, PVAL(fgv, ew), PVAL(bgv, ew), TRUE);
+
+ ClearScreen();
+ rv = ps->mangled_screen = 1;
+ break;
+
+ case MC_CHOICEB : /* set a custom hdr color */
+ /*
+ * Find the SPEC_COLOR_S for header.
+ */
+ lval = LVAL((*cl)->var, ew);
+ hcolors = spec_colors_from_varlist(lval, 0);
+ for(hc = hcolors, i=0; hc; hc = hc->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ if(hc){
+ if((*cl)->flags & CF_VAR2){
+ old_val = hc->bg;
+ if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
+ hc->bg = cpystr(colorx(CFC_ICOLOR(*cl)));
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
+ hc->bg = cpystr(MATCH_NORM_COLOR);
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
+ hc->bg = cpystr(MATCH_NONE_COLOR);
+ else if(old_val)
+ hc->bg = cpystr(is_rgb_color(old_val)
+ ? old_val
+ : color_to_asciirgb(old_val));
+ else
+ hc->bg = cpystr(color_to_asciirgb(colorx(COL_WHITE)));
+
+ if(old_val)
+ fs_give((void **) &old_val);
+
+ /*
+ * If the user sets one of foreground/background and the
+ * other is not yet set, set it.
+ */
+ if(!(hc->fg && hc->fg[0])){
+ if(hc->fg)
+ fs_give((void **)&hc->fg);
+
+ hc->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
+ }
+ }
+ else{
+ old_val = hc->fg;
+
+ if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
+ hc->fg = cpystr(colorx(CFC_ICOLOR(*cl)));
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
+ hc->fg = cpystr(MATCH_NORM_COLOR);
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
+ hc->fg = cpystr(MATCH_NONE_COLOR);
+ else if(old_val)
+ hc->fg = cpystr(is_rgb_color(old_val)
+ ? old_val
+ : color_to_asciirgb(old_val));
+ else
+ hc->fg = cpystr(color_to_asciirgb(colorx(COL_BLACK)));
+
+ if(old_val)
+ fs_give((void **) &old_val);
+
+ if(!(hc->bg && hc->bg[0])){
+ if(hc->bg)
+ fs_give((void **)&hc->bg);
+
+ hc->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
+ }
+ }
+ }
+
+ /*
+ * Turn on selected *'s for default selections, if any, and
+ * for ones we forced on.
+ */
+ color_update_selected(ps, *cl,
+ (hc && hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->fg : ps->VAR_NORM_FORE_COLOR,
+ (hc && hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->bg : ps->VAR_NORM_BACK_COLOR,
+ TRUE);
+
+ if(hc && lval && lval[i]){
+ fs_give((void **)&lval[i]);
+ lval[i] = var_from_spec_color(hc);
+ }
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+
+ set_current_color_vals(ps);
+ ClearScreen();
+ rv = ps->mangled_screen = 1;
+ break;
+
+
+ case MC_CHOICEC : /* set a custom keyword color */
+ /* find keyword associated with color we are editing */
+ for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ if(!kw){ /* can't happen */
+ dprint((1,
+ "This can't happen, kw not set when setting keyword color\n"));
+ break;
+ }
+
+ hcolors = spec_colors_from_varlist(LVAL((*cl)->var, ew), 0);
+
+ /*
+ * Look through hcolors, derived from lval, to find this keyword
+ * and its current color.
+ */
+ for(hc = hcolors; hc; hc = hc->next)
+ if(hc->spec && ((kw->nick && !strucmp(kw->nick, hc->spec))
+ || (kw->kw && !strucmp(kw->kw, hc->spec))))
+ break;
+
+ if(!hc){ /* this keyword didn't have a color set, add to list */
+ SPEC_COLOR_S *new;
+
+ new = (SPEC_COLOR_S *) fs_get(sizeof(*hc));
+ memset((void *) new, 0, sizeof(*new));
+ new->spec = cpystr(kw->kw);
+ new->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
+ new->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
+
+ if(hcolors){
+ for(hc = hcolors; hc->next; hc = hc->next)
+ ;
+
+ hc->next = new;
+ }
+ else
+ hcolors = new;
+
+ hc = new;
+ }
+
+ if(hc){
+ if((*cl)->flags & CF_VAR2){
+ old_val = hc->bg;
+ if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
+ hc->bg = cpystr(colorx(CFC_ICOLOR(*cl)));
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
+ hc->bg = cpystr(MATCH_NORM_COLOR);
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
+ hc->bg = cpystr(MATCH_NONE_COLOR);
+ else if(old_val)
+ hc->bg = cpystr(is_rgb_color(old_val)
+ ? old_val
+ : color_to_asciirgb(old_val));
+ else
+ hc->bg = cpystr(color_to_asciirgb(colorx(COL_WHITE)));
+
+ if(old_val)
+ fs_give((void **) &old_val);
+
+ /*
+ * If the user sets one of foreground/background and the
+ * other is not yet set, set it.
+ */
+ if(!(hc->fg && hc->fg[0])){
+ if(hc->fg)
+ fs_give((void **)&hc->fg);
+
+ hc->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
+ }
+ }
+ else{
+ old_val = hc->fg;
+
+ if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
+ hc->fg = cpystr(colorx(CFC_ICOLOR(*cl)));
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
+ hc->fg = cpystr(MATCH_NORM_COLOR);
+ else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
+ hc->fg = cpystr(MATCH_NONE_COLOR);
+ else if(old_val)
+ hc->fg = cpystr(is_rgb_color(old_val)
+ ? old_val
+ : color_to_asciirgb(old_val));
+ else
+ hc->fg = cpystr(color_to_asciirgb(colorx(COL_BLACK)));
+
+ if(old_val)
+ fs_give((void **) &old_val);
+
+ if(!(hc->bg && hc->bg[0])){
+ if(hc->bg)
+ fs_give((void **)&hc->bg);
+
+ hc->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
+ }
+ }
+ }
+
+ /*
+ * Turn on selected *'s for default selections, if any, and
+ * for ones we forced on.
+ */
+ color_update_selected(ps, *cl,
+ (hc && hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->fg : ps->VAR_NORM_FORE_COLOR,
+ (hc && hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->bg : ps->VAR_NORM_BACK_COLOR,
+ TRUE);
+
+ alval = ALVAL((*cl)->var, ew);
+ free_list_array(alval);
+ *alval = varlist_from_spec_colors(hcolors);
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+
+ fix_side_effects(ps, (*cl)->var, 0);
+ set_current_color_vals(ps);
+ ClearScreen();
+ rv = ps->mangled_screen = 1;
+ break;
+
+ case MC_TOGGLE : /* toggle default on or off */
+ fgv = (*cl)->var; /* foreground color */
+ bgv = (*cl)->var+1; /* background color */
+
+ if((*cl)->value[1] == 'X'){ /* turning default off */
+ (*cl)->value[1] = ' ';
+ /*
+ * Take whatever color is the current_val and suck it
+ * into the user_val. Same colors remain checked.
+ */
+ apval1 = APVAL(fgv, ew);
+ if(apval1){
+ if(*apval1)
+ fs_give((void **)apval1);
+ }
+
+ apval2 = APVAL(bgv, ew);
+ if(apval2){
+ if(*apval2)
+ fs_give((void **)apval2);
+ }
+
+ /* editing normal but there is an exception config */
+ if((ps->ew_for_except_vars != Main) && (ew == Main)){
+ COLOR_PAIR *newc;
+
+ /* use global_val if it is set */
+ if(fgv && fgv->global_val.p && fgv->global_val.p[0] &&
+ bgv && bgv->global_val.p && bgv->global_val.p[0]){
+ *apval1 = cpystr(fgv->global_val.p);
+ *apval2 = cpystr(bgv->global_val.p);
+ }
+ else if(var_defaults_to_rev(fgv) &&
+ (newc = pico_get_rev_color())){
+ *apval1 = cpystr(newc->fg);
+ *apval2 = cpystr(newc->bg);
+ }
+ else{
+ *apval1 = cpystr(ps->VAR_NORM_FORE_COLOR);
+ *apval2 = cpystr(ps->VAR_NORM_BACK_COLOR);
+ }
+ }
+ else{ /* editing outermost config */
+ /* just use current_vals */
+ if(fgv->current_val.p)
+ *apval1 = cpystr(fgv->current_val.p);
+ if(bgv->current_val.p)
+ *apval2 = cpystr(bgv->current_val.p);
+ }
+ }
+ else{ /* turning default on */
+ char *starred_fg = NULL, *starred_bg = NULL;
+
+ (*cl)->value[1] = 'X';
+ apval = APVAL(fgv, ew);
+ if(apval && *apval)
+ fs_give((void **)apval);
+
+ apval = APVAL(bgv, ew);
+ if(apval && *apval)
+ fs_give((void **)apval);
+
+ if(fgv->cmdline_val.p)
+ fs_give((void **)&fgv->cmdline_val.p);
+
+ if(bgv->cmdline_val.p)
+ fs_give((void **)&bgv->cmdline_val.p);
+
+ set_current_color_vals(ps);
+
+ if(fgv == &ps->vars[V_SLCTBL_FORE_COLOR]){
+ F_TURN_OFF(F_SLCTBL_ITEM_NOBOLD, ps);
+ (*cl)->next->value[1] = 'X';
+ }
+
+ /* editing normal but there is an exception config */
+ if((ps->ew_for_except_vars != Main) && (ew == Main)){
+ COLOR_PAIR *newc;
+
+ /* use global_val if it is set */
+ if(fgv && fgv->global_val.p && fgv->global_val.p[0] &&
+ bgv && bgv->global_val.p && bgv->global_val.p[0]){
+ starred_fg = fgv->global_val.p;
+ starred_bg = bgv->global_val.p;
+ }
+ else if(var_defaults_to_rev(fgv) &&
+ (newc = pico_get_rev_color())){
+ starred_fg = newc->fg;
+ starred_bg = newc->bg;
+ }
+ else{
+ starred_fg = ps->VAR_NORM_FORE_COLOR;
+ starred_bg = ps->VAR_NORM_BACK_COLOR;
+ }
+ }
+ else{ /* editing outermost config */
+ starred_fg = fgv->current_val.p;
+ starred_bg = bgv->current_val.p;
+ }
+
+ /*
+ * Turn on selected *'s for default selections.
+ */
+ color_update_selected(ps, prev_confline(*cl),
+ starred_fg, starred_bg, FALSE);
+
+ ps->mangled_body = 1;
+ }
+
+ fix_side_effects(ps, fgv, 0);
+ rv = 1;
+ break;
+
+ case MC_TOGGLEB : /* toggle default on or off, hdr color */
+ /*
+ * Find the SPEC_COLOR_S for header.
+ */
+ rv = 1;
+ lval = LVAL((*cl)->var, ew);
+ hcolors = spec_colors_from_varlist(lval, 0);
+ for(hc = hcolors, i=0; hc; hc = hc->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ if((*cl)->value[1] == 'X'){ /* turning default off */
+ (*cl)->value[1] = ' ';
+ /*
+ * Take whatever color is the default value and suck it
+ * into the hc structure.
+ */
+ if(hc){
+ if(hc->bg)
+ fs_give((void **)&hc->bg);
+ if(hc->fg)
+ fs_give((void **)&hc->fg);
+
+ if(ps->VAR_NORM_FORE_COLOR &&
+ ps->VAR_NORM_FORE_COLOR[0] &&
+ ps->VAR_NORM_BACK_COLOR &&
+ ps->VAR_NORM_BACK_COLOR[0]){
+ hc->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
+ hc->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
+ }
+
+ if(lval && lval[i]){
+ fs_give((void **)&lval[i]);
+ lval[i] = var_from_spec_color(hc);
+ }
+ }
+ }
+ else{ /* turning default on */
+ (*cl)->value[1] = 'X';
+ /* Remove current colors, leaving val */
+ if(hc){
+ if(hc->bg)
+ fs_give((void **)&hc->bg);
+ if(hc->fg)
+ fs_give((void **)&hc->fg);
+
+ if(lval && lval[i]){
+ fs_give((void **)&lval[i]);
+ lval[i] = var_from_spec_color(hc);
+ }
+ }
+
+ set_current_color_vals(ps);
+ ClearScreen();
+ ps->mangled_screen = 1;
+
+ }
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+
+ /*
+ * Turn on selected *'s for default selections.
+ */
+ color_update_selected(ps, prev_confline(*cl),
+ ps->VAR_NORM_FORE_COLOR,
+ ps->VAR_NORM_BACK_COLOR,
+ FALSE);
+
+ break;
+
+ case MC_TOGGLEC : /* toggle default on or off, keyword color */
+ for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ if(!kw){ /* can't happen */
+ dprint((1,
+ "This can't happen, kw not set when togglec keyword color\n"));
+ break;
+ }
+
+ hcolors = spec_colors_from_varlist(LVAL((*cl)->var, ew), 0);
+
+ /*
+ * Look through hcolors, derived from lval, to find this keyword
+ * and its current color.
+ */
+ for(hc = hcolors; hc; hc = hc->next)
+ if(hc->spec && ((kw->nick && !strucmp(kw->nick, hc->spec))
+ || (kw->kw && !strucmp(kw->kw, hc->spec))))
+ break;
+
+ /* Remove this color from list */
+ if(hc){
+ SPEC_COLOR_S *tmp;
+
+ if(hc == hcolors){
+ hcolors = hc->next;
+ hc->next = NULL;
+ free_spec_colors(&hc);
+ }
+ else{
+ for(tmp = hcolors; tmp->next; tmp = tmp->next)
+ if(tmp->next == hc)
+ break;
+
+ if(tmp->next){
+ tmp->next = hc->next;
+ hc->next = NULL;
+ free_spec_colors(&hc);
+ }
+ }
+ }
+
+ if((*cl)->value[1] == 'X')
+ (*cl)->value[1] = ' ';
+ else
+ (*cl)->value[1] = 'X';
+
+ /*
+ * Turn on selected *'s for default selections, if any, and
+ * for ones we forced on.
+ */
+ color_update_selected(ps, prev_confline(*cl),
+ ps->VAR_NORM_FORE_COLOR,
+ ps->VAR_NORM_BACK_COLOR,
+ FALSE);
+
+ alval = ALVAL((*cl)->var, ew);
+ free_list_array(alval);
+ *alval = varlist_from_spec_colors(hcolors);
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+
+ fix_side_effects(ps, (*cl)->var, 0);
+ set_current_color_vals(ps);
+ ClearScreen();
+ rv = ps->mangled_screen = 1;
+ break;
+
+ case MC_TOGGLED : /* toggle selectable item bold on or off */
+ toggle_feature_bit(ps, feature_list_index(F_SLCTBL_ITEM_NOBOLD),
+ &ps->vars[V_FEATURE_LIST], *cl, 1);
+ ps->mangled_body = 1; /* to fix Sample Text */
+ rv = 1;
+ break;
+
+ case MC_DEFAULT : /* restore default values */
+
+ /* First, confirm that user wants to restore all default colors */
+ if(want_to(_("Really restore all colors to default values"),
+ 'y', 'n', NO_HELP, WT_NORM) != 'y'){
+ cmd_cancelled("RestoreDefs");
+ return(rv);
+ }
+
+ /* get rid of all user set colors */
+ for(v = ps->vars; v->name; v++){
+ if(!color_holding_var(ps, v)
+ || v == &ps->vars[V_VIEW_HDR_COLORS]
+ || v == &ps->vars[V_KW_COLORS])
+ continue;
+
+ apval = APVAL(v, ew);
+ if(apval && *apval)
+ fs_give((void **)apval);
+
+ if(v->cmdline_val.p)
+ fs_give((void **)&v->cmdline_val.p);
+ }
+
+ /*
+ * For custom header colors, we want to remove the color values
+ * but leave the spec value so that it is easy to reset.
+ */
+ alval = ALVAL(&ps->vars[V_VIEW_HDR_COLORS], ew);
+ if(alval && *alval){
+ SPEC_COLOR_S *global_hcolors = NULL, *hcg;
+
+ v = &ps->vars[V_VIEW_HDR_COLORS];
+ if(v->global_val.l && v->global_val.l[0])
+ global_hcolors = spec_colors_from_varlist(v->global_val.l, 0);
+
+ hcolors = spec_colors_from_varlist(*alval, 0);
+ for(hc = hcolors; hc; hc = hc->next){
+ if(hc->fg)
+ fs_give((void **)&hc->fg);
+ if(hc->bg)
+ fs_give((void **)&hc->bg);
+
+ for(hcg = global_hcolors; hcg; hcg = hcg->next){
+ if(hc->spec && hcg->spec && !strucmp(hc->spec, hcg->spec)){
+ hc->fg = hcg->fg;
+ hcg->fg = NULL;
+ hc->bg = hcg->bg;
+ hcg->bg = NULL;
+ if(hc->val && !hcg->val)
+ fs_give((void **) &hc->val);
+ }
+ }
+
+ if(global_hcolors)
+ free_spec_colors(&global_hcolors);
+ }
+
+ free_list_array(alval);
+ *alval = varlist_from_spec_colors(hcolors);
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+ }
+
+ /*
+ * Same for keyword colors.
+ */
+ alval = ALVAL(&ps->vars[V_KW_COLORS], ew);
+ if(alval && *alval){
+ hcolors = spec_colors_from_varlist(*alval, 0);
+ for(hc = hcolors; hc; hc = hc->next){
+ if(hc->fg)
+ fs_give((void **)&hc->fg);
+ if(hc->bg)
+ fs_give((void **)&hc->bg);
+ }
+
+ free_list_array(alval);
+ *alval = varlist_from_spec_colors(hcolors);
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+ }
+
+ /* set bold for selectable items */
+ F_TURN_OFF(F_SLCTBL_ITEM_NOBOLD, ps);
+ lval = LVAL(&ps->vars[V_FEATURE_LIST], ew);
+ if(test_feature(lval, feature_list_name(F_SLCTBL_ITEM_NOBOLD), 0))
+ toggle_feature_bit(ps, feature_list_index(F_SLCTBL_ITEM_NOBOLD),
+ &ps->vars[V_FEATURE_LIST], *cl, 1);
+
+ set_current_color_vals(ps);
+ clear_index_cache(ps->mail_stream, 0);
+
+ /* redo config display */
+ *cl = first_confline(*cl);
+ free_conflines(cl);
+ opt_screen->top_line = NULL;
+ first_line = NULL;
+ color_config_init_display(ps, cl, &first_line);
+ *cl = first_line;
+ ClearScreen();
+ ps->mangled_screen = 1;
+ rv = 1;
+ break;
+
+ case MC_ADD : /* add custom header color */
+ /* get header field name */
+ help = NO_HELP;
+ while(1){
+ i = optionally_enter(sval, -FOOTER_ROWS(ps), 0, sizeof(sval),
+ _("Enter the name of the header field to be added: "),
+ NULL, help, NULL);
+ if(i == 0)
+ break;
+ else if(i == 1){
+ cmd_cancelled("Add");
+ cancel = 1;
+ break;
+ }
+ else if(i == 3){
+ help = help == NO_HELP ? h_config_add_custom_color : NO_HELP;
+ continue;
+ }
+ else
+ break;
+ }
+
+ ps->mangled_footer = 1;
+
+ removing_leading_and_trailing_white_space(sval);
+ if(sval[strlen(sval)-1] == ':') /* remove trailing colon */
+ sval[strlen(sval)-1] = '\0';
+
+ removing_trailing_white_space(sval);
+
+ if(cancel || !sval[0])
+ break;
+
+ new_hcolor = (SPEC_COLOR_S *)fs_get(sizeof(*new_hcolor));
+ memset((void *)new_hcolor, 0, sizeof(*new_hcolor));
+ new_hcolor->spec = cpystr(sval);
+ confline = var_from_spec_color(new_hcolor);
+
+ /* add it to end of list */
+ alval = ALVAL(&ps->vars[V_VIEW_HDR_COLORS], ew);
+ if(alval){
+ /* get rid of possible empty value first */
+ if((t = *alval) && t[0] && !t[0][0] && !(t+1)[0])
+ free_list_array(alval);
+
+ for(t = *alval, i=0; t && t[0]; t++)
+ i++;
+
+ if(i)
+ fs_resize((void **)alval, sizeof(char *) * (i+1+1));
+ else
+ *alval = (char **)fs_get(sizeof(char *) * (i+1+1));
+
+ (*alval)[i] = confline;
+ (*alval)[i+1] = NULL;
+ }
+
+ set_current_color_vals(ps);
+
+ /* go to end of display */
+ for(ctmp = *cl; ctmp && ctmp->next; ctmp = next_confline(ctmp))
+ ;
+
+ /* back up to the KEYWORD COLORS title line */
+ for(; ctmp && (!ctmp->value || strcmp(ctmp->value, KW_COLORS_HDR))
+ && ctmp->prev;
+ ctmp = prev_confline(ctmp))
+ ;
+
+ /*
+ * Back up to last header line, or comment line if no header lines.
+ * One of many in a long line of dangerous moves in the config
+ * screens.
+ */
+ ctmp = prev_confline(ctmp); /* ------- line */
+ ctmp = prev_confline(ctmp); /* blank line */
+ ctmp = prev_confline(ctmp); /* the line */
+
+ *cl = ctmp;
+
+ /* delete the comment line if there were no headers before this */
+ if(i == 0){
+ beg = ctmp->prev;
+ end = ctmp;
+
+ *cl = beg ? beg->prev : NULL;
+
+ if(beg && beg->prev) /* this will always be true */
+ beg->prev->next = end ? end->next : NULL;
+
+ if(end && end->next)
+ end->next->prev = beg ? beg->prev : NULL;
+
+ if(end)
+ end->next = NULL;
+
+ if(beg == opt_screen->top_line || end == opt_screen->top_line)
+ opt_screen->top_line = NULL;
+
+ free_conflines(&beg);
+ }
+
+ add_header_color_line(ps, cl, confline, i);
+
+ /* be sure current is on selectable line */
+ for(; *cl && ((*cl)->flags & CF_NOSELECT); *cl = next_confline(*cl))
+ ;
+ for(; *cl && ((*cl)->flags & CF_NOSELECT); *cl = prev_confline(*cl))
+ ;
+
+ rv = ps->mangled_body = 1;
+ break;
+
+ case MC_DELETE : /* delete custom header color */
+ if((*cl)->var != &ps->vars[V_VIEW_HDR_COLORS]){
+ q_status_message(SM_ORDER, 0, 2,
+ _("Can't delete this color setting"));
+ break;
+ }
+
+ if(want_to(_("Really delete header color from config"),
+ 'y', 'n', NO_HELP, WT_NORM) != 'y'){
+ cmd_cancelled("Delete");
+ return(rv);
+ }
+
+ alval = ALVAL((*cl)->var, ew);
+ if(alval){
+ int n, j;
+
+ for(t = *alval, n=0; t && t[0]; t++)
+ n++;
+
+ j = CFC_ICUST(*cl);
+
+ if(n > j){ /* it better be */
+ if((*alval)[j])
+ fs_give((void **)&(*alval)[j]);
+
+ for(i = j; i < n; i++)
+ (*alval)[i] = (*alval)[i+1];
+ }
+ }
+
+ set_current_color_vals(ps);
+
+ /*
+ * Note the conf lines that go with this header. That's the
+ * blank line before and the current line.
+ */
+ beg = (*cl)->prev;
+ end = *cl;
+
+ another = 0;
+ /* reset current line */
+ if(end && end->next && end->next->next &&
+ end->next->next->var == &ps->vars[V_VIEW_HDR_COLORS]){
+ *cl = end->next->next; /* next Header Color */
+ another++;
+ }
+ else if(beg && beg->prev &&
+ beg->prev->var == &ps->vars[V_VIEW_HDR_COLORS]){
+ *cl = beg->prev; /* prev Header Color */
+ another++;
+ }
+
+ /* adjust SPEC_COLOR_S index (varmem) values */
+ for(ctmp = end; ctmp; ctmp = next_confline(ctmp))
+ if(ctmp->var == &ps->vars[V_VIEW_HDR_COLORS])
+ ctmp->varmem = CFC_ICUST_DEC(ctmp);
+
+ /*
+ * If that was the last header color line, add in the comment
+ * line placeholder. If there is another, just delete the
+ * old conf lines.
+ */
+ if(another){
+ if(beg && beg->prev) /* this will always be true */
+ beg->prev->next = end ? end->next : NULL;
+
+ if(end && end->next)
+ end->next->prev = beg ? beg->prev : NULL;
+
+ if(end)
+ end->next = NULL;
+
+ if(beg == opt_screen->top_line || end == opt_screen->top_line)
+ opt_screen->top_line = NULL;
+
+ free_conflines(&beg);
+ }
+ else if(end){
+ if(end->varname)
+ fs_give((void **) &end->varname);
+
+ if(end->value)
+ fs_give((void **) &end->value);
+
+ end->flags = CF_NOSELECT;
+ end->help = NO_HELP;
+ end->value = cpystr(_(ADDHEADER_COMMENT));
+ end->valoffset = COLOR_INDENT;
+ end->varnamep = NULL;
+ end->varmem = 0;
+ end->keymenu = NULL;
+ end->tool = NULL;
+ }
+
+ /* if not selectable, find next selectable line */
+ for(; *cl && ((*cl)->flags & CF_NOSELECT) && next_confline(*cl); *cl = next_confline(*cl))
+ ;
+ /* if no next selectable line, search backwards for one */
+ for(; *cl && ((*cl)->flags & CF_NOSELECT) && prev_confline(*cl); *cl = prev_confline(*cl))
+ ;
+
+ rv = ps->mangled_body = 1;
+ q_status_message(SM_ORDER, 0, 3, _("header color deleted"));
+ break;
+
+ case MC_SHUFFLE : /* shuffle order of custom headers */
+ if((*cl)->var != &ps->vars[V_VIEW_HDR_COLORS]){
+ q_status_message(SM_ORDER, 0, 2,
+ _("Can't shuffle this color setting"));
+ break;
+ }
+
+ alval = ALVAL((*cl)->var, ew);
+ if(!alval)
+ return(rv);
+
+ curcolor = CFC_ICUST(*cl);
+ prevcolor = curcolor-1;
+ nextcolor = curcolor+1;
+ if(!*alval || !(*alval)[nextcolor])
+ nextcolor = -1;
+
+ if((prevcolor < 0 && nextcolor < 0) || !*alval){
+ q_status_message(SM_ORDER, 0, 3,
+ _("Shuffle only makes sense when there is more than one Header Color defined"));
+ return(rv);
+ }
+
+ /* Move it up or down? */
+ i = 0;
+ opts[i].ch = 'u';
+ opts[i].rval = 'u';
+ opts[i].name = "U";
+ opts[i++].label = _("Up");
+
+ opts[i].ch = 'd';
+ opts[i].rval = 'd';
+ opts[i].name = "D";
+ opts[i++].label = _("Down");
+
+ opts[i].ch = -1;
+ deefault = 'u';
+
+ if(prevcolor < 0){ /* no up */
+ opts[0].ch = -2;
+ deefault = 'd';
+ }
+ else if(nextcolor < 0)
+ opts[1].ch = -2; /* no down */
+
+ snprintf(prompt, sizeof(prompt), _("Shuffle %s%s%s ? "),
+ (opts[0].ch != -2) ? _("UP") : "",
+ (opts[0].ch != -2 && opts[1].ch != -2) ? " or " : "",
+ (opts[1].ch != -2) ? _("DOWN") : "");
+ prompt[sizeof(prompt)-1] = '\0';
+ help = (opts[0].ch == -2) ? h_hdrcolor_shuf_down
+ : (opts[1].ch == -2) ? h_hdrcolor_shuf_up
+ : h_hdrcolor_shuf;
+
+ i = radio_buttons(prompt, -FOOTER_ROWS(ps), opts, deefault, 'x',
+ help, RB_NORM);
+
+ switch(i){
+ case 'x':
+ cmd_cancelled("Shuffle");
+ return(rv);
+
+ case 'u':
+ case 'd':
+ break;
+ }
+
+ /* swap order */
+ if(i == 'd'){
+ old_val = (*alval)[curcolor];
+ (*alval)[curcolor] = (*alval)[nextcolor];
+ (*alval)[nextcolor] = old_val;
+ }
+ else if(i == 'u'){
+ old_val = (*alval)[curcolor];
+ (*alval)[curcolor] = (*alval)[prevcolor];
+ (*alval)[prevcolor] = old_val;
+ }
+ else /* can't happen */
+ return(rv);
+
+ set_current_color_vals(ps);
+
+ /*
+ * Swap the conf lines.
+ */
+
+ cur_beg = (*cl)->prev;
+ cur_end = *cl;
+
+ if(i == 'd'){
+ next_beg = cur_end->next;
+ next_end = next_beg ? next_beg->next : NULL;
+
+ if(next_end->next)
+ next_end->next->prev = cur_end;
+ cur_end->next = next_end->next;
+ next_end->next = cur_beg;
+ if(cur_beg->prev)
+ cur_beg->prev->next = next_beg;
+ next_beg->prev = cur_beg->prev;
+ cur_beg->prev = next_end;
+
+ /* adjust SPEC_COLOR_S index values */
+ cur_beg->varmem = CFC_ICUST_INC(cur_beg);
+ cur_beg->next->varmem = CFC_ICUST_INC(cur_beg->next);
+
+ next_beg->varmem = CFC_ICUST_DEC(next_beg);
+ next_beg->next->varmem = CFC_ICUST_DEC(next_beg->next);
+
+ if(opt_screen->top_line == cur_end)
+ opt_screen->top_line = next_end;
+ else if(opt_screen->top_line == cur_beg)
+ opt_screen->top_line = next_beg;
+ }
+ else{
+ prev_end = cur_beg->prev;
+ prev_beg = prev_end ? prev_end->prev : NULL;
+
+ if(prev_beg && prev_beg->prev)
+ prev_beg->prev->next = cur_beg;
+ cur_beg->prev = prev_beg->prev;
+ prev_beg->prev = cur_end;
+ if(cur_end->next)
+ cur_end->next->prev = prev_end;
+ prev_end->next = cur_end->next;
+ cur_end->next = prev_beg;
+
+ /* adjust SPEC_COLOR_S index values */
+ cur_beg->varmem = CFC_ICUST_DEC(cur_beg);
+ cur_beg->next->varmem = CFC_ICUST_DEC(cur_beg->next);
+
+ prev_beg->varmem = CFC_ICUST_INC(prev_beg);
+ prev_beg->next->varmem = CFC_ICUST_INC(prev_beg->next);
+
+ if(opt_screen->top_line == prev_end)
+ opt_screen->top_line = cur_end;
+ else if(opt_screen->top_line == prev_beg)
+ opt_screen->top_line = cur_beg;
+ }
+
+ rv = ps->mangled_body = 1;
+ q_status_message(SM_ORDER, 0, 3, _("Header Colors shuffled"));
+ break;
+
+ case MC_EDIT:
+ rv = color_edit_screen(ps, cl);
+ if((*cl)->value && (*cl)->var &&
+ srchstr((*cl)->var->name, "-foreground-color")){
+ fs_give((void **)&(*cl)->value);
+ (*cl)->value = pretty_value(ps, *cl);
+ }
+
+ break;
+
+ case MC_EXIT: /* exit */
+ if((*cl)->keymenu == &color_changing_keymenu ||
+ (*cl)->keymenu == &kw_color_changing_keymenu ||
+ (*cl)->keymenu == &custom_color_changing_keymenu ||
+ ((*cl)->prev &&
+ ((*cl)->prev->keymenu == &color_changing_keymenu ||
+ (*cl)->prev->keymenu == &kw_color_changing_keymenu ||
+ (*cl)->prev->keymenu == &custom_color_changing_keymenu)) ||
+ ((*cl)->prev->prev &&
+ ((*cl)->prev->prev->keymenu == &color_changing_keymenu ||
+ (*cl)->prev->prev->keymenu == &kw_color_changing_keymenu ||
+ (*cl)->prev->prev->keymenu == &custom_color_changing_keymenu)))
+ rv = simple_exit_cmd(flags);
+ else
+ rv = config_exit_cmd(flags);
+
+ break;
+
+#ifdef _WINDOWS
+ case MC_RGB1 :
+ fgv = (*cl)->var;
+ bgv = (*cl)->var+1;
+ v = (*cl)->var;
+ if((*cl)->flags & CF_VAR2)
+ v += 1;
+
+ pval = PVAL(v, ew);
+ apval = APVAL(v, ew);
+ if(old_val = mswin_rgbchoice(pval ? pval : v->current_val.p)){
+ if(*apval)
+ fs_give((void **)apval);
+
+ *apval = old_val;
+ set_current_val(v, TRUE, FALSE);
+ fix_side_effects(ps, v, 0);
+ set_current_color_vals(ps);
+ color_update_selected(ps, *cl, PVAL(fgv, ew), PVAL(bgv, ew), TRUE);
+ rv = ps->mangled_screen = 1;
+ }
+
+ break;
+
+ case MC_RGB2 :
+ /*
+ * Find the SPEC_COLOR_S for header.
+ */
+ alval = ALVAL((*cl)->var, ew);
+ hcolors = spec_colors_from_varlist(*alval, 0);
+
+ for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
+ if(CFC_ICUST(*cl) == i){
+ char **pc = ((*cl)->flags & CF_VAR2) ? &hc->bg : &hc->fg;
+
+ if(old_val = mswin_rgbchoice(*pc)){
+ fs_give((void **) pc);
+ *pc = old_val;
+ color_update_selected(ps, *cl,
+ (hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->fg : ps->VAR_NORM_FORE_COLOR,
+ (hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->bg : ps->VAR_NORM_BACK_COLOR,
+ TRUE);
+
+ if(hc && *alval && (*alval)[i]){
+ fs_give((void **)&(*alval)[i]);
+ (*alval)[i] = var_from_spec_color(hc);
+ }
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+
+ set_current_color_vals(ps);
+ ClearScreen();
+ rv = ps->mangled_screen = 1;
+ }
+
+ break;
+ }
+
+ break;
+
+ case MC_RGB3 :
+ /*
+ * Custom colored keywords.
+ */
+ for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ if(!kw){ /* can't happen */
+ dprint((1,
+ "This can't happen, kw not set in MC_RGB3\n"));
+ break;
+ }
+
+ hcolors = spec_colors_from_varlist(LVAL((*cl)->var, ew), 0);
+
+ /*
+ * Look through hcolors, derived from lval, to find this keyword
+ * and its current color.
+ */
+ for(hc = hcolors; hc; hc = hc->next)
+ if(hc->spec && ((kw->nick && !strucmp(kw->nick, hc->spec))
+ || (kw->kw && !strucmp(kw->kw, hc->spec))))
+ break;
+
+ if(!hc){ /* this keyword didn't have a color set, add to list */
+ SPEC_COLOR_S *new;
+
+ new = (SPEC_COLOR_S *) fs_get(sizeof(*hc));
+ memset((void *) new, 0, sizeof(*new));
+ new->spec = cpystr(kw->kw);
+ new->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
+ new->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
+
+ if(hcolors){
+ for(hc = hcolors; hc->next; hc = hc->next)
+ ;
+
+ hc->next = new;
+ }
+ else
+ hcolors = new;
+
+ hc = new;
+ }
+
+ if(hc){
+ char **pc = ((*cl)->flags & CF_VAR2) ? &hc->bg : &hc->fg;
+
+ if(old_val = mswin_rgbchoice(*pc)){
+ fs_give((void **) pc);
+ *pc = old_val;
+
+ /*
+ * Turn on selected *'s for default selections, if any, and
+ * for ones we forced on.
+ */
+ color_update_selected(ps, *cl,
+ (hc && hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->fg : ps->VAR_NORM_FORE_COLOR,
+ (hc && hc->fg && hc->fg[0]
+ && hc->bg && hc->bg[0])
+ ? hc->bg : ps->VAR_NORM_BACK_COLOR,
+ TRUE);
+
+ alval = ALVAL((*cl)->var, ew);
+ free_list_array(alval);
+ *alval = varlist_from_spec_colors(hcolors);
+ fix_side_effects(ps, (*cl)->var, 0);
+ set_current_color_vals(ps);
+ ClearScreen();
+ rv = 1;
+ }
+ }
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+
+ ps->mangled_screen = 1;
+ break;
+#endif
+
+ default :
+ rv = -1;
+ break;
+ }
+
+
+ if(rv == 1)
+ exception_override_warning((*cl)->var);
+
+ return(rv);
+}
+
+
+/*
+ * Turn on selected *'s for default selections, if any, and
+ * for ones we forced on.
+ * Adjust the Sample line right above the color selection lines.
+ */
+void
+color_update_selected(struct pine *ps, CONF_S *cl, char *fg, char *bg, int cleardef)
+{
+ int i, fg_is_custom = 1, bg_is_custom = 1;
+#ifdef _WINDOWS
+ CONF_S *cl_custom = NULL;
+#endif
+
+ /* back up to header line */
+ for(; cl && (cl->flags & CF_DOUBLEVAR); cl = prev_confline(cl))
+ ;
+
+ /* adjust sample line */
+ if(cl && cl->var && cl->flags & CF_COLORSAMPLE){
+ if(cl->value)
+ fs_give((void **)&cl->value);
+
+ cl->value = color_setting_text_line(ps, cl->var);
+ }
+
+ for(i = 0, cl = next_confline(cl);
+ i < pico_count_in_color_table() && cl;
+ i++, cl = next_confline(cl)){
+ if(fg && !strucmp(color_to_canonical_name(fg), colorx(i))){
+ cl->value[1] = R_SELD;
+ fg_is_custom = 0;
+ }
+ else
+ cl->value[1] = ' ';
+
+ if(bg && !strucmp(color_to_canonical_name(bg), colorx(i))){
+ cl->value[cl->val2offset - cl->valoffset + 1] = R_SELD;
+ bg_is_custom = 0;
+ }
+ else
+ cl->value[cl->val2offset - cl->valoffset + 1] = ' ';
+ }
+
+#ifdef _WINDOWS
+ cl_custom = cl;
+ cl = next_confline(cl);
+#endif
+
+ if(cl && cl->var && offer_normal_color_for_var(ps, cl->var)){
+ if(fg && !struncmp(color_to_canonical_name(fg), MATCH_NORM_COLOR, RGBLEN)){
+ cl->value[1] = R_SELD;
+ fg_is_custom = 0;
+ }
+ else
+ cl->value[1] = ' ';
+
+ if(bg && !struncmp(color_to_canonical_name(bg), MATCH_NORM_COLOR, RGBLEN)){
+ cl->value[cl->val2offset - cl->valoffset + 1] = R_SELD;
+ bg_is_custom = 0;
+ }
+ else
+ cl->value[cl->val2offset - cl->valoffset + 1] = ' ';
+
+ cl = next_confline(cl);
+ }
+
+ if(cl && cl->var && offer_none_color_for_var(ps, cl->var)){
+ if(fg && !struncmp(color_to_canonical_name(fg), MATCH_NONE_COLOR, RGBLEN)){
+ cl->value[1] = R_SELD;
+ fg_is_custom = 0;
+ }
+ else
+ cl->value[1] = ' ';
+
+ if(bg && !struncmp(color_to_canonical_name(bg), MATCH_NONE_COLOR, RGBLEN)){
+ cl->value[cl->val2offset - cl->valoffset + 1] = R_SELD;
+ bg_is_custom = 0;
+ }
+ else
+ cl->value[cl->val2offset - cl->valoffset + 1] = ' ';
+
+ cl = next_confline(cl);
+ }
+
+ /* Turn off Default X */
+ if(cleardef)
+ cl->value[1] = ' ';
+
+#ifdef _WINDOWS
+ /* check for a custom setting */
+ if(cl_custom){
+ cl_custom->value[1] = fg_is_custom ? R_SELD : ' ';
+ cl_custom->value[cl_custom->val2offset - cl_custom->valoffset + 1]
+ = bg_is_custom ? R_SELD : ' ';
+ }
+#endif
+}
+
+
+int
+color_edit_screen(struct pine *ps, CONF_S **cl)
+{
+ OPT_SCREEN_S screen, *saved_screen;
+ CONF_S *ctmp = NULL, *first_line = NULL, *ctmpb;
+ int rv, is_index = 0, is_hdrcolor = 0, indent = 12;
+ int is_general = 0, is_keywordcol = 0;
+ char tmp[1200+1], name[1200], *p;
+ struct variable *vtmp, v;
+ int i, def;
+ COLOR_PAIR *color = NULL;
+ SPEC_COLOR_S *hc = NULL, *hcolors = NULL;
+ KEYWORD_S *kw;
+
+ vtmp = (*cl)->var;
+ if(vtmp == &ps->vars[V_VIEW_HDR_COLORS])
+ is_hdrcolor++;
+ else if(vtmp == &ps->vars[V_KW_COLORS])
+ is_keywordcol++;
+ else if(color_holding_var(ps, vtmp)){
+ if(!struncmp(vtmp->name, "index-", 6))
+ is_index++;
+ else
+ is_general++;
+ }
+
+ new_confline(&ctmp);
+ /* Blank line */
+ ctmp->flags |= CF_NOSELECT | CF_B_LINE;
+
+ first_line = ctmp;
+
+ new_confline(&ctmp)->var = vtmp;
+
+ name[0] = '\0';
+ if(is_general){
+ p = srchstr(vtmp->name, "-foreground-color");
+ snprintf(name, sizeof(name), "%.*s", p ? MIN(p - vtmp->name, 30) : 30, vtmp->name);
+ name[sizeof(name)-1] = '\0';
+ if(islower((unsigned char)name[0]))
+ name[0] = toupper((unsigned char)name[0]);
+ }
+ else if(is_index){
+ p = srchstr(vtmp->name, "-foreground-color");
+ snprintf(name, sizeof(name), "%.*s Symbol",
+ p ? MIN(p - vtmp->name, 30) : 30, vtmp->name);
+ name[sizeof(name)-1] = '\0';
+ if(islower((unsigned char)name[0]))
+ name[0] = toupper((unsigned char)name[0]);
+ }
+ else if(is_hdrcolor){
+ char **lval;
+
+ lval = LVAL(vtmp, ew);
+ hcolors = spec_colors_from_varlist(lval, 0);
+
+ for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ if(hc){
+ snprintf(name, sizeof(name), "%s%s", HEADER_WORD, hc->spec);
+ name[sizeof(name)-1] = '\0';
+ i = sizeof(HEADER_WORD) - 1;
+ if(islower((unsigned char) name[i]))
+ name[i] = toupper((unsigned char) name[i]);
+ }
+ }
+ else if(is_keywordcol){
+ char **lval;
+
+ for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
+ if(CFC_ICUST(*cl) == i)
+ break;
+
+ if(kw){
+ char *nm, *comment = NULL;
+
+ nm = kw->nick ? kw->nick : kw->kw ? kw->kw : "";
+ if(utf8_width(nm) > 60)
+ nm = short_str(nm, tmp_20k_buf, SIZEOF_20KBUF, 60, EndDots);
+
+ if(kw->nick && kw->kw && kw->kw[0])
+ comment = kw->kw;
+
+ if(utf8_width(nm) + (comment ? utf8_width(comment) : 0) < 60)
+ utf8_snprintf(name, sizeof(name), "%.50w%s%.50w%s",
+ nm,
+ comment ? " (" : "",
+ comment ? comment : "",
+ comment ? ")" : "");
+ else
+ snprintf(name, sizeof(name), "%s", nm);
+
+ name[sizeof(name)-1] = '\0';
+
+ lval = LVAL(vtmp, ew);
+ hcolors = spec_colors_from_varlist(lval, 0);
+ if(kw && hcolors)
+ if(!(kw->nick && kw->nick[0]
+ && (color=hdr_color(kw->nick, NULL, hcolors))))
+ if(kw->kw && kw->kw[0])
+ color = hdr_color(kw->kw, NULL, hcolors);
+ }
+ }
+
+ snprintf(tmp, sizeof(tmp), "%s Color =", name[0] ? name : "?");
+ tmp[sizeof(tmp)-1] = '\0';
+ ctmp->varname = cpystr(tmp);
+ ctmp->varnamep = ctmpb = ctmp;
+ ctmp->flags |= (CF_STARTITEM | CF_NOSELECT);
+ ctmp->keymenu = &color_changing_keymenu;
+
+ if(is_hdrcolor){
+ char **apval;
+
+ def = !(hc && hc->fg && hc->fg[0] && hc->bg && hc->bg[0]);
+
+ add_color_setting_disp(ps, &ctmp, vtmp, ctmpb,
+ &custom_color_changing_keymenu,
+ &hdr_color_checkbox_keymenu,
+ config_help(vtmp - ps->vars, 0),
+ indent, CFC_ICUST(*cl),
+ def ? ps_global->VAR_NORM_FORE_COLOR
+ : hc->fg,
+ def ? ps_global->VAR_NORM_BACK_COLOR
+ : hc->bg,
+ def);
+
+ /* optional string to match in header value */
+ new_confline(&ctmp);
+ ctmp->varnamep = ctmpb;
+ ctmp->keymenu = &color_pattern_keymenu;
+ ctmp->help = h_config_customhdr_pattern;
+ ctmp->tool = color_text_tool;
+ ctmp->varoffset = indent-5;
+ ctmp->varname = cpystr(_("Pattern to match ="));
+ ctmp->valoffset = indent-5 + strlen(ctmp->varname) + 1;
+ ctmp->varmem = (*cl)->varmem;
+
+ /*
+ * This is really ugly. This is just to get the value correct.
+ */
+ memset(&v, 0, sizeof(v));
+ v.is_used = 1;
+ v.is_user = 1;
+ apval = APVAL(&v, ew);
+ if(hc && hc->val && apval)
+ *apval = pattern_to_string(hc->val);
+
+ set_current_val(&v, FALSE, FALSE);
+ ctmp->var = &v;
+ ctmp->value = pretty_value(ps, ctmp);
+ ctmp->var = vtmp;
+ if(apval && *apval)
+ fs_give((void **)apval);
+
+ if(v.current_val.p)
+ fs_give((void **)&v.current_val.p);
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+ }
+ else if(is_keywordcol){
+
+ def = !(color && color->fg && color->fg[0]
+ && color->bg && color->bg[0]);
+
+ add_color_setting_disp(ps, &ctmp, vtmp, ctmpb,
+ &kw_color_changing_keymenu,
+ &kw_color_checkbox_keymenu,
+ config_help(vtmp - ps->vars, 0),
+ indent, CFC_ICUST(*cl),
+ def ? ps_global->VAR_NORM_FORE_COLOR
+ : color->fg,
+ def ? ps_global->VAR_NORM_BACK_COLOR
+ : color->bg,
+ def);
+
+ if(hcolors)
+ free_spec_colors(&hcolors);
+ }
+ else{
+ char *pvalfg, *pvalbg;
+ int def;
+ COLOR_PAIR *newc;
+
+ pvalfg = PVAL(vtmp, ew);
+ pvalbg = PVAL(vtmp+1, ew);
+ def = !(pvalfg && pvalfg[0] && pvalbg && pvalbg[0]);
+ if(def){
+ /* display default val, if there is one */
+ pvalfg = PVAL(vtmp, Main);
+ pvalbg = PVAL(vtmp+1, Main);
+ if(ew == Post && pvalfg && pvalfg[0] && pvalbg && pvalbg[0]){
+ ;
+ }
+ else if(vtmp && vtmp->global_val.p && vtmp->global_val.p[0] &&
+ (vtmp+1)->global_val.p && (vtmp+1)->global_val.p[0]){
+ pvalfg = vtmp->global_val.p;
+ pvalbg = (vtmp+1)->global_val.p;
+ }
+ else{
+ if(var_defaults_to_rev(vtmp) && (newc = pico_get_rev_color())){
+ pvalfg = newc->fg;
+ pvalbg = newc->bg;
+ }
+ else{
+ pvalfg = NULL;
+ pvalbg = NULL;
+ }
+ }
+ }
+
+ add_color_setting_disp(ps, &ctmp, vtmp, ctmpb,
+ &color_changing_keymenu,
+ &config_checkbox_keymenu,
+ config_help(vtmp - ps->vars, 0),
+ indent, 0, pvalfg, pvalbg, def);
+ }
+
+ first_line = first_sel_confline(first_line);
+
+ saved_screen = opt_screen;
+ memset(&screen, 0, sizeof(screen));
+ screen.ro_warning = saved_screen ? saved_screen->deferred_ro_warning : 0;
+ rv = conf_scroll_screen(ps, &screen, first_line,
+ ew == Post ? _("SETUP COLOR EXCEPTIONS")
+ : _("SETUP COLOR"),
+ _("configuration"), 1);
+
+ opt_screen = saved_screen;
+ ps->mangled_screen = 1;
+ return(rv);
+}