Home | History | Annotate | Download | only in ldlinux
      1 /* ----------------------------------------------------------------------- *
      2  *
      3  *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
      8  *   Boston MA 02110-1301, USA; either version 2 of the License, or
      9  *   (at your option) any later version; incorporated herein by reference.
     10  *
     11  * ----------------------------------------------------------------------- */
     12 
     13 #include <stdlib.h>
     14 #include <string.h>
     15 #include <stdio.h>
     16 #include <colortbl.h>
     17 #include "menu.h"
     18 
     19 /*
     20  * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows
     21  *
     22  * 00 - screen		Rest of the screen
     23  * 01 - border		Border area
     24  * 02 - title		Title bar
     25  * 03 - unsel		Unselected menu item
     26  * 04 - hotkey		Unselected hotkey
     27  * 05 - sel		Selection bar
     28  * 06 - hotsel		Selected hotkey
     29  * 07 - scrollbar	Scroll bar
     30  * 08 - tabmsg		Press [Tab] message
     31  * 09 - cmdmark		Command line marker
     32  * 10 - cmdline		Command line
     33  * 11 - pwdborder	Password box border
     34  * 12 - pwdheader	Password box header
     35  * 13 - pwdentry	Password box contents
     36  * 14 - timeout_msg	Timeout message
     37  * 15 - timeout		Timeout counter
     38  * 16 - help		Current entry help text
     39  * 17 - disabled        Disabled menu item
     40  */
     41 
     42 static const struct color_table default_colors[] = {
     43     {"screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
     44     {"border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
     45     {"title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL},
     46     {"unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL},
     47     {"hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL},
     48     {"sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL},
     49     {"hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL},
     50     {"scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
     51     {"tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL},
     52     {"cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL},
     53     {"cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
     54     {"pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
     55     {"pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL},
     56     {"pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
     57     {"timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
     58     {"timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
     59     {"help", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
     60     {"disabled", "1;30;44", 0x60cccccc, 0x00000000, SHADOW_NORMAL},
     61 };
     62 
     63 #define NCOLORS (sizeof default_colors/sizeof default_colors[0])
     64 const int message_base_color = NCOLORS;
     65 const int menu_color_table_size = NCOLORS + 256;
     66 
     67 /* Algorithmically generate the msgXX colors */
     68 void set_msg_colors_global(struct color_table *tbl,
     69 			   unsigned int fg, unsigned int bg,
     70 			   enum color_table_shadow shadow)
     71 {
     72     struct color_table *cp = tbl + message_base_color;
     73     unsigned int i;
     74     unsigned int fga, bga;
     75     unsigned int fgh, bgh;
     76     unsigned int fg_idx, bg_idx;
     77     unsigned int fg_rgb, bg_rgb;
     78 
     79     static const unsigned int pc2rgb[8] =
     80 	{ 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00,
     81 	0xffffff
     82     };
     83 
     84     /* Converting PC RGBI to sensible RGBA values is an "interesting"
     85        proposition.  This algorithm may need plenty of tweaking. */
     86 
     87     fga = fg & 0xff000000;
     88     fgh = ((fg >> 1) & 0xff000000) | 0x80000000;
     89 
     90     bga = bg & 0xff000000;
     91     bgh = ((bg >> 1) & 0xff000000) | 0x80000000;
     92 
     93     for (i = 0; i < 256; i++) {
     94 	fg_idx = i & 15;
     95 	bg_idx = i >> 4;
     96 
     97 	fg_rgb = pc2rgb[fg_idx & 7] & fg;
     98 	bg_rgb = pc2rgb[bg_idx & 7] & bg;
     99 
    100 	if (fg_idx & 8) {
    101 	    /* High intensity foreground */
    102 	    fg_rgb |= fgh;
    103 	} else {
    104 	    fg_rgb |= fga;
    105 	}
    106 
    107 	if (bg_idx == 0) {
    108 	    /* Default black background, assume transparent */
    109 	    bg_rgb = 0;
    110 	} else if (bg_idx & 8) {
    111 	    bg_rgb |= bgh;
    112 	} else {
    113 	    bg_rgb |= bga;
    114 	}
    115 
    116 	cp->argb_fg = fg_rgb;
    117 	cp->argb_bg = bg_rgb;
    118 	cp->shadow = shadow;
    119 	cp++;
    120     }
    121 }
    122 
    123 struct color_table *default_color_table(void)
    124 {
    125     unsigned int i;
    126     const struct color_table *dp;
    127     struct color_table *cp;
    128     struct color_table *color_table;
    129     static const int pc2ansi[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
    130     static char msg_names[6 * 256];
    131     char *mp;
    132 
    133     color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
    134 
    135     dp = default_colors;
    136     cp = color_table;
    137 
    138     for (i = 0; i < NCOLORS; i++) {
    139 	*cp = *dp;
    140 	cp->ansi = refstrdup(dp->ansi);
    141 	cp++;
    142 	dp++;
    143     }
    144 
    145     mp = msg_names;
    146     for (i = 0; i < 256; i++) {
    147 	cp->name = mp;
    148 	mp += sprintf(mp, "msg%02x", i) + 1;
    149 
    150 	rsprintf(&cp->ansi, "%s3%d;4%d", (i & 8) ? "1;" : "",
    151 		 pc2ansi[i & 7], pc2ansi[(i >> 4) & 7]);
    152 	cp++;
    153     }
    154 
    155   /*** XXX: This needs to move to run_menu() ***/
    156     console_color_table = color_table;
    157     console_color_table_size = NCOLORS + 256;
    158 
    159     set_msg_colors_global(color_table, MSG_COLORS_DEF_FG,
    160 			  MSG_COLORS_DEF_BG, MSG_COLORS_DEF_SHADOW);
    161 
    162     return color_table;
    163 }
    164 
    165 struct color_table *copy_color_table(const struct color_table *master)
    166 {
    167     const struct color_table *dp;
    168     struct color_table *color_table, *cp;
    169     unsigned int i;
    170 
    171     color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
    172 
    173     dp = master;
    174     cp = color_table;
    175 
    176     for (i = 0; i < NCOLORS + 256; i++) {
    177 	*cp = *dp;
    178 	cp->ansi = refstr_get(dp->ansi);
    179 	cp++;
    180 	dp++;
    181     }
    182 
    183     return color_table;
    184 }
    185