summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authormrdotx2020-11-13 13:29:06 +0100
committermrdotx2020-11-13 13:29:06 +0100
commit97ce2f5ae774f4792d89a16ee17ef7b3fd2ad41a (patch)
tree28dc5e050ec09cfc02484f20830eff12941809aa
downloadaur-97ce2f5ae774f4792d89a16ee17ef7b3fd2ad41a.tar.gz
initial upload
-rw-r--r--.SRCINFO39
-rw-r--r--.gitignore9
-rw-r--r--24-bit-color.patch991
-rw-r--r--PKGBUILD113
-rw-r--r--enable-wide-glyphs.patch278
-rw-r--r--improve-font-rendering.patch173
-rw-r--r--perl-segfault.patch33
-rw-r--r--resize-font191
-rw-r--r--sgr-mouse-mode.patch90
-rw-r--r--urxvt-tabbed.desktop10
-rw-r--r--urxvt.desktop10
-rw-r--r--urxvtc.desktop10
12 files changed, 1947 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..ae5408856ba9
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,39 @@
+pkgbase = rxvt-unicode-truecolor-wide-glyphs
+ pkgdesc = Unicode enabled rxvt-clone terminal emulator (urxvt) with truecolor and wide glyphs support
+ pkgver = 9.22
+ pkgrel = 1
+ url = http://software.schmorp.de/pkg/rxvt-unicode.html
+ arch = i686
+ arch = x86_64
+ license = GPL
+ depends = libxft
+ depends = perl
+ depends = startup-notification
+ optdepends = gtk2-perl: to use the urxvt-tabbed
+ provides = rxvt-unicode
+ provides = rxvt-unicode-terminfo
+ conflicts = rxvt-unicode
+ conflicts = rxvt-unicode-terminfo
+ source = http://dist.schmorp.de/rxvt-unicode/rxvt-unicode-9.22.tar.bz2
+ source = urxvt.desktop
+ source = urxvtc.desktop
+ source = urxvt-tabbed.desktop
+ source = resize-font
+ source = sgr-mouse-mode.patch
+ source = 24-bit-color.patch
+ source = enable-wide-glyphs.patch
+ source = improve-font-rendering.patch
+ source = perl-segfault.patch
+ sha1sums = e575b869782fbfed955f84f48b204ec888d91ba1
+ sha1sums = b5a4507f85ebb7bac589db2e07d9bc40106720d9
+ sha1sums = 62c4ffecfce6967def394dd4d418b68652372ea2
+ sha1sums = cd204d608d114d39c80331efe0af0231ad6b7e18
+ sha1sums = a61366659c73bd551fa99a8415bb71e033897598
+ sha1sums = dfbc8729c545105eff21e20ef3a4a3841a68a192
+ sha1sums = 9f5db305863b17175e72f9e2d4a78d0d7f25fd34
+ sha1sums = d9f3b52b273d13fbd4089a7869ab2e70bf190bc9
+ sha1sums = 2f976cfbb4ae092d331e169b56ec6423b198f462
+ sha1sums = 361f4649596342d07311c2590b809b85b3a918ee
+
+pkgname = rxvt-unicode-truecolor-wide-glyphs
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..cc1fafbf050f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+# path: /home/klassiker/.local/share/repos/rxvt-unicode-truecolor-wide-glyphs/.gitignore
+# author: klassiker [mrdotx]
+# github: https://aur.archlinux.org/packages/rxvt-unicode-truecolor-wide-glyphs
+# date: 2020-11-13T13:23:15+0100
+
+/pkg/
+/src/
+rxvt-unicode-*.bz2
+*.pkg.tar*
diff --git a/24-bit-color.patch b/24-bit-color.patch
new file mode 100644
index 000000000000..b3b587f77bcf
--- /dev/null
+++ b/24-bit-color.patch
@@ -0,0 +1,991 @@
+--- 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, \ No newline at end of file
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..a6855b2b9fad
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,113 @@
+# Maintainer: mrdotx <klassiker@gmx.de>
+_pkgname=rxvt-unicode
+pkgname=rxvt-unicode-truecolor-wide-glyphs
+pkgver=9.22
+pkgrel=1
+pkgdesc='Unicode enabled rxvt-clone terminal emulator (urxvt) with truecolor and wide glyphs support'
+arch=('i686' 'x86_64')
+url='http://software.schmorp.de/pkg/rxvt-unicode.html'
+license=('GPL')
+depends=('libxft' 'perl' 'startup-notification')
+optdepends=('gtk2-perl: to use the urxvt-tabbed')
+provides=('rxvt-unicode' 'rxvt-unicode-terminfo')
+conflicts=('rxvt-unicode' 'rxvt-unicode-terminfo')
+source=(http://dist.schmorp.de/rxvt-unicode/$_pkgname-$pkgver.tar.bz2
+ 'urxvt.desktop'
+ 'urxvtc.desktop'
+ 'urxvt-tabbed.desktop'
+ 'resize-font'
+ 'sgr-mouse-mode.patch'
+ '24-bit-color.patch'
+ 'enable-wide-glyphs.patch'
+ 'improve-font-rendering.patch'
+ 'perl-segfault.patch'
+ )
+sha1sums=('e575b869782fbfed955f84f48b204ec888d91ba1'
+ 'b5a4507f85ebb7bac589db2e07d9bc40106720d9'
+ '62c4ffecfce6967def394dd4d418b68652372ea2'
+ 'cd204d608d114d39c80331efe0af0231ad6b7e18'
+ 'a61366659c73bd551fa99a8415bb71e033897598'
+ 'dfbc8729c545105eff21e20ef3a4a3841a68a192'
+ '9f5db305863b17175e72f9e2d4a78d0d7f25fd34'
+ 'd9f3b52b273d13fbd4089a7869ab2e70bf190bc9'
+ '2f976cfbb4ae092d331e169b56ec6423b198f462'
+ '361f4649596342d07311c2590b809b85b3a918ee')
+
+prepare() {
+ cd $_pkgname-$pkgver
+
+ # https://aur.archlinux.org/packages/rxvt-unicode-patched
+ patch -p0 -i ../sgr-mouse-mode.patch
+
+ # https://aur.archlinux.org/packages/rxvt-unicode-truecolor
+ patch -p0 -i ../24-bit-color.patch
+
+ # https://aur.archlinux.org/packages/rxvt-unicode-cvs-patched-wideglyphs
+ patch -p1 -i ../enable-wide-glyphs.patch
+
+ # https://aur.archlinux.org/packages/rxvt-unicode-improve-font-rendering
+ patch -p1 -i ../improve-font-rendering.patch
+
+ # https://bugs.archlinux.org/task/67691
+ patch -p1 -i ../perl-segfault.patch
+}
+
+build() {
+ cd $_pkgname-$pkgver
+
+ # do not specify --with-terminfo (FS#46424)
+ ./configure \
+ --prefix=/usr \
+ --enable-24-bit-color \
+ --enable-256-color \
+ --enable-combining \
+ --disable-fading \
+ --disable-fallback \
+ --enable-font-styles \
+ --enable-frills \
+ --disable-iso14755 \
+ --disable-keepscrolling \
+ --enable-lastlog \
+ --enable-mousewheel \
+ --disable-next-scroll \
+ --enable-perl \
+ --disable-pixbuf \
+ --enable-pointer-blank \
+ --disable-rxvt-scroll \
+ --enable-selectionscrolling \
+ --disable-slipwheeling \
+ --disable-smart-resize \
+ --disable-startup-notification \
+ --enable-text-blink \
+ --enable-transparency \
+ --enable-unicode3 \
+ --enable-utmp \
+ --enable-wide-glyphs \
+ --enable-wtmp \
+ --enable-xft \
+ --enable-xim \
+ --disable-xterm-scroll
+ make
+}
+
+package() {
+ # install freedesktop menu
+ for _f in urxvt urxvtc urxvt-tabbed; do
+ install -Dm 644 $_f.desktop "$pkgdir/usr/share/applications/$_f.desktop"
+ done
+
+ # install perl script resize-font
+ install -Dm 644 resize-font "$pkgdir/usr/lib/urxvt/perl/resize-font"
+
+ cd $_pkgname-$pkgver
+
+ # install terminfo
+ export TERMINFO="$pkgdir/usr/share/terminfo"
+ install -dm 755 "$TERMINFO"
+
+ make DESTDIR="$pkgdir" install
+
+ # install the tabbing wrapper (requires gtk2-perl)
+ sed -i 's/\"rxvt\"/"urxvt"/' doc/rxvt-tabbed
+ install -Dm 755 doc/rxvt-tabbed "$pkgdir/usr/bin/urxvt-tabbed"
+}
diff --git a/enable-wide-glyphs.patch b/enable-wide-glyphs.patch
new file mode 100644
index 000000000000..fb639a81b8e4
--- /dev/null
+++ b/enable-wide-glyphs.patch
@@ -0,0 +1,278 @@
+diff --git a/config.h.in b/config.h.in
+index 914d6062..2e2e03f3 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -18,6 +18,9 @@
+ /* Define if you want your background to use the parent window background */
+ #undef ENABLE_TRANSPARENCY
+
++/* Define if you want to display wide glyphs */
++#undef ENABLE_WIDE_GLYPHS
++
+ /* Define if you want european extended codesets */
+ #undef ENCODING_EU
+
+diff --git a/configure b/configure
+index 3e3f78bd..b8b1591d 100755
+--- a/configure
++++ b/configure
+@@ -717,6 +717,7 @@ enable_unicode3
+ enable_combining
+ enable_xft
+ enable_font_styles
++enable_wide_glyphs
+ enable_pixbuf
+ enable_startup_notification
+ enable_transparency
+@@ -1390,6 +1391,7 @@ Optional Features:
+ --enable-combining enable composition of base and combining characters
+ --enable-xft enable xft support on systems that have it
+ --enable-font-styles enable bold and italic support
++ --enable-wide-glyphs enable displaying of wide glyphs
+ --enable-pixbuf enable integration with gdk-pixbuf for background images
+ --enable-startup-notification enable freedesktop startup notification support
+ --enable-transparency enable transparent backgrounds
+@@ -4780,6 +4782,7 @@ if test "${enable_everything+set}" = set; then :
+ support_8bitctrls=no
+ support_iso14755=no
+ support_styles=no
++ support_wide_glyphs=no
+ support_perl=no
+ codesets=
+ fi
+@@ -4808,6 +4811,7 @@ if test "${enable_everything+set}" = set; then :
+ #support_8bitctrls=yes
+ support_iso14755=yes
+ support_styles=yes
++ support_wide_glyphs=yes
+ support_perl=yes
+ codesets=all
+ fi
+@@ -4909,6 +4913,14 @@ if test "${enable_font_styles+set}" = set; then :
+ fi
+
+
++# Check whether --enable-wide-glyphs was given.
++if test "${enable_wide_glyphs+set}" = set; then :
++ enableval=$enable_wide_glyphs; if test x$enableval = xyes -o x$enableval = xno; then
++ support_wide_glyphs=$enableval
++ fi
++fi
++
++
+ # Check whether --enable-pixbuf was given.
+ if test "${enable_pixbuf+set}" = set; then :
+ enableval=$enable_pixbuf; if test x$enableval = xyes -o x$enableval = xno; then
+@@ -7733,6 +7745,11 @@ if test x$support_styles = xyes; then
+
+ $as_echo "#define ENABLE_STYLES 1" >>confdefs.h
+
++fi
++if test x$support_wide_glyphs = xyes; then
++
++$as_echo "#define ENABLE_WIDE_GLYPHS 1" >>confdefs.h
++
+ fi
+ if test x$support_iso14755 = xyes; then
+
+diff --git a/configure.ac b/configure.ac
+index 0da3b596..52ab8e4c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -132,6 +132,7 @@ AC_ARG_ENABLE(everything,
+ support_8bitctrls=no
+ support_iso14755=no
+ support_styles=no
++ support_wide_glyphs=no
+ support_perl=no
+ codesets=
+ fi
+@@ -160,6 +161,7 @@ AC_ARG_ENABLE(everything,
+ #support_8bitctrls=yes
+ support_iso14755=yes
+ support_styles=yes
++ support_wide_glyphs=yes
+ support_perl=yes
+ codesets=all
+ fi
+@@ -225,6 +227,12 @@ AC_ARG_ENABLE(font-styles,
+ support_styles=$enableval
+ fi])
+
++AC_ARG_ENABLE(wide-glyphs,
++ [ --enable-wide-glyphs enable displaying of wide glyphs],
++ [if test x$enableval = xyes -o x$enableval = xno; then
++ support_wide_glyphs=$enableval
++ fi])
++
+ AC_ARG_ENABLE(pixbuf,
+ [ --enable-pixbuf enable integration with gdk-pixbuf for background images],
+ [if test x$enableval = xyes -o x$enableval = xno; then
+@@ -648,6 +656,9 @@ fi
+ if test x$support_styles = xyes; then
+ AC_DEFINE(ENABLE_STYLES, 1, Define if you want bold and italic support)
+ fi
++if test x$support_wide_glyphs = xyes; then
++ AC_DEFINE(ENABLE_WIDE_GLYPHS, 1, Define if you want to display wide glyphs)
++fi
+ if test x$support_iso14755 = xyes; then
+ AC_DEFINE(ISO_14755, 1, Define if you want ISO 14755 extended support)
+ fi
+diff --git a/src/command.C b/src/command.C
+index 19e4fccf..75853d75 100644
+--- a/src/command.C
++++ b/src/command.C
+@@ -237,7 +237,9 @@ rxvt_term::iso14755_51 (unicode_t ch, rend_t r, int x, int y, int y2)
+ # endif
+ scr_overlay_set (11, y + 1, ch, r);
+
++#if !ENABLE_WIDE_GLYPHS
+ if (WCWIDTH (ch) >= 2)
++#endif
+ scr_overlay_set (12, y + 1, NOCHAR, r);
+ }
+
+diff --git a/src/rxvtfont.C b/src/rxvtfont.C
+index c56921c8..9d75541a 100644
+--- a/src/rxvtfont.C
++++ b/src/rxvtfont.C
+@@ -471,6 +471,7 @@ rxvt_font_default::draw (rxvt_drawable &d, int x, int y,
+ else
+ switch (t)
+ {
++ case ' ':
+ case '\t':
+ case ZERO_WIDTH_CHAR:
+ case NOCHAR:
+@@ -1026,8 +1027,10 @@ rxvt_font_x11::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &car
+
+ careful = xcs->lbearing < 0 || xcs->rbearing > prop->width * wcw;
+
++#if !ENABLE_WIDE_GLYPHS
+ if (careful && !OVERLAP_OK (w, wcw, prop))
+ return false;
++#endif
+
+ return true;
+ }
+@@ -1345,12 +1348,14 @@ rxvt_font_xft::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &car
+
+ careful = g.x > 0 || w > prop->width * wcw;
+
++#if !ENABLE_WIDE_GLYPHS
+ if (careful && !OVERLAP_OK (w, wcw, prop))
+ return false;
+
+ // this weeds out _totally_ broken fonts, or glyphs
+ if (!OVERLAP_OK (g.xOff, wcw, prop))
+ return false;
++#endif
+
+ return true;
+ }
+@@ -1395,6 +1400,10 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
+
+ ep->glyph = glyph;
+ ep->x = x_ + (cwidth - extents.xOff >> 1);
++#if ENABLE_WIDE_GLYPHS
++ /* Left-align to bounding box, do not overlap to the left. */
++ max_it(ep->x, x_);
++#endif
+ ep->y = y_ + ascent;
+
+ if (extents.xOff == 0)
+diff --git a/src/screen.C b/src/screen.C
+index 115afbf2..61681b84 100644
+--- a/src/screen.C
++++ b/src/screen.C
+@@ -936,7 +936,61 @@ rxvt_term::scr_add_lines (const wchar_t *str, int len, int minlines) NOTHROW
+ # endif
+ #endif
+
+- rend_t rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c));
++ rend_t rend;
++#if ENABLE_WIDE_GLYPHS
++ // Re-use previous font for space characters.
++ // This allows for better display of wider chars with regard to
++ // backtracking (which uses RS_SAME).
++ if (c != ' ')
++ {
++#endif
++ rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c));
++#if ENABLE_WIDE_GLYPHS
++
++ }
++ else
++ {
++ // Code taken from ENABLE_COMBINING - might get refactored.
++ line_t *linep;
++ text_t *tp;
++ rend_t *rp = NULL;
++
++ if (screen.cur.col > 0)
++ {
++ linep = line;
++ tp = line->t + screen.cur.col - 1;
++ rp = line->r + screen.cur.col - 1;
++ }
++ else if (screen.cur.row > 0
++ && ROW(screen.cur.row - 1).is_longer ())
++ {
++ linep = &ROW(screen.cur.row - 1);
++ tp = linep->t + ncol - 1;
++ rp = linep->r + ncol - 1;
++ }
++
++ if (rp)
++ {
++ // XXX: this font does not show up in iso-14755 mode for the space!?
++ if (*tp == NOCHAR)
++ {
++ while (*tp == NOCHAR && tp > linep->t)
++ tp--, rp--;
++
++ // first try to find a precomposed character
++ unicode_t n = rxvt_compose (*tp, c);
++ if (n == NOCHAR)
++ n = rxvt_composite.compose (*tp, c);
++
++ *tp = n;
++ *rp = SET_FONT (*rp, FONTSET (*rp)->find_font (*tp));
++ }
++ rend = SET_FONT (rstyle, GET_FONT(*rp));
++ }
++ else
++ rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c));
++ }
++#endif
+
+ // if the character doesn't fit into the remaining columns...
+ if (ecb_unlikely (screen.cur.col > ncol - width && ncol >= width))
+@@ -2387,7 +2441,12 @@ rxvt_term::scr_refresh () NOTHROW
+ text--, count++, xpixel -= fwidth;
+
+ // force redraw after "careful" characters to avoid pixel droppings
+- for (int i = 0; srp[col + i] & RS_Careful && col + i < ncol - 1; i++)
++ for (int i = 0; srp[col + i] & RS_Careful && col + i < ncol - 1
++#if ENABLE_WIDE_GLYPHS
++ // But not for spaces.
++ && stp[col + i + 1] != ' '
++#endif
++ ; i++)
+ drp[col + i + 1] = srp[col + i + 1] ^ RS_redraw;
+
+ // force redraw before "careful" characters to avoid pixel droppings
+diff --git a/src/xdefaults.C b/src/xdefaults.C
+index 9b47bf2c..add21eec 100644
+--- a/src/xdefaults.C
++++ b/src/xdefaults.C
+@@ -294,6 +294,9 @@ static const char optionsstring[] = "options: "
+ #if ENABLE_STYLES
+ "styles,"
+ #endif
++#if ENABLE_WIDE_GLYPHS
++ "wide-glyphs,"
++#endif
+ #if ENABLE_COMBINING
+ "combining,"
+ #endif
diff --git a/improve-font-rendering.patch b/improve-font-rendering.patch
new file mode 100644
index 000000000000..de8f9789327a
--- /dev/null
+++ b/improve-font-rendering.patch
@@ -0,0 +1,173 @@
+diff --git a/src/rxvtfont.C b/src/rxvtfont.C
+index 1914539..4c0189e 100644
+--- a/src/rxvtfont.C
++++ b/src/rxvtfont.C
+@@ -1223,92 +1223,63 @@ rxvt_font_xft::load (const rxvt_fontprop &prop, bool force_prop)
+ return false;
+
+ int ftheight = 0;
+- bool success = true;
+-
+- for (;;)
+- {
+- p = FcPatternDuplicate (match);
+- f = XftFontOpenPattern (disp, p);
+-
+- if (!f)
+- {
+- FcPatternDestroy (p);
+- success = false;
+- break;
+- }
+-
+- FT_Face face = XftLockFace (f);
+-
+- ascent = (face->size->metrics.ascender + 63) >> 6;
+- descent = (-face->size->metrics.descender + 63) >> 6;
+- height = max (ascent + descent, (face->size->metrics.height + 63) >> 6);
+- width = 0;
+-
+- bool scalable = face->face_flags & FT_FACE_FLAG_SCALABLE;
+
+- XftUnlockFace (f);
++ p = FcPatternDuplicate (match);
++ f = XftFontOpenPattern (disp, p);
+
+- int glheight = height;
++ if (!f)
++ {
++ FcPatternDestroy (p);
++ return false;
++ }
+
+- for (uint16_t *t = extent_test_chars; t < extent_test_chars + ecb_array_length (extent_test_chars); t++)
+- {
+- FcChar16 ch = *t;
++ FT_Face face = XftLockFace (f);
+
+- if (cs != CS_UNICODE
+- && ch > 0x100
+- && FROM_UNICODE (cs, ch) == NOCHAR)
+- continue;
++ ascent = f->ascent;
++ descent = f->descent;
++ height = max (ascent + descent, f->height);
++ width = 0;
+
+- // ignore characters we wouldn't use anyways
+- bool careful;
+- if (!has_char (*t, &prop, careful))
+- continue;
++ bool scalable = face->face_flags & FT_FACE_FLAG_SCALABLE;
+
+- XGlyphInfo g;
+- XftTextExtents16 (disp, f, &ch, 1, &g);
++ XftUnlockFace (f);
+
+- g.width -= g.x;
++ for (uint16_t *t = extent_test_chars; t < extent_test_chars + ecb_array_length (extent_test_chars); t++)
++ {
++ FcChar16 ch = *t;
+
+- int wcw = WCWIDTH (ch);
+- if (wcw > 0) g.width = (g.width + wcw - 1) / wcw;
++ if (cs != CS_UNICODE
++ && ch > 0x100
++ && FROM_UNICODE (cs, ch) == NOCHAR)
++ continue;
+
+- if (width < g.width ) width = g.width;
+- if (height < g.height ) height = g.height;
+- if (glheight < g.height - g.y) glheight = g.height - g.y;
+- }
++ // ignore characters we wouldn't use anyways
++ bool careful;
++ if (!has_char (*t, &prop, careful))
++ continue;
+
+- if (!width)
+- {
+- rxvt_warn ("unable to calculate font width for '%s', ignoring.\n", name);
++ XGlyphInfo g;
++ XftTextExtents16 (disp, f, &ch, 1, &g);
+
+- XftFontClose (disp, f);
+- f = 0;
++ g.width -= g.x;
+
+- success = false;
+- break;
+- }
++ int wcw = WCWIDTH (ch);
++ if (wcw > 1) g.xOff = g.xOff / wcw;
+
+- if (prop.height == rxvt_fontprop::unset
+- || (height <= prop.height && glheight <= prop.height)
+- || height <= 2
+- || !scalable)
+- break;
++ if (width < g.xOff ) width = g.xOff;
++ if (height < g.height) height = g.height;
++ }
+
+- if (ftheight)
+- {
+- // take smaller steps near the end
+- if (height > prop.height + 1) ftheight++;
+- if (height > prop.height + 2) ftheight++;
+- if (height > prop.height + 3) ftheight++;
++ bool success = true;
+
+- ftheight -= height - prop.height;
+- }
+- else
+- ftheight = prop.height - 1;
++ if (!width)
++ {
++ rxvt_warn ("unable to calculate font width for '%s', ignoring.\n", name);
+
+ XftFontClose (disp, f);
+- FcPatternDel (match, FC_PIXEL_SIZE);
+- FcPatternAddInteger (match, FC_PIXEL_SIZE, ftheight);
++ f = 0;
++
++ success = false;
+ }
+
+ FcPatternDestroy (match);
+@@ -1395,7 +1366,7 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
+
+ max_it(ep->x, x_);
+ #endif
+- ep->y = y_ + ascent;
++ ep->y = y_ + term->fbase + (term->lineSpace >> 1);
+
+ if (extents.xOff == 0)
+ ep->x = x_ + cwidth;
+diff --git a/src/screen.C b/src/screen.C
+index 9eb375a..7b3cdbf 100644
+--- a/src/screen.C
++++ b/src/screen.C
+@@ -2432,8 +2432,8 @@ rxvt_term::scr_refresh () NOTHROW
+ XSetForeground (dpy, gc, pix_colors[fore]);
+
+ XDrawLine (dpy, vt, gc,
+- xpixel, ypixel + font->ascent + 1,
+- xpixel + Width2Pixel (count) - 1, ypixel + font->ascent + 1);
++ xpixel, ypixel + Height2Pixel (1) - 1,
++ xpixel + Width2Pixel (count) - 1, ypixel + Height2Pixel (1) - 1);
+ }
+ } /* for (col....) */
+ } /* for (row....) */
+diff --git a/src/table/jis0208_1990_0.h b/src/table/jis0208_1990_0.h
+index b23378f..0febcd3 100644
+--- a/src/table/jis0208_1990_0.h
++++ b/src/table/jis0208_1990_0.h
+@@ -2241,6 +2241,7 @@ const uint16_t *jis0208_1990_0_f_i[] = {
+
+ static uint32_t cs_jis0208_1990_0_from_unicode (unicode_t unicode) {
+ if (unicode == 0x2312) return 0x225e;
++ if (unicode == 0xff5e) return 0x2141;
+ uint8_t l = unicode;
+ uint16_t h = unicode >> 8;
+ if (0x00 <= h && h <= 0xff
diff --git a/perl-segfault.patch b/perl-segfault.patch
new file mode 100644
index 000000000000..c7a4cc927cee
--- /dev/null
+++ b/perl-segfault.patch
@@ -0,0 +1,33 @@
+--- rxvt-unicode/src/rxvtperl.xs 2020/01/20 09:35:12 1.246
++++ rxvt-unicode/src/rxvtperl.xs 2020/06/30 07:31:24 1.247
+@@ -372,6 +372,9 @@
+
+ static PerlInterpreter *perl;
+
++#if 0 /* we are not a library anymore, so doing this is just not worth it */
++/*THINK/TODO: this has the side effect of, of course, not calling destructors. */
++/* but therse are not guaranteed anyway... */
+ rxvt_perl_interp::~rxvt_perl_interp ()
+ {
+ if (perl)
+@@ -381,6 +384,7 @@
+ PERL_SYS_TERM ();
+ }
+ }
++#endif
+
+ void
+ rxvt_perl_interp::init ()
+
+--- rxvt-unicode/src/rxvtperl.h 2012/06/12 10:45:53 1.28
++++ rxvt-unicode/src/rxvtperl.h 2020/06/30 07:31:24 1.29
+@@ -51,7 +51,9 @@
+ {
+ char **perl_environ;
+
++ #if 0 // see rxvtperl.xs
+ ~rxvt_perl_interp ();
++ #endif
+
+ void init ();
+ void init (rxvt_term *term);
diff --git a/resize-font b/resize-font
new file mode 100644
index 000000000000..b6b8e4f921a8
--- /dev/null
+++ b/resize-font
@@ -0,0 +1,191 @@
+# vim:ft=perl:fenc=utf-8:tw=80
+# Copyright (c) 2009-, Simon Lundström <simmel@soy.se>
+# Copyright (c) 2014 Maarten de Vries <maarten@de-vri.es>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+my @fonts = (
+ {'name' => 'font', 'code' => 710},
+ {'name' => 'boldFont', 'code' => 711},
+ {'name' => 'italicFont', 'code' => 712},
+ {'name' => 'boldItalicFont', 'code' => 713},
+);
+
+my @fixed = qw(4x6 5x7 5x8 6x9 6x10 6x12 6x13 7x13 7x14 8x13 8x16 9x15 9x18
+ 10x20 12x24);
+my $step;
+
+sub on_start {
+ my ($self) = @_;
+
+ foreach (@fonts) {
+ $_->{'default'} = $self->resource($_->{'name'});
+ }
+
+ $step = $self->x_resource("%.step") || 2;
+}
+
+sub on_init {
+ my ($self) = @_;
+ my $commands = {
+ "smaller" => "C-minus",
+ "bigger" => "C-plus",
+ "reset" => "C-equal",
+ "show" => "C-question",
+ };
+ bind_hotkeys($self, $commands);
+
+ ()
+}
+
+sub bind_hotkeys {
+ my ($self, $commands) = @_;
+
+ for (keys %$commands) {
+ my $hotkey = $$commands{$_};
+ my $hotkey_bound = $self->{'term'}->x_resource("keysym.$hotkey");
+ if (!defined($hotkey_bound) ) {
+ # Support old-style key bindings
+ if ($self->x_resource("%.$_")) {
+ $hotkey = $self->x_resource("%.$_");
+ }
+
+ # FIXME If we're bound to a keysym, don't bind the default.
+ $self->bind_action($hotkey, "%:$_") or
+ warn "unable to register '$hotkey' as hotkey for $_";
+ }
+ else {
+ if ($hotkey_bound !~ /^resize-font:/) {
+ warn "Hotkey $$commands{$_} already bound to $hotkey_bound, not ".
+ "binding to resize-font:$_ by default.";
+ }
+ }
+ }
+}
+
+sub on_action {
+ my ($self, $string) = @_;
+
+ if ($string eq "bigger") {
+ foreach (@fonts) {
+ next if not defined($_->{'default'});
+ update_font_size($self, $_, +$step);
+ }
+ }
+ elsif ($string eq "smaller") {
+ foreach (@fonts) {
+ next if not defined($_->{'default'});
+ update_font_size($self, $_, -$step);
+ }
+ }
+ elsif ($string eq "reset") {
+ foreach (@fonts) {
+ next if not defined($_->{'default'});
+ set_font($self, $_, $_->{'default'});
+ }
+ }
+ elsif ($string eq "show") {
+
+ my $term = $self->{'term'};
+ $term->{'resize-font'}{'overlay'} = {
+ ov => $term->overlay_simple(0, -1, format_font_info($self)),
+ to => urxvt::timer
+ ->new
+ ->start(urxvt::NOW + 1)
+ ->cb(sub {
+ delete $term->{'resize-font'}{'overlay'};
+ }),
+ };
+ }
+
+ ()
+}
+
+sub get_font {
+ my ($self, $name) = @_;
+ return $self->resource($name);
+}
+
+sub set_font {
+ my ($self, $font, $new) = @_;
+ $self->cmd_parse(sprintf("\33]%d;%s\007", $font->{'code'}, $new));
+}
+
+sub round {
+ return sprintf("%.0f", @_);
+}
+
+sub atleast {
+ my ($min, $val) = @_;
+ if (0 < abs $val && abs $val < $min){
+ return $val / abs($val)
+ }
+ return $val;
+}
+
+sub update_font_size {
+ my ($self, $font, $delta) = @_;
+ my $regex = qr"(?<=size=)(\d+(?:\.\d+)?)";
+ my $current = get_font($self, $font->{'name'});
+
+ my ($index) = grep { $fixed[$_] eq $current } 0..$#fixed;
+ if ($index or $index eq 0) {
+ my $inc = $delta / abs($delta);
+ $index += $inc;
+ if ($index < 0) { $index = 0; }
+ if ($index > $#fixed) { $index = $#fixed; }
+ $current = $fixed[$index];
+ }
+ elsif ($current =~ /^-/) {
+ my @font = split(/-/, $current);
+ # https://en.wikipedia.org/wiki/X_logical_font_description
+ #Pixel size
+ if ($font[7] gt 0) {
+ $delta = atleast(1, $delta);
+ my $newsize = round($font[7]+$delta);
+ $font[7] = $newsize if ($newsize > 0)
+ }
+ #Point size
+ elsif ($font[8] gt 0) {
+ $delta = atleast(1, $delta*10);
+ my $newsize = round($font[8]+$delta);
+ $font[8] = $newsize if ($newsize > 0)
+ }
+ $current = join('-', @font);
+ }
+ else {
+ my $newsize = $1+$delta if ($current =~ /$regex/);
+ $current =~ s/$regex/$newsize/ge if ($newsize > 0);
+ }
+ set_font($self, $font, $current);
+}
+
+sub format_font_info {
+ my ($self) = @_;
+
+ my $width = 0;
+ foreach (@fonts) {
+ my $length = length($_->{'name'});
+ $width = $length > $width ? $length : $width;
+ }
+ ++$width;
+
+ my $info = '';
+ foreach (@fonts) {
+ $info .= sprintf("%-${width}s %s\n", $_->{'name'} . ':',
+ get_font($self, $_->{'name'}));
+ }
+
+ return $info;
+}
diff --git a/sgr-mouse-mode.patch b/sgr-mouse-mode.patch
new file mode 100644
index 000000000000..186e8fdb74f8
--- /dev/null
+++ b/sgr-mouse-mode.patch
@@ -0,0 +1,90 @@
+--- src/command.C 2014-12-13 13:22:09.000000000 +0100
++++ src/command.C 2016-01-13 04:50:39.161862513 +0100
+@@ -1280,6 +1280,8 @@
+ int x, y;
+ int code = 32;
+
++ if (priv_modes & PrivMode_ExtMouseSgr) code = 0;
++
+ x = Pixel2Col (ev.x) + 1;
+ y = Pixel2Row (ev.y) + 1;
+
+@@ -1293,11 +1295,18 @@
+ code += 32;
+ }
+
+- if (MEvent.button == AnyButton)
++ if (!(priv_modes & PrivMode_ExtMouseSgr) && MEvent.button == AnyButton)
+ button_number = 3;
+ else
+ {
+- button_number = MEvent.button - Button1;
++ if (ev.type == MotionNotify) {
++ if (ev.state & Button1Mask) button_number = 0;
++ else if (ev.state & Button2Mask) button_number = 1;
++ else if (ev.state & Button3Mask) button_number = 2;
++ else return;
++ } else {
++ button_number = ev.button - Button1;
++ }
+ /* add 0x3D for wheel events, like xterm does */
+ if (button_number >= 3)
+ button_number += 64 - 3;
+@@ -1347,16 +1356,22 @@
+ #endif
+
+ #if ENABLE_FRILLS
++ if (priv_modes & PrivMode_ExtMouseSgr)
++ tt_printf ("\033[<%d;%d;%d%c",
++ code + button_number + key_state,
++ x,
++ y,
++ (ev.type == ButtonRelease ? 'm' : 'M'));
+- if (priv_modes & PrivMode_ExtMouseRight)
++ else if (priv_modes & PrivMode_ExtMouseRight)
+ tt_printf ("\033[%d;%d;%dM",
+ code + button_number + key_state,
+ x,
+ y);
+ else if (priv_modes & PrivMode_ExtModeMouse)
+ tt_printf ("\033[M%c%lc%lc",
+ code + button_number + key_state,
+ wint_t (32 + x),
+ wint_t (32 + y));
+ else
+ #endif
+ tt_printf ("\033[M%c%c%c",
+@@ -2908,7 +2913,7 @@
+ scr_soft_reset ();
+
+ static const int pm_h[] = { 7, 25 };
+- static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1005, 1015, 1049 };
++ static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1002, 1003, 1005, 1006, 1015, 1049 };
+
+ process_terminal_mode ('h', 0, ecb_array_length (pm_h), pm_h);
+ process_terminal_mode ('l', 0, ecb_array_length (pm_l), pm_l);
+@@ -3713,13 +3718,14 @@
+ { 1002, PrivMode_MouseBtnEvent },
+ { 1003, PrivMode_MouseAnyEvent },
+ #if ENABLE_FRILLS
+ { 1005, PrivMode_ExtModeMouse },
++ { 1006, PrivMode_ExtMouseSgr },
+ #endif
+ { 1010, PrivMode_TtyOutputInh }, // rxvt extension
+ { 1011, PrivMode_Keypress }, // rxvt extension
+ #if ENABLE_FRILLS
+ { 1015, PrivMode_ExtMouseRight }, // urxvt extension of 1005
+ #endif
+ // 1035 enable modifiers for alt, numlock NYI
+ // 1036 send ESC for meta keys NYI
+ // 1037 send DEL for keypad delete NYI
+--- src/rxvt.h 2014-12-17 16:33:08.000000000 +0100
++++ src/rxvt.h 2016-01-13 03:42:31.508911380 +0100
+@@ -644,6 +644,7 @@
+ #define PrivMode_ExtModeMouse (1UL<<23) // xterm pseudo-utf-8 hack
+ #define PrivMode_ExtMouseRight (1UL<<24) // xterm pseudo-utf-8, but works in non-utf-8-locales
+ #define PrivMode_BlinkingCursor (1UL<<25)
++#define PrivMode_ExtMouseSgr (1UL<<26) // sgr mouse extension
+
+ #define PrivMode_mouse_report (PrivMode_MouseX10|PrivMode_MouseX11|PrivMode_MouseBtnEvent|PrivMode_MouseAnyEvent)
+
diff --git a/urxvt-tabbed.desktop b/urxvt-tabbed.desktop
new file mode 100644
index 000000000000..f3efdc9b9e37
--- /dev/null
+++ b/urxvt-tabbed.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Name=urxvt (tabbed)
+Comment=An unicode capable and tabbed rxvt clone
+Exec=urxvt-tabbed
+Icon=terminal
+Terminal=false
+Type=Application
+Categories=Application;System;TerminalEmulator;
diff --git a/urxvt.desktop b/urxvt.desktop
new file mode 100644
index 000000000000..0a9baf7dfcce
--- /dev/null
+++ b/urxvt.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Name=urxvt
+Comment=An unicode capable rxvt clone
+Exec=urxvt
+Icon=terminal
+Terminal=false
+Type=Application
+Categories=Application;System;TerminalEmulator;
diff --git a/urxvtc.desktop b/urxvtc.desktop
new file mode 100644
index 000000000000..e39a418f6522
--- /dev/null
+++ b/urxvtc.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Name=urxvt (client)
+Comment=An unicode capable rxvt clone client for urxvtd
+Exec=urxvtc
+Icon=terminal
+Terminal=false
+Type=Application
+Categories=Application;System;TerminalEmulator;