Mail Archives: djgpp-workers/2000/11/20/11:23:48
With Emacs 21 finally in pretest, I feel it's time to tell this story.
I guess it will mainly amuse Morten, but I thought others will want to
hear it as well, because this is one of those cases where DJGPP gives
something significant back to the GNU project.
As you might or might not know, Emacs 21 supports colors on a Unix
character terminal. ``Big deal'', you might think; however, GNU/Linux
users were asking for this for years, and didn't get it till now.
Evidently, many users don't want, or cannot afford, running X; go
figure.
Of course, the DJGPP port of Emacs supports colors on a character
terminal for more than 6 years, thanks to Morten. But when I first
looked at the development sources of Emacs 21, a year and a half ago,
I was extremely disappointed, because none of the lessons learned from
the DJGPP port were used for the Unix tty color support.
This might require a few words of explanation, for those who are not
privy to Emacs internals.
Emacs support for colors evolved from the X Window System. Many Lisp
packages use color names defined by X and assume the availability of
certain functions that look up colors, convert them to pixel values,
etc. For example, the default color for displaying the comments is
"FireBrick", the color for strings is "RosyBrown", etc.
Such X-style color definitions are used in many packages, both bundled
with Emacs and those which are not. Some packages even use the
standard X "#RRGGBB" specification. What do you expect DJGPP color
support functions to do when they are passed such color
specifications?
To solve this problem in a way that would avoid the need to add
DOS-specific color definitions everywhere, the DJGPP port of Emacs
used a transparent color translation scheme, whereby each X color name
was translated to one of the 16 basic colors supported by the
text-mode VGA display. This transparent translation began as simple
association list, like this:
( ...
("FireBrick" . "red")
("RosyBrown" . "brown")
...
)
where each X color was looked up, and the corresponding VGA color was
used instead. Over the years, this translation evolved into more
sophisticated scheme (e.g., support for "#RRGGBB" was added). In
addition, a set of function was introduced to mimic the X
color-related functions in a reasonable manner (report the supported
colors etc.).
This approach allowed to stop worrying about any changes in mainstream
Emacs code that used X colors, because the translation layer would
automatically map any X color into one of the PC colors, and everybody
will be happy.
However, the new tty color support, as originally written, didn't take
that road. Instead, it supported only the basic tty colors, and left
it to the applications (Lisp packages) to deal with defininig special
colors for the tty case.
When I saw this, I tried to explain to Richard Stallman and to Gerd
Moellmann, the new Emacs head maintainer and the guy who wrote the tty
color support, that it was simply wrong, because it meant that
maintainers of all Lisp packages that support colors will need to know
about the tty case and make sure the colors are set correctly. This
would be a terrible burden, and a constant cause for bugs (e.g., what
if some terminals support more colors than others? what if an
unsupported color name would inadvertently be passed to the tty color
support functions?).
Originally, my arguments were not accepted, perhaps because I couldn't
explain very well what problems did I envision. It took a coincidence
to convince them: a couple of weeks later, Richard Stallman tried to
use on a tty the paren.el package, which causes the matching parentheses
to stand out in color. paren.el defines the background color of the
matching parenthesis to be "turquoise", which of course isn't defined
on the tty. The tty color support was written so that undefined
colors were silently ignored (the alternative would be to throw an
error, which is much worse). So the matching paren was not highlighted,
Richard thought that paren.el was broken, and spent some time debugging
that...
After that, there were no more arguments about this issue. Richard
immediately asked me to generalize the MS-DOS color support so that it
works for tty's as well, and the rest, as they say, is history ;-)
Btw, the generalized tty support I wrote introduces a couple of cool
ideas that were not present in the DJGPP-specific code. For example,
one problem I needed to solve was that many X colors mapped to
lightgray or darkgray (because the mapping tries to find a defined
color which is the closest to the X color in the RGB space, and
there are too few defined colors to work with). This caused an
unpleasant effect whereby a color such as "lightsalmon1" would map to
lightgray. An interested reader can find the solution in the file
lisp/term/tty-colors.el in the Emacs 21 distribution (available via
anon ftp from alpha.gnu.org, in the gnu/emacs directory).
So this is the case where experience gathered by DJGPP helped solve a
complex problem in the mainstream GNU package. Let no one say that
DJGPP is an unimportant toy project for a dying ``operating system''!
- Raw text -