Last active
April 24, 2023 12:49
-
-
Save cpixl/63271adf12171e0fc0bc to your computer and use it in GitHub Desktop.
24-bit color patch for URxvt version 9.22 (based on https://github.com/spudowiar/rxvt-unicode)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- README.configure | |
+++ README.configure | |
@@ -9,8 +9,8 @@ CONFIGURE OPTIONS | |
--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 @@ CONFIGURE OPTIONS | |
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) | |
Set the basename for the installed binaries, resulting in "urxvt", | |
"urxvtd" etc.). Specify "--with-name=rxvt" to replace with "rxvt". | |
--- config.h.in | |
+++ config.h.in | |
@@ -380,6 +380,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 | |
@@ -713,6 +713,7 @@ enable_everything | |
enable_assert | |
enable_warnings | |
enable_256_color | |
+enable_24_bit_color | |
enable_unicode3 | |
enable_combining | |
enable_xft | |
@@ -1386,6 +1387,7 @@ Optional Features: | |
--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 | |
@@ -4820,6 +4822,20 @@ $as_echo "#define USE_256_COLORS 1" >>confdefs.h | |
fi | |
+support_24_bit_color=no | |
+# Check whether --enable-24-bit-color was given. | |
+if test "${enable_24_bit_color+set}" = set; 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 | |
+ | |
+$as_echo "#define USE_24_BIT_COLOR 1" >>confdefs.h | |
+ | |
+fi | |
+ | |
# Check whether --enable-unicode3 was given. | |
if test "${enable_unicode3+set}" = set; then : | |
enableval=$enable_unicode3; if test x$enableval = xyes -o x$enableval = xno; then | |
--- configure.ac | |
+++ configure.ac | |
@@ -201,6 +201,16 @@ if test x$support_256_color = xyes; then | |
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 | |
--- src/background.C | |
+++ src/background.C | |
@@ -312,7 +312,7 @@ rxvt_term::render_image (rxvt_image &image) | |
img->draw (bg_img, PictOpOver, image.alpha * 1. / 0xffff); | |
XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); | |
- img->convert_format (format, pix_colors [Color_bg])->replace (img); | |
+ img->convert_format (format, lookup_color(Color_bg, pix_colors))->replace (img); | |
delete bg_img; | |
bg_img = img; | |
@@ -471,7 +471,7 @@ rxvt_term::render_root_image () | |
} | |
XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); | |
- img->convert_format (format, pix_colors [Color_bg])->replace (img); | |
+ img->convert_format (format, lookup_color(Color_bg, pix_colors))->replace (img); | |
delete bg_img; | |
bg_img = img; | |
@@ -520,7 +520,7 @@ rxvt_term::bg_init () | |
root_effects.set_blur (rs [Rs_blurradius]); | |
if (ISSET_PIXCOLOR (Color_tint)) | |
- root_effects.set_tint (pix_colors_focused [Color_tint]); | |
+ root_effects.set_tint (lookup_color(Color_tint, pix_colors_focused)); | |
if (rs [Rs_shade]) | |
root_effects.set_shade (rs [Rs_shade]); | |
--- src/command.C | |
+++ src/command.C | |
@@ -1843,11 +1843,11 @@ rxvt_term::update_fade_color (unsigned int idx, bool first_time) | |
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 | |
} | |
@@ -3334,7 +3334,7 @@ rxvt_term::process_color_seq (int report, int color, const char *str, char resp) | |
if (str[0] == '?' && !str[1]) | |
{ | |
rgba c; | |
- pix_colors_focused[color].get (c); | |
+ lookup_color(color, pix_colors_focused).get (c); | |
#if XFT | |
if (c.a != rgba::MAX_CC) | |
@@ -3482,7 +3482,7 @@ rxvt_term::process_xterm_seq (int op, char *str, char resp) | |
bool changed = false; | |
if (ISSET_PIXCOLOR (Color_tint)) | |
- changed = root_effects.set_tint (pix_colors_focused [Color_tint]); | |
+ changed = root_effects.set_tint (lookup_color(Color_tint, pix_colors_focused)); | |
if (changed) | |
update_background (); | |
@@ -3876,7 +3876,7 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg) | |
{ | |
unsigned int i; | |
short rendset; | |
- int rendstyle; | |
+ rend_t rendstyle; | |
if (nargs == 0) | |
{ | |
@@ -3969,6 +3969,14 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg) | |
scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_fg); | |
i += 2; | |
} | |
+#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_fg); | |
+ i += 4; | |
+ } | |
+#endif | |
break; | |
case 39: /* default fg */ | |
scr_color (Color_fg, Color_fg); | |
@@ -3990,6 +3998,14 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg) | |
scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_bg); | |
i += 2; | |
} | |
+#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 | |
break; | |
case 49: /* default bg */ | |
scr_color (Color_bg, Color_bg); | |
--- src/init.C | |
+++ src/init.C | |
@@ -1068,7 +1068,7 @@ rxvt_term::get_colors () | |
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 | |
@@ -1077,13 +1077,13 @@ rxvt_term::get_colors () | |
* 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), | |
@@ -1325,8 +1325,8 @@ rxvt_term::create_windows (int argc, const char *const *argv) | |
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, | |
@@ -1412,8 +1412,8 @@ rxvt_term::create_windows (int argc, const char *const *argv) | |
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); | |
@@ -1430,8 +1430,8 @@ rxvt_term::create_windows (int argc, const char *const *argv) | |
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 | |
@@ -254,10 +254,10 @@ rxvt_term::~rxvt_term () | |
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 | |
} | |
@@ -971,8 +971,8 @@ rxvt_term::set_window_color (int idx, const char *color) | |
} | |
} | |
- 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. */ | |
@@ -989,12 +989,12 @@ rxvt_term::recolor_cursor () | |
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); | |
} | |
@@ -1013,14 +1013,14 @@ rxvt_term::get_colorfgbg () | |
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 BG_IMAGE_FROM_FILE | |
@@ -1049,8 +1049,8 @@ rxvt_term::set_color (rxvt_color &color, const char *name) | |
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]); | |
} | |
/* -------------------------------------------------------------------- * | |
@@ -1188,8 +1188,8 @@ rxvt_term::set_widthheight (unsigned int newwidth, unsigned int newheight) | |
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/rxvt.h | |
+++ src/rxvt.h | |
@@ -39,7 +39,11 @@ typedef uint32_t text_t; | |
#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 | |
@@ -411,43 +415,52 @@ enum { | |
#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)) | |
@@ -599,7 +612,9 @@ enum colour_list { | |
#endif | |
}; | |
-#if USE_256_COLORS | |
+#if USE_24_BIT_COLOR | |
+#define Color_Bits 25 | |
+#elif USE_256_COLORS | |
# define Color_Bits 9 // 0 .. maxTermCOLOR | |
#else | |
# define Color_Bits 7 // 0 .. maxTermCOLOR | |
@@ -729,21 +744,21 @@ typedef struct _mwmhints | |
#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)]) | |
@@ -1503,7 +1518,12 @@ struct rxvt_term : zero_initialized, rxvt_vars, rxvt_screen | |
void scr_swap_screen () NOTHROW; | |
void scr_change_screen (int scrn); | |
void scr_color (unsigned int color, int fgbg) NOTHROW; | |
- void scr_rendition (int set, int style) NOTHROW; | |
+#if USE_24_BIT_COLOR | |
+ void scr_color_24 (unsigned int color, int fgbg) NOTHROW; | |
+ void scr_color_rgb (unsigned int r, unsigned int g, unsigned int b, int fgbg) NOTHROW; | |
+#endif | |
+ rxvt_color &lookup_color (unsigned int color, rxvt_color *table) NOTHROW; | |
+ void scr_rendition (int set, rend_t style) NOTHROW; | |
void scr_add_lines (const wchar_t *str, int len, int minlines = 0) NOTHROW; | |
void scr_backspace () NOTHROW; | |
void scr_tab (int count, bool ht = false) NOTHROW; | |
--- src/rxvtfont.C | |
+++ src/rxvtfont.C | |
@@ -243,20 +243,20 @@ rxvt_font::clear_rect (rxvt_drawable &d, int x, int y, int w, int h, int color) | |
# ifdef HAVE_BG_PIXMAP | |
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 @@ rxvt_font_default::draw (rxvt_drawable &d, int x, int y, | |
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 @@ rxvt_font_x11::draw (rxvt_drawable &d, int x, int y, | |
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 @@ rxvt_font_x11::draw (rxvt_drawable &d, int x, int y, | |
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 @@ rxvt_font_x11::draw (rxvt_drawable &d, int x, int y, | |
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 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, | |
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 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, | |
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 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, | |
} | |
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 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y, | |
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 @@ struct rxvt_fontset | |
char *fontdesc; | |
// must be power-of-two - 1, also has to match RS_fontMask in rxvt.h | |
-#if USE_256_COLORS | |
- enum { fontCount = 7 }; // 4 extra colors bits, 4 fewer fontcount bits | |
+#if USE_24_BIT_COLOR | |
+ enum { fontCount = 7 }; // 36 extra colors bits, 4 fewer fontcount bits | |
+#elif USE_256_COLORS | |
+ enum { fontCount = 7 }; // 4 extra colors bits, 4 fewer fontcount bits | |
#else | |
enum { fontCount = 127 }; | |
#endif | |
--- src/rxvtperl.xs | |
+++ src/rxvtperl.xs | |
@@ -789,6 +789,18 @@ MODULE = urxvt PACKAGE = urxvt | |
PROTOTYPES: ENABLE | |
+TYPEMAP: <<END | |
+rend_t T_UINT | |
+ | |
+INPUT | |
+T_UINT | |
+ $var = ($type)SvUV($arg); | |
+ | |
+OUTPUT | |
+T_UINT | |
+ sv_setuv($arg, (UV)$var); | |
+END | |
+ | |
BOOT: | |
{ | |
sv_setsv (get_sv ("urxvt::LIBDIR", 1), newSVpvn (LIBDIR, sizeof (LIBDIR) - 1)); | |
@@ -1069,43 +1081,44 @@ NOW () | |
OUTPUT: | |
RETVAL | |
-int | |
-GET_BASEFG (int rend) | |
+rend_t | |
+GET_BASEFG (rend_t rend) | |
CODE: | |
RETVAL = GET_BASEFG (rend); | |
OUTPUT: | |
RETVAL | |
-int | |
-GET_BASEBG (int rend) | |
+rend_t | |
+GET_BASEBG (rend_t rend) | |
CODE: | |
RETVAL = GET_BASEBG (rend); | |
OUTPUT: | |
RETVAL | |
-int | |
-SET_FGCOLOR (int rend, int new_color) | |
+rend_t | |
+SET_FGCOLOR (rend_t rend, int new_color) | |
CODE: | |
RETVAL = SET_FGCOLOR (rend, clamp (new_color, 0, TOTAL_COLORS - 1)); | |
OUTPUT: | |
RETVAL | |
-int | |
-SET_BGCOLOR (int rend, int new_color) | |
+rend_t | |
+SET_BGCOLOR (rend_t rend, int new_color) | |
CODE: | |
RETVAL = SET_BGCOLOR (rend, clamp (new_color, 0, TOTAL_COLORS - 1)); | |
OUTPUT: | |
RETVAL | |
-int | |
-GET_CUSTOM (int rend) | |
+rend_t | |
+GET_CUSTOM (rend_t rend) | |
CODE: | |
+ | |
RETVAL = (rend & RS_customMask) >> 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)) | |
@@ -1515,8 +1528,8 @@ rxvt_term::vt_emask_add (U32 emask) | |
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; | |
@@ -2003,10 +2016,10 @@ rxvt_term::cur_charset () | |
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 () | |
@@ -2072,7 +2085,7 @@ rxvt_term::cmd_parse (SV *octets) | |
} | |
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); | |
@@ -2171,8 +2184,8 @@ Window | |
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 | |
@@ -2299,7 +2312,7 @@ rxvt_term::set_background (rxvt_img *img, bool border = false) | |
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 | |
@@ -625,12 +625,52 @@ rxvt_term::scr_color (unsigned int color, int fgbg) NOTHROW | |
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) NOTHROW | |
+{ | |
+ 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) NOTHROW | |
+{ | |
+ 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) NOTHROW | |
+{ | |
+#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) NOTHROW | |
+rxvt_term::scr_rendition (int set, rend_t style) NOTHROW | |
{ | |
if (set) | |
rstyle |= style; | |
@@ -1388,13 +1428,13 @@ rxvt_term::scr_erase_screen (int mode) NOTHROW | |
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); | |
} | |
} | |
@@ -1715,15 +1755,15 @@ rxvt_term::scr_rvideo_mode (bool on) NOTHROW | |
{ | |
rvideo_state = on; | |
- ::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 (); | |
@@ -2426,14 +2466,14 @@ rxvt_term::scr_refresh () NOTHROW | |
{ | |
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, | |
@@ -2453,7 +2493,7 @@ rxvt_term::scr_refresh () NOTHROW | |
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), | |
@@ -2463,7 +2503,7 @@ rxvt_term::scr_refresh () NOTHROW | |
} | |
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), | |
@@ -2532,15 +2572,15 @@ rxvt_term::scr_recolor (bool refresh) NOTHROW | |
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); | |
@@ -2550,7 +2590,7 @@ rxvt_term::scr_recolor (bool refresh) NOTHROW | |
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-next.C | |
+++ src/scrollbar-next.C | |
@@ -154,15 +154,15 @@ scrollBar_t::init_next () | |
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 @@ scrollBar_t::init_next () | |
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 @@ scrollBar_t::show_plain (int update) | |
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 @@ scrollBar_t::show_rxvt (int update) | |
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 @@ scrollBar_t::show_xterm (int update) | |
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); | |
} | |
--- src/scrollbar.C | |
+++ src/scrollbar.C | |
@@ -72,8 +72,8 @@ scrollBar_t::resize () | |
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, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment