Date: Mon, 20 Nov 2000 18:22:14 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: djgpp-workers AT delorie DOT com cc: Morten Welinder Subject: DJGPP and Emacs 21 Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com 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''!