Thread: Ncurses restore color on endwin()

  1. #1
    Registered User
    Join Date
    Dec 2011
    Posts
    51

    Ncurses restore color on endwin()

    My terminal colors are not restored to their original values in the Nothing Fancy File Manager I am working on. In order to troubleshoot this, I wrote the following:

    Code:
    #include <stdio.h>
    #include <ncurses.h>
    
    #define MAXCOLOR 15
    
    struct textColor{
        short red;
        short green;
        short blue;
    }tc[MAXCOLOR], tci[MAXCOLOR];
    
    WINDOW *w;
    
    void set_colors(void)
    {
        int i;
        initscr();
        start_color();
        use_default_colors();
        w=newwin(MAXCOLOR, 150, 0, 0);
        for(i=1; i<MAXCOLOR;i++)//store current colors
        {
            color_content(i, &tci[i].red, &tci[i].green, &tci[i].blue);
            init_color(i, tci[i].red, tci[i].green, tci[i].blue);
            init_pair(i, i, COLOR_BLACK);
            wattrset(w, COLOR_PAIR(i));
            wprintw(w, "COLOR %hd\n",i);
            wrefresh(w);
        }
        getchar();
        for(i=1; i<MAXCOLOR; i++)//Attempt to restore colors
        {
            init_color(i, tci[i].red, tci[i].green, tci[i].blue);
            wattrset(w, COLOR_PAIR(i));
            wprintw(w, "COLOR %hd\n",i);
            wrefresh(w);
        }
        getchar();
        endwin();
    }
    
    int main(void)
    {
        set_colors();
        return 0;
    }
    A loop to try to get the current colors, apply those colors (they should be the same), then a second loop just to re-read the stored colors. This is not working. Even the \n in the second loop is not working. In fact The enter key is not even working properly when the program finishes. I have to reboot. Even it I put an ini_pair in the second loop, no luck. I am rather puzzled.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Instead of rebooting your entire machine, type "reset" into the terminal.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Jun 2009
    Posts
    4

    init_color, etc.

    Quote Originally Posted by mariostg View Post
    My terminal colors are not restored to their original values in the Nothing Fancy File Manager I am working on. In order to troubleshoot this, I wrote the following:
    It sounds as if you're using Linux console.
    ncurses has no way of knowing what the original colors were, so it cannot restore the colors.

    By the way, Linux console has only 8 colors - setting MAXCOLOR to 15 (rather than using the COLORS value from the terminal database) can make things more puzzling.
    Last edited by dickey; 08-03-2012 at 04:44 PM. Reason: typo

  4. #4
    Registered User
    Join Date
    Jun 2009
    Posts
    4
    Quote Originally Posted by brewbuck View Post
    Instead of rebooting your entire machine, type "reset" into the terminal.
    yes - that should work, since the reset (for Linux console) will reset the palette using \E]R

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Code:
    #include <ncurses.h>
     
    const short colors[] = 
    {
        COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
        COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
    };
    
    const int num_colors = sizeof(colors) / sizeof(*colors);
     
    void set_colors(void)
    {
        int i;
        initscr();
        start_color();
        use_default_colors();
        for (i = 0; i < num_colors; ++i)
        {
            init_pair(i, colors[i], COLOR_BLACK);
            attron(COLOR_PAIR(i));
            printw("COLOR %hd\n", i);
        }
        refresh();
        standend();
        getch();
        endwin();
    }
     
    int main(void)
    {
        set_colors();
        return 0;
    }
    Notice:
    - not mixing stdio functions with ncurses functions
    - the difference between attrset() and attron()

    Does that leave your terminal messed up?

    gg

  6. #6
    Registered User
    Join Date
    Dec 2011
    Posts
    51
    @brewbuck
    Typing reset at the terminal does not do anything. Also after the program exis, if I start Firefox, it does not get the focus automatically. it stays behind. Then when I type in an address and hit enter, Firefox quit.

    @dicky
    Indeed I used linux, that is why i posted on this sub-forum. I use Arch with Openbox.

    @Codeplug
    I think I read about stdio and ncurses sometime ago but did not pay too much attention. Have to check further.
    attron and attrset, I also read but did not think it could have much impact. I will check this out too.
    Other than few colors, terminal is ok.

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Other than few colors, terminal is ok.
    You should get similar results once all the bugs are fixed.

    gg

  8. #8
    Registered User
    Join Date
    Dec 2011
    Posts
    51
    @Codeplug, I took your snippet, which works fine, and expended a bit to include init_color (lines 27 to 36). And this is when the colors of the terminal gets screwed up. The terminal supports 256 colors but when the program terminates, the colors of the bash prompt are changed and the colors of file listing, I use dircolors, are affected.

    Code:
    #include <ncurses.h>
      
    const short colors[] =
    {
        COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
        COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
    };
     
    const int num_colors = sizeof(colors) / sizeof(*colors);
    
    WINDOW *w;
      
    void set_colors(void)
    {
        int i;
        initscr();
        start_color();
        use_default_colors();
    
        for (i = 0; i < num_colors; ++i)
        {
            init_pair(i, colors[i], COLOR_BLACK);
            attron(COLOR_PAIR(i));
            printw("COLOR %hd\n", i);
            refresh();
        }
        int j;
        for(;i<21;i++)
        {
            j=(i-10)*100;
            init_color(i, 500, 1000, j);
            init_pair(i, i, COLOR_BLACK);
            attron(COLOR_PAIR(i));
            printw("COLOR %hd\n", i);
            refresh();
        }
        standend();
        getch();
        endwin();
    }
      
    int main(void)
    {
        set_colors();
        return 0;
    }

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Code:
    #include <stdlib.h>
    #include <ncurses.h>
       
    const short colors[] =
    {
        COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
        COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
    };
      
    const int num_colors = sizeof(colors) / sizeof(*colors);
     
    void set_colors(void)
    {
        int i;
        initscr();
        if (!has_colors())
        {
            endwin();
            printf("no color!\n");
            exit(1);
        }
    	
        start_color();
        printw("COLORS = %d\n", COLORS);
        refresh();
        getch(); 
        
        if (!can_change_color())
        {
            endwin();
            printf("no color change!\n");
            exit(1);
        }
    
        for (i = 0; i < num_colors; ++i)
        {
            init_pair(i, colors[i], COLOR_BLACK);
            attron(COLOR_PAIR(i));
            printw("COLOR %hd\n", i);
            refresh();
        }
    
        for (i = 0; i < num_colors; ++i)
        {
            int r = init_color(colors[i], 1000, 0, 0);
            if (r == ERR)
            {
                endwin();
                printf("init_color failed on %d\n", i);
                exit(1);
            }
            attron(COLOR_PAIR(i));
            printw("COLOR %hd\n", i);
            refresh();
        }
        standend();
        getch();
        endwin();
    }
       
    int main(void)
    {
        set_colors();
        return 0;
    }
    Valid values for the first parameter to init_color() are between 0 and COLORS. COLORS is 8 on my term and running the above results in "no color change!".

    gg

  10. #10
    Registered User
    Join Date
    Dec 2011
    Posts
    51
    I have colors=256.

    echo $TERM
    xterm-256color
    -->display full color change on my last program post
    TERM=xterm
    echo $TERM
    xterm
    -->display color 0 to 7 only.

    This display Error on color 7, 8 and 9
    Code:
    #include <ncurses.h>
      
    const short colors[] =
    {
        COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
        COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
    };
     
    const int num_colors = sizeof(colors) / sizeof(*colors);
    
    WINDOW *w;
      
    void set_colors(void)
    {
        int i;
        initscr();
        start_color();
        use_default_colors();
    
        for (i = 0; i < num_colors; ++i)
        {
            init_pair(i, colors[i], COLOR_BLACK);
            attron(COLOR_PAIR(i));
            printw("COLOR %hd\n", i);
            refresh();
        }
        int j;
        for(;i<21;i++)
        {
            j=(i-10)*100;
            int r=init_color(i, 500, 1000, j);
            if (r==ERR)
                printw("ERROR COLOR %hd\n", i);
            init_pair(i, i, COLOR_BLACK);
            attron(COLOR_PAIR(i));
            printw("COLOR %hd\n", i);
            refresh();
        }
        standend();
        getch();
        endwin();
    }
      
    int main(void)
    {
        set_colors();
        return 0;
    }
    Last edited by mariostg; 08-04-2012 at 08:05 PM.

  11. #11
    Registered User
    Join Date
    Dec 2011
    Posts
    51
    I am going to think about all this overnight now...

  12. #12
    Registered User
    Join Date
    Dec 2011
    Posts
    51
    Ok I think I got it. init_color() not required. On a term that supports 256 colors, it is as simple as that. I should have thought about it before. And most importantly, the terminal colorsheme is not broken on exit.

    Code:
    #include <ncurses.h>
      
    WINDOW *w;
      
    void set_colors(void)
    {
        int i;
        initscr();
        start_color();
        use_default_colors();
    
        for(i=0 ;i<256;i++)
        {
            init_pair(i, i, COLOR_BLACK);
            attron(COLOR_PAIR(i));
            printw("[COLOR %hd] ", i);
            refresh();
        }
        standend();
        getch();
        endwin();
    }
      
    int main(void)
    {
        set_colors();
        return 0;
    }
    Last edited by mariostg; 08-05-2012 at 08:00 AM. Reason: remove variable j

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Change color per Character ncurses
    By greendragons in forum C Programming
    Replies: 5
    Last Post: 04-30-2012, 08:10 PM
  2. Need help to restore running app
    By WDT in forum C# Programming
    Replies: 4
    Last Post: 08-05-2009, 11:05 AM
  3. log and restore
    By TopJo in forum C Programming
    Replies: 3
    Last Post: 07-01-2003, 07:14 PM
  4. Restore CD's
    By windoze victim in forum Tech Board
    Replies: 8
    Last Post: 03-10-2003, 05:50 AM
  5. windows restore
    By master2000 in forum Tech Board
    Replies: 8
    Last Post: 01-08-2003, 09:42 AM