Reading the RGB values of the console color palett

2019-02-24 06:24发布

问题:

Meat

In C or C++ is there any way to read the color palette RGB values directly? Especially interesting is the extended color space used by xterm (and others) to define up to 256 terminal colors.

Potatoes

The case in point is that I want to define my own colors (using ANSI escape sequences, like \e]4;3;rgb:cc/78/33\e\\, or directly in c) but I need to save the users colors before I redefine them (in the unlikely event that they have already redefined their colors) so that I can restore them when my program finishes. Clobbering user setting is not nice.

Right now I'm aiming to use ANSI escape sequences to do this the client way. But since I cant find how you get the colors out I'm starting to look into doing this in c or c++ instead.

The solution will be written as a ruby gem with a native extension (basically embedded c or c++ code) and I'll aim to get a cross platform solution, even though the main target is OS X and secondly Linux environments...

Sause

From my initial experiments I have gotten to the point where I can define whatever colors I want for a code point in the color palette. I can also easily restore the default system colors (since they are ANSI standard). I have looked high and low for a way to do this in ANSI escape codes, but found none. I figure that this is kept in memory somewhere and if there is any way to find where, reading the colors should be easy...

Dessert

To sum up the information in the comments so far:

It looks like the only way to do this consistently is to print a screen of █ characters in the different colors and grabbing the colors off of that. Since this project is supposed to be cross platform over the three major OS's and since Linux currently have 3 display managers in user on on they way into use and windows has two (7 and 8) I can only imagine the hours and hours of fun that would be :)

So my "solution"™ is to just clobber the users colors (if they had anything other than the system defaults ... which, let's face it is pretty uncommon). I will provide a settings file where the user can tell the plugin what colors should be restored if they are not happy with the system defaults. Pragmatic and boring, but it get's me going on this again :)

回答1:

[Edit 1] sorry this not leads to solution but for others i added DAC palette IO access

look the old legacy EGA/VGA references ...

  • you can access palette via I/O
  • i think it was ports 0x03C8, 0x03C9 hex.
  • of course in modern OS you have no access to it
  • so try it in DOS-BOX or what ever and save the original palette values, they should be the same.

for direct access try this:

BYTE r,g,b,c=5; // R,G,B values are 6 bit only !!!
out 0x3C8,c;    // set color index to work with <0,255>
in  r,0x3C9;    // read color pallete for color c
in  g,0x3C9;    // not sure if it should be r,g,b 
in  b,0x3C9;    // or b,g,r ... i did not use it for too many years
out 0x3C8,c;    // set color index to work with <0,255>
out 0x3C9,r;    // write color pallete for color c
out 0x3C9,g;
out 0x3C9,b;

C/C++ do not have in,out operations so use this:

BYTE i,o;       // this must be local !!!
WORD port;      // this must be local !!!
asm {
    mov dx,port // in i,port
    in al,dx
    mov o,al

    mov dx,port // out port,o
    mov al,o
    out dx,al
    }