--- config.h.in +++ config.h.in @@ -395,6 +395,9 @@ /* Define if you want 256-color support */ #undef USE_256_COLORS +/* Define if you want 24-bit color support */ +#undef USE_24_BIT_COLOR + /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE --- configure +++ configure @@ -740,6 +740,7 @@ enable_assert enable_warnings enable_256_color +enable_24_bit_color enable_unicode3 enable_combining enable_xft @@ -1421,6 +1422,7 @@ --enable-assert enable assertions --enable-warnings turn on g++ warnings --enable-256-color enable 256-color support + --enable-24-bit-color enable 24-bit color support --enable-unicode3 use 21 instead of 16 bits to represent unicode characters --enable-combining enable composition of base and combining characters --enable-xft enable xft support on systems that have it @@ -5283,6 +5285,21 @@ fi +support_24_bit_color=no +# Check whether --enable-24-bit-color was given. +if test ${enable_24_bit_color+y} +then : + enableval=$enable_24_bit_color; if test x$enableval = xyes; then + support_24_bit_color=yes + fi +fi + +if test x$support_24_bit_color = xyes; then + +printf "%s\n" "#define USE_24_BIT_COLOR 1" >>confdefs.h + +fi + # Check whether --enable-unicode3 was given. if test ${enable_unicode3+y} then : --- configure.ac +++ configure.ac @@ -203,6 +203,16 @@ AC_DEFINE(USE_256_COLORS, 1, Define if you want 256-color support) fi +support_24_bit_color=no +AC_ARG_ENABLE(24-bit-color, + [ --enable-24-bit-color enable 24-bit color support], + [if test x$enableval = xyes; then + support_24_bit_color=yes + fi]) +if test x$support_24_bit_color = xyes; then + AC_DEFINE(USE_24_BIT_COLOR, 1, Define if you want 24-bit color support) +fi + AC_ARG_ENABLE(unicode3, [ --enable-unicode3 use 21 instead of 16 bits to represent unicode characters], [if test x$enableval = xyes -o x$enableval = xno; then --- README.configure +++ README.configure @@ -9,8 +9,8 @@ --enable-everything Add (or remove) support for all non-multichoice options listed in - "./configure --help", except for "--enable-assert" and - "--enable-256-color". + "./configure --help", except for "--enable-assert", + "--enable-256-color" and "--enable-24-bit-color". You can specify this and then disable options you do not like by *following* this with the appropriate "--disable-..." arguments, or @@ -251,6 +251,20 @@ It also results in higher memory usage and can slow down urxvt dramatically when more than six fonts are in use by a terminal + instance. + + --enable-24-bit-color (default: off) + Enable use of 24-bit colors through + SGR 38 ; 2 ; R ; G ; B m + SGR 48 ; 2 ; R ; G ; B m + + This switch should break termcap/terminfo compatibility to + "TERM=rxvt-unicode-256color", and consequently set "TERM" to + "rxvt-unicode-24bit" by default but there is no termcap/terminfo + for 24-bit color support + + It also results in higher memory usage and can slow down urxvt + dramatically when more than six fonts are in use by a terminal instance. --with-name=NAME (default: urxvt) --- src/command.C +++ src/command.C @@ -1824,11 +1824,11 @@ if (rs[Rs_fade]) { if (!first_time) - pix_colors_focused [idx].free (this); + lookup_color(idx, pix_colors_focused).free (this); rgba c; - pix_colors [Color_fade].get (c); - pix_colors_focused [idx].fade (this, atoi (rs[Rs_fade]), pix_colors_unfocused [idx], c); + lookup_color(Color_fade, pix_colors).get (c); + lookup_color(idx, pix_colors_focused).fade (this, atoi (rs[Rs_fade]), lookup_color(idx, pix_colors_unfocused), c); } #endif } @@ -3418,7 +3418,7 @@ return; rgba c; - pix_colors_focused[color].get (c); + lookup_color(color, pix_colors_focused).get (c); char rgba_str[32]; #if XFT @@ -3906,7 +3906,7 @@ { unsigned int i; short rendset; - int rendstyle; + rend_t rendstyle; if (nargs == 0) { @@ -4012,6 +4012,20 @@ break; case 38: // set fg color, ISO 8613-6 +#if USE_24_BIT_COLOR + if (nargs > i + 2 && arg[i + 1] == 5) + { + scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_fg); + i += 2; + } + else if (nargs > i + 4 && arg[i + 1] == 2) + { + unsigned int r = arg[i + 2], g = arg[i + 3], b = arg[i + 4]; + scr_color_rgb (r, g, b, Color_fg); + i += 4; + } +#endif + break; case 48: // set bg color, ISO 8613-6 { unsigned int fgbg = arg[i] == 38 ? Color_fg : Color_bg; @@ -4024,6 +4038,14 @@ scr_color (idx, fgbg); } +#if USE_24_BIT_COLOR + else if (nargs > i + 4 && arg[i + 1] == 2) + { + unsigned int r = arg[i + 2], g = arg[i + 3], b = arg[i + 4]; + scr_color_rgb (r, g, b, Color_bg); + i += 4; + } +#endif else if (nargs > i + 4 && arg[i + 1] == 2) { unsigned int r = arg[i + 2]; --- src/init.C +++ src/init.C @@ -1110,7 +1110,7 @@ for (i = 0; i < NRS_COLORS; i++) if (const char *name = rs[Rs_color + i]) - set_color (pix_colors [i], name); + set_color (lookup_color(i, pix_colors), name); /* * get scrollBar shadow colors @@ -1119,13 +1119,13 @@ * from the fvwm window manager. */ #ifdef RXVT_SCROLLBAR - pix_colors [Color_scroll].fade (this, 50, pix_colors [Color_bottomShadow]); + lookup_color(Color_scroll, pix_colors).fade (this, 50, lookup_color(Color_bottomShadow, pix_colors)); rgba cscroll; - pix_colors [Color_scroll].get (cscroll); + lookup_color(Color_scroll, pix_colors).get (cscroll); /* topShadowColor */ - if (!pix_colors[Color_topShadow].set (this, + if (!lookup_color(Color_topShadow, pix_colors).set (this, rgba ( min ((int)rgba::MAX_CC, max (cscroll.r / 5, cscroll.r) * 7 / 5), min ((int)rgba::MAX_CC, max (cscroll.g / 5, cscroll.g) * 7 / 5), @@ -1367,8 +1367,8 @@ window_calc (0, 0); /* sub-window placement & size in rxvt_term::resize_all_windows () */ - attributes.background_pixel = pix_colors_focused [Color_border]; - attributes.border_pixel = pix_colors_focused [Color_border]; + attributes.background_pixel = lookup_color(Color_border, pix_colors_focused); + attributes.border_pixel = lookup_color(Color_border, pix_colors_focused); attributes.colormap = cmap; top = XCreateWindow (dpy, parent, @@ -1465,8 +1465,8 @@ window_vt_x, window_vt_y, vt_width, vt_height, 0, - pix_colors_focused[Color_fg], - pix_colors_focused[Color_bg]); + lookup_color(Color_fg, pix_colors_focused), + lookup_color(Color_bg, pix_colors_focused)); attributes.bit_gravity = NorthWestGravity; XChangeWindowAttributes (dpy, vt, CWBitGravity, &attributes); @@ -1483,8 +1483,8 @@ vt_ev.start (display, vt); /* graphics context for the vt window */ - gcvalue.foreground = pix_colors[Color_fg]; - gcvalue.background = pix_colors[Color_bg]; + gcvalue.foreground = lookup_color(Color_fg, pix_colors); + gcvalue.background = lookup_color(Color_bg, pix_colors); gcvalue.graphics_exposures = 0; gc = XCreateGC (dpy, vt, --- src/main.C +++ src/main.C @@ -248,10 +248,10 @@ for (int i = 0; i < TOTAL_COLORS; i++) if (ISSET_PIXCOLOR (i)) { - pix_colors_focused [i].free (this); + lookup_color(i, pix_colors_focused).free (this); #if OFF_FOCUS_FADING if (rs[Rs_fade]) - pix_colors_unfocused [i].free (this); + lookup_color(i, pix_colors_unfocused).free (this); #endif } @@ -965,8 +965,8 @@ } } - pix_colors_focused[idx].free (this); - set_color (pix_colors_focused[idx], color); + lookup_color(idx, pix_colors_focused).free (this); + set_color (lookup_color(idx, pix_colors_focused), color); done: /*TODO: handle Color_BD, scrollbar background, etc. */ @@ -983,12 +983,12 @@ XColor fg, bg; (ISSET_PIXCOLOR (Color_pointer_fg) - ? pix_colors_focused[Color_pointer_fg] - : pix_colors_focused[Color_fg]).get (fg); + ? lookup_color(Color_pointer_fg, pix_colors_focused) + : lookup_color(Color_fg, pix_colors_focused)).get (fg); (ISSET_PIXCOLOR (Color_pointer_bg) - ? pix_colors_focused[Color_pointer_bg] - : pix_colors_focused[Color_bg]).get (bg); + ? lookup_color(Color_pointer_bg, pix_colors_focused) + : lookup_color(Color_bg, pix_colors_focused)).get (bg); XRecolorCursor (dpy, TermWin_cursor, &fg, &bg); } @@ -1007,14 +1007,14 @@ char *env_colorfgbg; for (i = Color_Black; i <= Color_White; i++) - if (pix_colors[Color_fg] == pix_colors[i]) + if (lookup_color(Color_fg, pix_colors) == lookup_color(i, pix_colors)) { sprintf (fstr, "%d", i - Color_Black); break; } for (i = Color_Black; i <= Color_White; i++) - if (pix_colors[Color_bg] == pix_colors[i]) + if (lookup_color(Color_bg, pix_colors) == lookup_color(i, pix_colors)) { sprintf (bstr, "%d", i - Color_Black); #if HAVE_IMG @@ -1043,8 +1043,8 @@ void rxvt_term::alias_color (int dst, int src) { - pix_colors[dst].free (this); - pix_colors[dst].set (this, rs[Rs_color + dst] = rs[Rs_color + src]); + lookup_color(dst, pix_colors).free (this); + lookup_color(dst, pix_colors).set (this, rs[Rs_color + dst] = rs[Rs_color + src]); } #ifdef SMART_RESIZE @@ -1198,8 +1198,8 @@ void rxvt_term::im_set_color (unsigned long &fg, unsigned long &bg) { - fg = pix_colors [Color_fg]; - bg = pix_colors [Color_bg]; + fg = lookup_color(Color_fg, pix_colors); + bg = lookup_color(Color_bg, pix_colors); } void --- src/rxvtfont.C +++ src/rxvtfont.C @@ -243,20 +243,20 @@ # ifdef HAVE_IMG if (term->bg_img - && !term->pix_colors[color].is_opaque () + && !term->lookup_color(color, term->pix_colors).is_opaque () && ((dst = XftDrawPicture (d)))) { XClearArea (disp, d, x, y, w, h, false); - Picture solid_color_pict = XftDrawSrcPicture (d, &term->pix_colors[color].c); + Picture solid_color_pict = XftDrawSrcPicture (d, &term->lookup_color(color, term->pix_colors).c); XRenderComposite (disp, PictOpOver, solid_color_pict, None, dst, 0, 0, 0, 0, x, y, w, h); } else # endif - XftDrawRect (d, &term->pix_colors[color].c, x, y, w, h); + XftDrawRect (d, &term->lookup_color(color, term->pix_colors).c, x, y, w, h); #else - XSetForeground (disp, gc, term->pix_colors[color]); + XSetForeground (disp, gc, term->lookup_color(color, term->pix_colors)); XFillRectangle (disp, d, gc, x, y, w, h); #endif } @@ -342,7 +342,7 @@ clear_rect (d, x, y, term->fwidth * len, term->fheight, bg); - XSetForeground (disp, gc, term->pix_colors[fg]); + XSetForeground (disp, gc, term->lookup_color(fg, term->pix_colors)); while (len) { @@ -1053,7 +1053,7 @@ int base = ascent; // sorry, incorrect: term->fbase; XGCValues v; - v.foreground = term->pix_colors[fg]; + v.foreground = term->lookup_color(fg, term->pix_colors); v.font = f->fid; if (enc2b) @@ -1062,7 +1062,7 @@ if (bg == Color_bg && !slow) { - v.background = term->pix_colors[bg]; + v.background = term->lookup_color(bg, term->pix_colors); XChangeGC (disp, gc, GCForeground | GCBackground | GCFont, &v); XDrawImageString16 (disp, d, gc, x, y + base, xc, len); } @@ -1094,7 +1094,7 @@ if (bg == Color_bg && !slow) { - v.background = term->pix_colors[bg]; + v.background = term->lookup_color(bg, term->pix_colors); XChangeGC (disp, gc, GCForeground | GCBackground | GCFont, &v); XDrawImageString (disp, d, gc, x, y + base, xc, len); } @@ -1417,7 +1417,7 @@ if (term->bg_img && (bg == Color_transparent || bg == Color_bg - || (bg >= 0 && !term->pix_colors[bg].is_opaque () && ((dst = XftDrawPicture (d2)))))) + || (bg >= 0 && !term->lookup_color(bg, term->pix_colors).is_opaque () && ((dst = XftDrawPicture (d2)))))) { int src_x = x, src_y = y; @@ -1454,7 +1454,7 @@ if (dst) { - Picture solid_color_pict = XftDrawSrcPicture (d2, &term->pix_colors[bg].c); + Picture solid_color_pict = XftDrawSrcPicture (d2, &term->lookup_color(bg, term->pix_colors).c); // dst can only be set when bg >= 0 XRenderComposite (disp, PictOpOver, solid_color_pict, None, dst, 0, 0, 0, 0, 0, 0, w, h); @@ -1462,9 +1462,9 @@ } else #endif - XftDrawRect (d2, &term->pix_colors[bg >= 0 ? bg : Color_bg].c, 0, 0, w, h); + XftDrawRect (d2, &term->lookup_color(bg >= 0 ? bg : Color_bg, term->pix_colors).c, 0, 0, w, h); - XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, enc, ep - enc); + XftDrawGlyphSpec (d2, &term->lookup_color(fg, term->pix_colors).c, f, enc, ep - enc); XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y); } else @@ -1473,7 +1473,7 @@ else { clear_rect (d, x, y, w, h, bg); - XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, enc, ep - enc); + XftDrawGlyphSpec (d, &term->lookup_color(fg, term->pix_colors).c, f, enc, ep - enc); } } --- src/rxvtfont.h +++ src/rxvtfont.h @@ -72,8 +72,10 @@ char *fontdesc; // must be power-of-two - 1, also has to match RS_fontMask in rxvt.h -#if USE_256_COLORS - enum { fontCount = 7 }; // 2 extra colors bits, 2 fewer fontcount bits +#if USE_24_BIT_COLOR + enum { fontCount = 7 }; // 36 extra colors bits, 2 fewer fontcount bits +#elif USE_256_COLORS + enum { fontCount = 7 }; // 2 extra colors bits, 2 fewer fontcount bits #else enum { fontCount = 31 }; #endif --- src/rxvt.h +++ src/rxvt.h @@ -39,7 +39,11 @@ #else typedef uint16_t text_t; // saves lots of memory #endif +#if USE_24_BIT_COLOR +typedef uint64_t rend_t; +#else typedef uint32_t rend_t; +#endif typedef int32_t tlen_t; // was int16_t, but this results in smaller code and memory use typedef int32_t tlen_t_; // specifically for use in the line_t structure @@ -342,43 +346,52 @@ #define RS_None 0 // GET_BGATTR depends on RS_fgShift > RS_bgShift -#define RS_colorMask ((1UL << Color_Bits) - 1UL) -#define RS_bgShift 0 -#define RS_fgShift (RS_bgShift + Color_Bits) -#define RS_bgMask (RS_colorMask << RS_bgShift) -#define RS_fgMask (RS_colorMask << RS_fgShift) +#define RS_colorMask ((rend_t) ((1UL << Color_Bits) - 1UL)) +#define RS_bgShift 0 +#define RS_fgShift (RS_bgShift + Color_Bits) +#define RS_bgMask ((rend_t) (RS_colorMask << RS_bgShift)) +#define RS_fgMask ((rend_t) (RS_colorMask << RS_fgShift)) // must have space for rxvt_fontset::fontCount * 2 + 2 values #define RS_fontShift (RS_fgShift + Color_Bits) -#define RS_Careful (1UL << RS_fontShift) /* be careful when drawing these */ -#define RS_fontCount rxvt_fontset::fontCount -#define RS_fontMask ((RS_fontCount << (RS_fontShift + 1)) | RS_Careful) // includes RS_Careful +#define RS_Careful ((rend_t) (1UL << RS_fontShift)) /* be careful when drawing these */ +#define RS_fontCount ((rend_t) rxvt_fontset::fontCount) +#define RS_fontMask ((rend_t) ((RS_fontCount << (RS_fontShift + 1)) | RS_Careful)) // includes RS_Careful // toggle this to force redraw, must be != RS_Careful and otherwise "pretty neutral" -#define RS_redraw (2UL << RS_fontShift) +#define RS_redraw ((rend_t) (2UL << RS_fontShift)) -#define RS_Sel (1UL << 22) +#if USE_24_BIT_COLOR +# define RS_fontCountSize 4 +#elif USE_256_COLORS +# define RS_fontCountSize 4 +#else +# define RS_fontCountSize 8 +#endif + +#define RS_selShift (RS_fontShift + RS_fontCountSize) +#define RS_Sel ((rend_t) (1UL << RS_selShift)) // 4 custom bits for extensions #define RS_customCount 16UL -#define RS_customShift 23 -#define RS_customMask ((RS_customCount - 1UL) << RS_customShift) +#define RS_customShift (RS_selShift + 1) +#define RS_customMask ((rend_t) ((RS_customCount - 1UL) << RS_customShift)) // font styles -#define RS_Bold (1UL << RS_styleShift) -#define RS_Italic (2UL << RS_styleShift) +#define RS_Bold ((rend_t) (1UL << RS_styleShift)) +#define RS_Italic ((rend_t) (2UL << RS_styleShift)) -#define RS_styleCount 4 -#define RS_styleShift 27 -#define RS_styleMask (RS_Bold | RS_Italic) +#define RS_styleCount 4 +#define RS_styleShift (RS_customShift + RS_styleCount) +#define RS_styleMask ((rend_t) (RS_Bold | RS_Italic)) // fake styles -#define RS_Blink (1UL << 29) -#define RS_RVid (1UL << 30) // reverse video -#define RS_Uline (1UL << 31) // underline +#define RS_Blink ((rend_t) (1UL << (RS_styleShift + 2))) +#define RS_RVid ((rend_t) (1UL << (RS_styleShift + 3))) // reverse video +#define RS_Uline ((rend_t) (1UL << (RS_styleShift + 4))) // underline -#define RS_baseattrMask (RS_Italic | RS_Bold | RS_Blink | RS_RVid | RS_Uline) -#define RS_attrMask (RS_baseattrMask | RS_fontMask) +#define RS_baseattrMask ((rend_t) (RS_Italic | RS_Bold | RS_Blink | RS_RVid | RS_Uline)) +#define RS_attrMask ((rend_t) (RS_baseattrMask | RS_fontMask)) #define DEFAULT_RSTYLE (RS_None | (Color_fg << RS_fgShift) | (Color_bg << RS_bgShift)) #define OVERLAY_RSTYLE (RS_None | (Color_Black << RS_fgShift) | (Color_Yellow << RS_bgShift)) @@ -528,7 +541,9 @@ #endif }; -#if USE_256_COLORS +#if USE_24_BIT_COLOR +# define Color_Bits 25 +#elif USE_256_COLORS # define Color_Bits 9 // 0 .. maxTermCOLOR24 #else # define Color_Bits 8 // 0 .. maxTermCOLOR24 @@ -664,21 +679,21 @@ #define ROW(n) ROW_of (this, n) /* how to build & extract colors and attributes */ -#define GET_BASEFG(x) (((x) & RS_fgMask) >> RS_fgShift) -#define GET_BASEBG(x) (((x) & RS_bgMask) >> RS_bgShift) +#define GET_BASEFG(x) ((((rend_t) (x)) & RS_fgMask) >> RS_fgShift) +#define GET_BASEBG(x) ((((rend_t) (x)) & RS_bgMask) >> RS_bgShift) -#define GET_FONT(x) (((x) & RS_fontMask) >> RS_fontShift) -#define SET_FONT(x,fid) (((x) & ~RS_fontMask) | ((fid) << RS_fontShift)) +#define GET_FONT(x) ((((rend_t) (x)) & RS_fontMask) >> RS_fontShift) +#define SET_FONT(x,fid) ((((rend_t) (x)) & ~((rend_t) RS_fontMask)) | (((rend_t) (fid)) << RS_fontShift)) -#define GET_STYLE(x) (((x) & RS_styleMask) >> RS_styleShift) -#define SET_STYLE(x,style) (((x) & ~RS_styleMask) | ((style) << RS_styleShift)) +#define GET_STYLE(x) ((((rend_t) (x)) & RS_styleMask) >> RS_styleShift) +#define SET_STYLE(x,style) ((((rend_t) (x)) & ~((rend_t) RS_styleMask)) | (((rend_t) (style)) << RS_styleShift)) -#define GET_ATTR(x) (((x) & RS_attrMask)) -#define SET_FGCOLOR(x,fg) (((x) & ~RS_fgMask) | ((fg) << RS_fgShift)) -#define SET_BGCOLOR(x,bg) (((x) & ~RS_bgMask) | ((bg) << RS_bgShift)) -#define SET_ATTR(x,a) (((x) & ~RS_attrMask) | (a)) +#define GET_ATTR(x) ((((rend_t) (x)) & RS_attrMask)) +#define SET_FGCOLOR(x,fg) ((((rend_t) (x)) & ~((rend_t) RS_fgMask)) | (((rend_t) (fg)) << RS_fgShift)) +#define SET_BGCOLOR(x,bg) ((((rend_t) (x)) & ~((rend_t) RS_bgMask)) | (((rend_t) (bg)) << RS_bgShift)) +#define SET_ATTR(x,a) ((((rend_t) (x)) & ~((rend_t) RS_attrMask)) | ((rend_t) (a))) -#define RS_SAME(a,b) (!(((a) ^ (b)) & ~RS_Careful)) +#define RS_SAME(a,b) (!((((rend_t) (a)) ^ ((rend_t) (b))) & ~((rend_t) RS_Careful))) #define PIXCOLOR_NAME(idx) rs[Rs_color + (idx)] #define ISSET_PIXCOLOR(idx) (!!rs[Rs_color + (idx)]) @@ -1413,7 +1428,12 @@ void scr_swap_screen () noexcept; void scr_change_screen (int scrn); void scr_color (unsigned int color, int fgbg) noexcept; - void scr_rendition (int set, int style) noexcept; +#if USE_24_BIT_COLOR + void scr_color_24 (unsigned int color, int fgbg) noexcept; + void scr_color_rgb (unsigned int r, unsigned int g, unsigned int b, int fgbg) noexcept; +#endif + rxvt_color &lookup_color (unsigned int color, rxvt_color *table) noexcept; + void scr_rendition (int set, rend_t style) noexcept; void scr_add_lines (const wchar_t *str, int len, int minlines = 0) noexcept; void scr_backspace () noexcept; void scr_tab (int count, bool ht = false) noexcept; --- src/rxvtperl.xs +++ src/rxvtperl.xs @@ -795,6 +795,18 @@ PROTOTYPES: ENABLE +TYPEMAP: <> RS_customShift; OUTPUT: RETVAL -int -SET_CUSTOM (int rend, int new_value) +rend_t +SET_CUSTOM (rend_t rend, int new_value) CODE: { if (!IN_RANGE_EXC (new_value, 0, RS_customCount)) @@ -1555,8 +1567,8 @@ THIS->vt_emask_perl |= emask; THIS->vt_select_input (); -U32 -rxvt_term::rstyle (U32 new_rstyle = THIS->rstyle) +UV +rxvt_term::rstyle (rend_t new_rstyle = THIS->rstyle) CODE: RETVAL = THIS->rstyle; THIS->rstyle = new_rstyle; @@ -2043,10 +2055,10 @@ RETVAL void -rxvt_term::scr_xor_rect (int beg_row, int beg_col, int end_row, int end_col, U32 rstyle1 = RS_RVid, U32 rstyle2 = RS_RVid | RS_Uline) +rxvt_term::scr_xor_rect (int beg_row, int beg_col, int end_row, int end_col, rend_t rstyle1 = RS_RVid, rend_t rstyle2 = RS_RVid | RS_Uline) void -rxvt_term::scr_xor_span (int beg_row, int beg_col, int end_row, int end_col, U32 rstyle = RS_RVid) +rxvt_term::scr_xor_span (int beg_row, int beg_col, int end_row, int end_col, rend_t rstyle = RS_RVid) void rxvt_term::scr_bell () @@ -2112,7 +2124,7 @@ } SV * -rxvt_term::overlay (int x, int y, int w, int h, int rstyle = OVERLAY_RSTYLE, int border = 2) +rxvt_term::overlay (int x, int y, int w, int h, rend_t rstyle = OVERLAY_RSTYLE, int border = 2) CODE: { overlay *o = new overlay (THIS, x, y, w, h, rstyle, border); @@ -2211,8 +2223,8 @@ XCreateSimpleWindow (rxvt_term *term, Window parent, int x, int y, unsigned int width, unsigned int height) C_ARGS: term->dpy, (Window)parent, x, y, width, height, 0, - term->pix_colors_focused[Color_border], - term->pix_colors_focused[Color_border] + term->lookup_color(Color_border, term->pix_colors_focused), + term->lookup_color(Color_border, term->pix_colors_focused) #endif @@ -2346,7 +2358,7 @@ img->reify () ->replace (img); - img->convert_format (XRenderFindVisualFormat (THIS->dpy, THIS->visual), THIS->pix_colors [Color_bg]) + img->convert_format (XRenderFindVisualFormat (THIS->dpy, THIS->visual), THIS->lookup_color(Color_bg, THIS->pix_colors)) ->replace (img); THIS->bg_img = img; --- src/screen.C +++ src/screen.C @@ -626,12 +626,51 @@ rstyle = SET_BGCOLOR (rstyle, color); } +#if USE_24_BIT_COLOR +static rxvt_color *scr_colors[1 << 24]; + +void +rxvt_term::scr_color_24 (unsigned int color, int fgbg) noexcept +{ + color += TOTAL_COLORS; + if (fgbg == Color_fg) + rstyle = SET_FGCOLOR (rstyle, color); + else + rstyle = SET_BGCOLOR (rstyle, color); +} + +void +rxvt_term::scr_color_rgb (unsigned int r, unsigned int g, unsigned int b, int fgbg) noexcept +{ + unsigned int color = (r << 16) + (g << 8) + b; + scr_color_24(color, fgbg); +} +#endif + +rxvt_color +&rxvt_term::lookup_color (unsigned int color, rxvt_color *table) noexcept +{ +#if USE_24_BIT_COLOR + if (color >= TOTAL_COLORS) { + color -= TOTAL_COLORS; + if (scr_colors[color] == NULL) { + scr_colors[color] = new rxvt_color(); + char name[1+2*3+1]; + sprintf(name, "#%02x%02x%02x", (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff); + scr_colors[color]->set(this, name); + } + return *scr_colors[color]; + } else +#endif + return table[color]; +} + /* ------------------------------------------------------------------------- */ /* * Change the rendition style for following text */ void -rxvt_term::scr_rendition (int set, int style) noexcept +rxvt_term::scr_rendition (int set, rend_t style) noexcept { if (set) rstyle |= style; @@ -1389,13 +1428,13 @@ if (mapped) { - gcvalue.foreground = pix_colors[bgcolor_of (rstyle)]; + gcvalue.foreground = lookup_color(bgcolor_of (rstyle), pix_colors); XChangeGC (dpy, gc, GCForeground, &gcvalue); XFillRectangle (dpy, vt, gc, 0, Row2Pixel (row - view_start), (unsigned int)vt_width, (unsigned int)Height2Pixel (num)); - gcvalue.foreground = pix_colors[Color_fg]; + gcvalue.foreground = lookup_color(Color_fg, pix_colors); XChangeGC (dpy, gc, GCForeground, &gcvalue); } } @@ -1724,15 +1763,15 @@ } else #endif - ::swap (pix_colors[Color_fg], pix_colors[Color_bg]); + ::swap (lookup_color(Color_fg, pix_colors), lookup_color(Color_bg, pix_colors)); #ifdef HAVE_IMG if (bg_img == 0) #endif - XSetWindowBackground (dpy, vt, pix_colors[Color_bg]); + XSetWindowBackground (dpy, vt, lookup_color(Color_bg, pix_colors)); XGCValues gcvalue; - gcvalue.foreground = pix_colors[Color_fg]; - gcvalue.background = pix_colors[Color_bg]; + gcvalue.foreground = lookup_color(Color_fg, pix_colors); + gcvalue.background = lookup_color(Color_bg, pix_colors); XChangeGC (dpy, gc, GCBackground | GCForeground, &gcvalue); scr_clear (); @@ -2430,14 +2469,14 @@ { if (showcursor && focus && row == screen.cur.row && IN_RANGE_EXC (col, cur_col, cur_col + cursorwidth)) - XSetForeground (dpy, gc, pix_colors[ccol1]); + XSetForeground (dpy, gc, lookup_color(ccol1, pix_colors)); else #if ENABLE_FRILLS if (ISSET_PIXCOLOR (Color_underline)) - XSetForeground (dpy, gc, pix_colors[Color_underline]); + XSetForeground (dpy, gc, lookup_color(Color_underline, pix_colors)); else #endif - XSetForeground (dpy, gc, pix_colors[fore]); + XSetForeground (dpy, gc, lookup_color(fore, pix_colors)); XDrawLine (dpy, vt, gc, xpixel, ypixel + font->ascent + 1, @@ -2457,7 +2496,7 @@ scr_set_char_rend (ROW(screen.cur.row), cur_col, cur_rend); else if (oldcursor.row >= 0) { - XSetForeground (dpy, gc, pix_colors[ccol1]); + XSetForeground (dpy, gc, lookup_color(ccol1, pix_colors)); if (cursor_type == 1) XFillRectangle (dpy, vt, gc, Col2Pixel (cur_col), @@ -2474,7 +2513,7 @@ } else if (oldcursor.row >= 0) { - XSetForeground (dpy, gc, pix_colors[ccol1]); + XSetForeground (dpy, gc, lookup_color(ccol1, pix_colors)); XDrawRectangle (dpy, vt, gc, Col2Pixel (cur_col), @@ -2543,15 +2582,15 @@ else # endif { - XSetWindowBackground (dpy, parent, pix_colors[Color_border]); + XSetWindowBackground (dpy, parent, lookup_color(Color_border, pix_colors)); XSetWindowBackgroundPixmap (dpy, vt, bg_img->pm); } } else #endif { - XSetWindowBackground (dpy, parent, pix_colors[Color_border]); - XSetWindowBackground (dpy, vt, pix_colors[Color_bg]); + XSetWindowBackground (dpy, parent, lookup_color(Color_border, pix_colors)); + XSetWindowBackground (dpy, vt, lookup_color(Color_bg, pix_colors)); } XClearWindow (dpy, parent); @@ -2561,7 +2600,7 @@ if (transparent) XSetWindowBackgroundPixmap (dpy, scrollBar.win, ParentRelative); else - XSetWindowBackground (dpy, scrollBar.win, pix_colors[scrollBar.color ()]); + XSetWindowBackground (dpy, scrollBar.win, lookup_color(scrollBar.color (), pix_colors)); scrollBar.state = SB_STATE_IDLE; scrollBar.show (0); } --- src/scrollbar.C +++ src/scrollbar.C @@ -72,8 +72,8 @@ total_width (), term->szHint.height, 0, - term->pix_colors[Color_fg], - term->pix_colors[color ()]); + term->lookup_color(Color_fg, term->pix_colors), + term->lookup_color(color (), term->pix_colors)); XDefineCursor (term->dpy, win, leftptr_cursor); XSelectInput (term->dpy, win, --- src/scrollbar-next.C +++ src/scrollbar-next.C @@ -154,15 +154,15 @@ gcvalue.graphics_exposures = False; - gcvalue.foreground = term->pix_colors_focused[Color_Black]; + gcvalue.foreground = term->lookup_color(Color_Black, term->pix_colors_focused); blackGC = XCreateGC (term->dpy, win, GCForeground | GCGraphicsExposures, &gcvalue); - gcvalue.foreground = term->pix_colors_focused[Color_White]; + gcvalue.foreground = term->lookup_color(Color_White, term->pix_colors_focused); whiteGC = XCreateGC (term->dpy, win, GCForeground | GCGraphicsExposures, &gcvalue); - light = term->pix_colors_focused[Color_scroll]; + light = term->lookup_color(Color_scroll, term->pix_colors_focused); #if 0 //color used by rxvt if (color.set (term, rgba (0xaeba, 0xaaaa, 0xaeba))) @@ -172,7 +172,7 @@ grayGC = XCreateGC (term->dpy, win, GCForeground | GCGraphicsExposures, &gcvalue); - dark = term->pix_colors_focused[Color_Grey25]; + dark = term->lookup_color(Color_Grey25, term->pix_colors_focused); #if 0 //color used by rxvt if (color.set (term, rgba (0x51aa, 0x5555, 0x5144))) --- src/scrollbar-plain.C +++ src/scrollbar-plain.C @@ -38,7 +38,7 @@ XGCValues gcvalue; init |= SB_STYLE_PLAIN; - gcvalue.foreground = term->pix_colors_focused[Color_scroll]; + gcvalue.foreground = term->lookup_color(Color_scroll, term->pix_colors_focused); pscrollbarGC = XCreateGC (term->dpy, win, GCForeground, &gcvalue); } --- src/scrollbar-rxvt.C +++ src/scrollbar-rxvt.C @@ -158,11 +158,11 @@ init |= SB_STYLE_RXVT; - gcvalue.foreground = term->pix_colors[Color_topShadow]; + gcvalue.foreground = term->lookup_color(Color_topShadow, term->pix_colors); topShadowGC = XCreateGC (term->dpy, term->vt, GCForeground, &gcvalue); - gcvalue.foreground = term->pix_colors[Color_bottomShadow]; + gcvalue.foreground = term->lookup_color(Color_bottomShadow, term->pix_colors); botShadowGC = XCreateGC (term->dpy, term->vt, GCForeground, &gcvalue); - gcvalue.foreground = term->pix_colors[ (term->depth <= 2 ? Color_fg : Color_scroll)]; + gcvalue.foreground = term->lookup_color( (term->depth <= 2 ? Color_fg : Color_scroll), term->pix_colors); scrollbarGC = XCreateGC (term->dpy, term->vt, GCForeground, &gcvalue); } else --- src/scrollbar-xterm.C +++ src/scrollbar-xterm.C @@ -49,13 +49,13 @@ rxvt_fatal ("can't create bitmap\n"); gcvalue.fill_style = FillOpaqueStippled; - gcvalue.foreground = term->pix_colors_focused[Color_scroll]; - gcvalue.background = term->pix_colors_focused[Color_bg]; + gcvalue.foreground = term->lookup_color(Color_scroll, term->pix_colors_focused); + gcvalue.background = term->lookup_color(Color_bg, term->pix_colors_focused); xscrollbarGC = XCreateGC (term->dpy, win, GCForeground | GCBackground | GCFillStyle | GCStipple, &gcvalue); - gcvalue.foreground = term->pix_colors_focused[Color_border]; + gcvalue.foreground = term->lookup_color(Color_border, term->pix_colors_focused); ShadowGC = XCreateGC (term->dpy, win, GCForeground, &gcvalue); }