Hi, a few days ago, I wanted to figure out which TERM variable I should set for my PuTTY which I use to manage Linux machines. That led me deep into the terminfo universe, a world I had no idea was so complex. I initially thought the modern solution would be to use a *-direct TERM string, since it avoids obscure color table mangling and directly supports 38:2 & 48:2 SGRs with RGB values.
However, it turned out that *-direct's are nastily incompatible with almost everything. When terminal colors were gradually evolving from 3bit, thru 4bit to 8bit, each step remained backward-compatible: for example, when a program didn't recognize 256-color environment, the first 8 or 16 colors still worked fine. But in *-direct environments, only 3bit color compatibility is preserved, and ANY program assuming today's de-facto standard (though not oficially standardized) of specifying 4bit or 8bit colors, breaks badly in *-direct environment. So I thought of a solution. Nowadays, software should recognize the RGB terminfo cap and use color numbers according to the definition provided by this cap. The problem is that the vast majority of software doesn't know about RGB; it just assumes that color numbers match the traditional 8/16/256 schemes. One workaround could be *-direct256 TERMs, but those have their own drawback: they eat first 256 (although not common) RGB colors. My approach is different. It relies on the fact that incompatible ncurses-based programs typically rely on init_pair() and not init_extended_pair(), since they don't need more than a signed int. In contrast, programs aware of RGB cap which use 24bit color values, never use init_pair() but init_extended_pair() instead. That suggests a possible compatibility layer: * Function init_pair() would evaluate RGB cap and when it defines color numbers having more than 15 bits, it translates old-style color numbers to its direct variants. * Similarly, init_color() could remember custom RGB values (instead of sending them to the terminal) and later translate old-style color numbers to these custom direct RGB values provided. And most importantly, this compatibility layer would be safe: it only activates when a program makes an invalid call to color functions. It's so because calling init_pair() when RGB cap says it's direct mode using > 15 bits is always invalid (such call can never address the entire color space), so this translation can never break anything which already assumes direct colors and will activate in 100% screwed up scenarios only, so it will always help. And there are really plenty of apps which know nothing about RGB cap and need help, because they display strange black or black-on-black colors every time they want display bright colors (8-15) or 256 colors. In general, I think there shouldn't be such an incompatibility gap as in the transition from classic (or *-256color) to *-direct TERMs, even if color numbers are not officially standardized. So I'd like to ask your opinion: Would adding such a compatibility layer be a good or bad idea? Or alternatively, several other solutions come to my mind - for example, make direct color space backwards compatible by defining it as not first 8, but first 256 colors remaining old-style, because most apps don't need them anyway (so just like xterm-direct256 so far), and for those apps which really need them, reserve e.g. 25th bit which - when set - will activate really full RGB palette including these 256 nearly-black colors. This could be implemented to *-direct TERMs. Maybe even cleaner solution? Best regards, Jakub
