[PATCH] 256 color support for libvte (and so gnome-terminal)
- From: Daniel Brockman <daniel brockman se>
- To: desktop-devel-list gnome org
- Cc: "nalin redhat com" <Nalin sea gmane org>
- Subject: [PATCH] 256 color support for libvte (and so gnome-terminal)
- Date: Mon, 27 Feb 2006 07:57:11 +0100
[CCing Nalin because it says so in HACKING, though his
last change to the source was done over a year ago.]
Hi list,
I wasn't sure where to send this, but this list seems
close enough. Yell at me if it isn't.
Okay, so I implemented 256 color support for libvte.
This is nice if you run Emacs in gnome-terminal and want to
use fancy color themes. Maybe you can think of other
cool applications. Personally I'd like to see an aalib-like
library utilizing the 256 colors.
The current implementation doesn't support dynamically
changing the palette, mostly because I don't know of any
programs that use that feature --- Emacs doesn't. :-(
The patch doesn't break API compatibility and shouldn't
break ABI compatibility unless someone is poking around in
the `vte_charcell' struct (declared in `vte-private.h').
The one thing I'm uncertain about is this change:
(struct vte_charcell): Increase size of `fore' and `back' fields
from 5 to 9 bits. Decrease size of `columns' field from 11 to 3.
I don't know if and why the `columns' field needed to be 11
bits wide before. Raise your hand if you have a character
that occupies two thousand horizontal terminal cells.
My guess is that three bits will do fine, but chances are
I'm missing something. --- Nalin, are you listening? :-)
(I also didn't know what to do about the termcap entries,
but maybe that doesn't matter as much.)
Anyway, to test the feature, try this:
./configure --enable-256-colors && make install
gnome-terminal
TERM=xterm-256color emacs -nw -f list-colors-display
If your Emacs doesn't support 256 colors, find yourself a
copy of the `256colors2.pl' script that ships with XTerm.
(Maybe it should also be shipped with libvte now?)
Here's the ChangeLog entry:
2006-02-27 Daniel Brockman <daniel brockman se>
* termcaps/xterm.baseline: Add entries for `xterm-256color',
`xterm-88color' and `xterm-16color' taken from the XTerm tarball.
* src/vteseq.c (vte_sequence_handler_character_attributes)
[VTE_ENABLE_256_COLORS]: Interpret the `38;5;foo' and `48;5;foo'
sequences used to pick colors from the 256-entry palette.
Disable interpretation of the `38' sequence used to enable
underlining and setting the foreground color to its default value.
* src/vte.c (vte_terminal_set_colors) [VTE_ENABLE_256_COLORS]:
Allow `palette_size' to equal 256.
(vte_terminal_set_colors): Fix cases in switch to use
`VTE_COLOR_PLAIN_OFFSET' instead of hardcoding `0',
`VTE_COLOR_BRIGHT_OFFSET' instead of hardcoding `8', and
`VTE_COLOR_DIM_OFFSET' instead of hardcoding `16'.
[VTE_ENABLE_256_COLORS]: Set up the standard color cube and
grayscale ramp palette entries.
* src/vte-private.h [VTE_ENABLE_256_COLORS]
(VTE_COLOR_DIM_OFFSET): Change from 16 to 256.
(struct vte_charcell): Increase size of `fore' and `back' fields
from 5 to 9 bits. Decrease size of `columns' field from 11 to 3.
* src/vte-private.h (VTE_COLOR_DIM_LAST): New macro.
(VTE_DEF_FG, VTE_DEF_BG, VTE_BOLD_FG, VTE_DIM_FG)
(VTE_DEF_HL, VTE_CUR_BG): Depend on `VTE_COLOR_DIM_LAST'.
* configure.in (--enable-256-colors): New option. Define macro
`VTE_ENABLE_256_COLORS' and set conditional `ENABLE_256_COLORS'.
and... here's the patch:
diff -cr vte-0.11.18/ vte-0.11.18-256-colors/
diff -cr vte-0.11.18/configure.in vte-0.11.18-256-colors/configure.in
*** vte-0.11.18/configure.in 2006-02-11 20:53:52.000000000 +0100
--- vte-0.11.18-256-colors/configure.in 2006-02-27 07:09:57.000000000 +0100
***************
*** 58,63 ****
--- 58,76 ----
VTE_DEFAULT_EMULATION=$emulation
AC_SUBST(VTE_DEFAULT_EMULATION)
+ AC_ARG_ENABLE([256-colors],
+ AS_HELP_STRING([--enable-256-colors], [enable support for 256 colors]),
+ [enable_256_colors=yes],
+ [enable_256_colors=no])
+ AM_CONDITIONAL([ENABLE_256_COLORS], [test "$enable_256_colors" != no])
+ AC_MSG_CHECKING([whether you want support for 256 colors])
+ if test "$enable_256_colors" != no ; then
+ AC_DEFINE([VTE_ENABLE_256_COLORS], 1, [enable support for 256 colors])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+
# Use Xft2 if Pango has Xft2 support and it isn't disabled.
if test "$have_x" = yes ; then
AC_ARG_WITH(xft2,[AS_HELP_STRING(--with-xft2,enable drawing using Xft2)],with_xft2=$withval,with_xft2=yes)
diff -cr vte-0.11.18/src/vte.c vte-0.11.18-256-colors/src/vte.c
*** vte-0.11.18/src/vte.c 2006-02-11 19:24:52.000000000 +0100
--- vte-0.11.18-256-colors/src/vte.c 2006-02-27 06:47:06.000000000 +0100
***************
*** 2012,2017 ****
--- 2012,2020 ----
g_return_if_fail((palette_size == 0) ||
(palette_size == 8) ||
(palette_size == 16) ||
+ #ifdef VTE_ENABLE_256_COLORS
+ (palette_size == 256) ||
+ #endif
(palette_size == G_N_ELEMENTS(terminal->pvt->palette)));
/* Accept NULL as the default foreground and background colors if we
***************
*** 2069,2113 ****
color.blue = 0x0000;
color.green = 0x0000;
break;
! case 0 + 0:
! case 0 + 1:
! case 0 + 2:
! case 0 + 3:
! case 0 + 4:
! case 0 + 5:
! case 0 + 6:
! case 0 + 7:
! case 8 + 0:
! case 8 + 1:
! case 8 + 2:
! case 8 + 3:
! case 8 + 4:
! case 8 + 5:
! case 8 + 6:
! case 8 + 7:
! color.blue = (i & 4) ? 0xc000 : 0;
color.green = (i & 2) ? 0xc000 : 0;
! color.red = (i & 1) ? 0xc000 : 0;
! if (i > 8) {
! color.blue += 0x3fff;
! color.green += 0x3fff;
! color.red += 0x3fff;
! }
! break;
! case 16 + 0:
! case 16 + 1:
! case 16 + 2:
! case 16 + 3:
! case 16 + 4:
! case 16 + 5:
! case 16 + 6:
! case 16 + 7:
! color.blue = (i & 4) ? 0x8000 : 0;
color.green = (i & 2) ? 0x8000 : 0;
! color.red = (i & 1) ? 0x8000 : 0;
break;
default:
! g_assert_not_reached();
break;
}
--- 2072,2159 ----
color.blue = 0x0000;
color.green = 0x0000;
break;
! case VTE_COLOR_PLAIN_OFFSET + 0:
! case VTE_COLOR_PLAIN_OFFSET + 1:
! case VTE_COLOR_PLAIN_OFFSET + 2:
! case VTE_COLOR_PLAIN_OFFSET + 3:
! case VTE_COLOR_PLAIN_OFFSET + 4:
! case VTE_COLOR_PLAIN_OFFSET + 5:
! case VTE_COLOR_PLAIN_OFFSET + 6:
! case VTE_COLOR_PLAIN_OFFSET + 7:
! color.blue = (i & 4) ? 0xc000 : 0;
color.green = (i & 2) ? 0xc000 : 0;
! color.red = (i & 1) ? 0xc000 : 0;
! break;
! case VTE_COLOR_BRIGHT_OFFSET + 0:
! case VTE_COLOR_BRIGHT_OFFSET + 1:
! case VTE_COLOR_BRIGHT_OFFSET + 2:
! case VTE_COLOR_BRIGHT_OFFSET + 3:
! case VTE_COLOR_BRIGHT_OFFSET + 4:
! case VTE_COLOR_BRIGHT_OFFSET + 5:
! case VTE_COLOR_BRIGHT_OFFSET + 6:
! case VTE_COLOR_BRIGHT_OFFSET + 7:
! color.blue = (i & 4) ? 0xffff : 0;
! color.green = (i & 2) ? 0xffff : 0;
! color.red = (i & 1) ? 0xffff : 0;
! break;
! case VTE_COLOR_DIM_OFFSET + 0:
! case VTE_COLOR_DIM_OFFSET + 1:
! case VTE_COLOR_DIM_OFFSET + 2:
! case VTE_COLOR_DIM_OFFSET + 3:
! case VTE_COLOR_DIM_OFFSET + 4:
! case VTE_COLOR_DIM_OFFSET + 5:
! case VTE_COLOR_DIM_OFFSET + 6:
! case VTE_COLOR_DIM_OFFSET + 7:
! color.blue = (i & 4) ? 0x8000 : 0;
color.green = (i & 2) ? 0x8000 : 0;
! color.red = (i & 1) ? 0x8000 : 0;
break;
default:
! #ifdef VTE_ENABLE_256_COLORS
! if (i >= 16 && i <= 231) {
! /* The standard color cube is defined by the
! * following formula
! *
! * i = 16 + 36r + 6g + b,
! *
! * where the color components `r', `g' and `b'
! * range from zero to five and map into the
! * normal colorspace according to these rules:
! *
! * byte(c) = 0 if c = 0
! * byte(c) = c * 40 + 55 otherwise
! *
! */
! guint16 jumble = (guint16) i - 16;
! guint8 r, g, b;
!
! b = (jumble % 6) * 40; jumble /= 6;
! if (b != 0) b += 55;
!
! g = (jumble % 6) * 40; jumble /= 6;
! if (g != 0) g += 55;
!
! r = (jumble % 6) * 40; jumble /= 6;
! if (r != 0) r += 55;
!
! g_assert (jumble == 0);
!
! /* The GDK components, of course, are _two_
! * bytes each, so we have to scale them up. */
! color.red = (guint16) r << 8;
! color.green = (guint16) g << 8;
! color.blue = (guint16) b << 8;
! }
! else if (i >= 232 && i <= 255)
! /* The standard grayscale ramp consists of
! * fourteen levels of gray, excluding both
! * totally black and totally white. */
! color.blue = color.green = color.red =
! (((guint16) i - 232) * 10 + 8) << 8;
! else
! #endif
! g_assert_not_reached();
!
break;
}
diff -cr vte-0.11.18/src/vte-private.h vte-0.11.18-256-colors/src/vte-private.h
*** vte-0.11.18/src/vte-private.h 2006-02-10 10:30:23.000000000 +0100
--- vte-0.11.18-256-colors/src/vte-private.h 2006-02-27 06:36:46.000000000 +0100
***************
*** 59,71 ****
#define VTE_COLOR_SET_SIZE 8
#define VTE_COLOR_PLAIN_OFFSET 0
#define VTE_COLOR_BRIGHT_OFFSET 8
! #define VTE_COLOR_DIM_OFFSET 16
! #define VTE_DEF_FG 24
! #define VTE_DEF_BG 25
! #define VTE_BOLD_FG 26
! #define VTE_DIM_FG 27
! #define VTE_DEF_HL 28
! #define VTE_CUR_BG 29
#define VTE_SATURATION_MAX 10000
#define VTE_SCROLLBACK_MIN 100
#define VTE_DEFAULT_CURSOR GDK_XTERM
--- 59,79 ----
#define VTE_COLOR_SET_SIZE 8
#define VTE_COLOR_PLAIN_OFFSET 0
#define VTE_COLOR_BRIGHT_OFFSET 8
! #ifdef VTE_ENABLE_256_COLORS
! /* I'm sorry to put the dim colors so far away from their plain and
! bright counterparts, but 256-color-aware applications expect to
! find the color cube at color index 16. --- Daniel Brockman */
! # define VTE_COLOR_DIM_OFFSET 256
! #else
! # define VTE_COLOR_DIM_OFFSET 16
! #endif
! #define VTE_COLOR_DIM_LAST (VTE_COLOR_DIM_OFFSET + 7)
! #define VTE_DEF_FG (VTE_COLOR_DIM_LAST + 1)
! #define VTE_DEF_BG (VTE_COLOR_DIM_LAST + 2)
! #define VTE_BOLD_FG (VTE_COLOR_DIM_LAST + 3)
! #define VTE_DIM_FG (VTE_COLOR_DIM_LAST + 4)
! #define VTE_DEF_HL (VTE_COLOR_DIM_LAST + 5)
! #define VTE_CUR_BG (VTE_COLOR_DIM_LAST + 6)
#define VTE_SATURATION_MAX 10000
#define VTE_SCROLLBACK_MIN 100
#define VTE_DEFAULT_CURSOR GDK_XTERM
***************
*** 88,100 ****
* includes any supported visible attributes. */
struct vte_charcell {
gunichar c; /* The Unicode character. */
! guint32 columns: 11; /* Number of visible columns (as determined
! by g_unicode_iswide(c)). Use as many bits
! as possible without making this structure
! grow any larger. */
guint32 fragment: 1; /* The nth fragment of a wide character. */
guint32 fore: 5; /* Indices in the color palette for the */
guint32 back: 5; /* foreground and background of the cell. */
guint32 standout: 1; /* Single-bit attributes. */
guint32 underline: 1;
guint32 strikethrough: 1;
--- 96,126 ----
* includes any supported visible attributes. */
struct vte_charcell {
gunichar c; /* The Unicode character. */
!
! /* Use as many leftover bits as possible for the `columns' field. */
! #ifdef VTE_ENABLE_256_COLORS
! /* I don't understand why this field should be larger than a
! * single bit (which is enough if you just want to store the
! * result of `g_unicode_iswide'), so I stripped it down to
! * make room for the 256 colors data. --- Daniel Brockman */
! /* XXX: Is this a bad idea? */
! guint32 columns: 3; /* Number of visible columns (as determined
! by g_unicode_iswide(c)). */
! #else
! guint32 columns: 11; /* Number of visible columns (as determined
! by g_unicode_iswide(c)). */
! #endif
!
guint32 fragment: 1; /* The nth fragment of a wide character. */
+
+ #ifdef VTE_ENABLE_256_COLORS
+ guint32 fore: 9; /* Indices in the color palette for the */
+ guint32 back: 9; /* foreground and background of the cell. */
+ #else
guint32 fore: 5; /* Indices in the color palette for the */
guint32 back: 5; /* foreground and background of the cell. */
+ #endif
+
guint32 standout: 1; /* Single-bit attributes. */
guint32 underline: 1;
guint32 strikethrough: 1;
diff -cr vte-0.11.18/src/vteseq.c vte-0.11.18-256-colors/src/vteseq.c
*** vte-0.11.18/src/vteseq.c 2006-02-10 10:25:56.000000000 +0100
--- vte-0.11.18-256-colors/src/vteseq.c 2006-02-25 11:44:34.000000000 +0100
***************
*** 2750,2755 ****
--- 2750,2789 ----
continue;
}
param = g_value_get_long(value);
+
+ #ifdef VTE_ENABLE_256_COLORS
+ /*
+ * XTerm understands the following sequences:
+ *
+ * `38;5;foo' --- set foreground color to `foo'.
+ * `48;5;foo' --- set background color to `foo'.
+ */
+ if ((param == 38 || param == 48)
+ && params->n_values - i >= 2) {
+ GValue *value1 = g_value_array_get_nth(params, i + 1);
+ GValue *value2 = g_value_array_get_nth(params, i + 2);
+
+ if (G_VALUE_HOLDS_LONG(value1)
+ && g_value_get_long(value1) == 5
+ && G_VALUE_HOLDS_LONG(value2)) {
+ glong color = g_value_get_long(value2);
+
+ if (color >= 0 && color <= 255) {
+ if (param == 38)
+ terminal->pvt->screen->
+ defaults.fore = color;
+ else
+ terminal->pvt->screen->
+ defaults.back = color;
+
+ /* The loop increment adds one,
+ so we only have to add two. */
+ i += 2; continue;
+ }
+ }
+ }
+ #endif
+
switch (param) {
case 0:
_vte_terminal_set_default_attributes(terminal);
***************
*** 2807,2817 ****
--- 2841,2856 ----
case 37:
terminal->pvt->screen->defaults.fore = param - 30;
break;
+ #ifndef VTE_ENABLE_256_COLORS
+ /* I at least don't see this making much sense
+ * alongside the `38;5;foo' sequence used for 256
+ * color support. --- Daniel Brockman */
case 38:
/* default foreground, underscore */
terminal->pvt->screen->defaults.fore = VTE_DEF_FG;
terminal->pvt->screen->defaults.underline = 1;
break;
+ #endif
case 39:
/* default foreground, no underscore */
terminal->pvt->screen->defaults.fore = VTE_DEF_FG;
diff -cr vte-0.11.18/termcaps/xterm.baseline vte-0.11.18-256-colors/termcaps/xterm.baseline
*** vte-0.11.18/termcaps/xterm.baseline 2002-11-25 21:39:20.000000000 +0100
--- vte-0.11.18-256-colors/termcaps/xterm.baseline 2006-02-27 05:59:47.000000000 +0100
***************
*** 28,33 ****
--- 28,44 ----
xterm-color|generic "ANSI" color xterm (X Window System):\
:Co#8:NC@:pa#64:\
:AB=\E[4%dm:AF=\E[3%dm:op=\E[m:tc=xterm-r6:
+ # These aliases are for compatibility with the terminfo; termcap cannot provide
+ # the extra features such as color initialization, but termcap applications
+ # still want the names. Note that AF/AB really should be Sf/Sb, but there are
+ # applications which expect the former. The terminfo contains both strings.
+ xterm-16color|xterm alias:\
+ :tc=xterm-new:
+ xterm-88color|xterm alias:\
+ :Co#88:pa#7744:tc=xterm-256color:
+ xterm-256color|xterm alias:\
+ :Co#256:pa#32767:\
+ :AB=\E[48;5;%dm:AF=\E[38;5;%dm:tc=xterm-redhat:
# This is the only entry which you should have to customize, since "xterm"
# is widely used for a variety of incompatible terminal emulations including
# color_xterm and rxvt.
Diff finished. Mon Feb 27 07:10:42 2006
Here's another totally unrelated tiny patch:
2006-02-27 Daniel Brockman <daniel brockman se>
* configure.in: Add check for `IT_PROG_INTLTOOL'.
diff -c old/vte-0.11.18-256-colors/configure.in new/vte-0.11.18-256-colors/configure.in
*** old/vte-0.11.18-256-colors/configure.in 2006-02-27 05:57:34.000000000 +0100
--- new/vte-0.11.18-256-colors/configure.in 2006-02-27 07:14:43.000000000 +0100
***************
*** 12,17 ****
--- 12,18 ----
AM_MAINTAINER_MODE
AM_PROG_LIBTOOL
+ IT_PROG_INTLTOOL
ALL_LINGUAS="ang am ar az be bg bn bs ca cs cy da de
el en_CA en_GB es et eu fa fi fr ga gl gu he hi hr hu
id is it ja ka ko ku ky li lt lv mi mk ml mn ms nb ne
Diff finished. Mon Feb 27 07:19:15 2006
Regards,
--
Daniel Brockman <daniel brockman se>
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]