2

I am recently working on a game project using the curses library, and I used color-related functions like start_color(), init_color() and init_pair(). The color works well in my project, but once its used, the colors in other TUI applications like vim will go wrong.

For example: When I first edit some part of my code, it is like this:

first image

This is vim with colorscheme slate, and it looks good.

However, when I run my code and exit and edit the code again, it become something like this:

second image

Note: I did not change anything when I did this, and I thought that it is because I have changed the color definitions when I run my code. Also, if I use other functions, it will also go wrong, like:

Third

But the original one should look like this: Fourth

I wanna know why this is happening, I thought there may be some ending functions of color I am not using, just like initscr() and endwin(), there should be another one for start_color(). Can anyone tell me why? Thanks a lot.

Chromium
  • 517
  • 1
  • 6
  • 21

1 Answers1

2

For terminals that support it, init_color() has a different effect than the other color-related functions in ncurses. It changes the palette of colors used by any application:

If a terminal is capable of redefining colors, the programmer can use the routine init_color to change the definition of a color.

The palette is stored in the terminal emulator; every application which uses colors will use the same set of colors unless it modifies the palette via escape sequences. Those escape sequences are documented in XTerm Control Sequences.

ncurses has no way to determine what the palette of colors is at the start; it cannot restore the palette to its initial state on exit (e.g., in endwin). Unlike the color pair (default 0), there is no predefined palette used by all terminals which can produce color. To see this, compare the initc capability for these variations:

   initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
   initc=\E]P%p1%x%p2%{255}%*%{1000}%/%02x%p3%{255}%*%{1000}%/%02x%p4%{255}%*%{1000}%/%02x,

Because the only information that ncurses has is how to change the color, it cannot set the palette back to its original state on exit.

Further reading:

Community
  • 1
  • 1
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • Thanks for the answer. But it also changes the results of the `ls`command, which is not in curses mode. Is that a *side-effect* of the change of the color palette? – Chromium Mar 17 '16 at 07:04
  • yes: "It changes the palette of colors used by **any** application" – Thomas Dickey Mar 17 '16 at 07:06
  • Is there any way to solve this? Can I reset the color palette so that it becomes normal when the program is about to exit? – Chromium Mar 17 '16 at 07:08
  • No: you could set the palette to some *known* state, but there is no standard method for determining what is *normal*. – Thomas Dickey Mar 17 '16 at 07:14
  • 1
    Even no standard, saving the color states at first using `color_content()` and restore in the end maybe a good way. – Chromium Mar 17 '16 at 07:20
  • `color_content` tells the programmer only what ncurses *knows*. ncurses cannot ask the terminal what the terminal has been set to, before ncurses starts. – Thomas Dickey Mar 17 '16 at 07:22
  • May I know how it changes the palette of other application, though it is a *hard* question? – Chromium Mar 17 '16 at 09:40
  • I don't know the back-works of curses, but it seems like the terminal is providing a colour palette and the curses is using that directly. Therefore when something changes in the palette it will change in rest of the terminal *until* the terminal is not closed. – Brambor Jun 07 '19 at 18:11
  • @ThomasDickey No. If you use the extension `color_content()` before you change it you most certainly can restore it to the previous state. I suspected all along I would have to do it this way and after coming here and seeing nothing but 'can't be done' I went with my gut instinct. It restored it to where it was before changing it. But it is also not completely portable since it is an extension, that function. – Pryftan Dec 04 '19 at 17:48
  • [color_content](https://pubs.opengroup.org/onlinepubs/7908799/xcurses/color_content.html) is standard. – Thomas Dickey Dec 04 '19 at 21:32
  • @ThomasDickey You know what. I looked at the manpage again and you're right. It was my usual tired head and the way it was laid out that made me think otherwise. But you still can restore the colour back. I had an answer demonstrating it but since people thought it'd be good to just down-vote without bothering saying anything I deleted it. – Pryftan Dec 14 '19 at 20:31