Search code examples
c++cursespdcurses

Why aren't colors working for stdscr? (PDCurses)


So, I'm using pdcurses to add some color to my console application, but I'm having issues. If I make a second window and try to color it's output, it works just fine, but if I try to color output to stdscr, nothing happens.

I want to keep using stdscr rather than cover it with another window, because stdscr will receive output that I send to stdout normally, allowing me to use a C++ style interface to the console. By sending output to cout, it goes to stdscr, and that's currently the only way I know of to use a C++ interface to pdcurses. In addition, other libraries will occasionally send their output straight to stdout, and if I use stdscr that output wont be lost (I know of lua's print function off the top of my heard).

Here's some sample code:

// This prints a red '>' in the inputLine window properly. //
wattron(inputLine, A_BOLD | COLOR_PAIR(COLOR_RED));
wprintw(inputLine, "\n> ");
wattroff(inputLine, A_BOLD | COLOR_PAIR(COLOR_RED));

// This prints a light grey "Le Testing." to stdscr.  Why isn't it red? //
wattron(stdscr, A_BOLD | COLOR_PAIR(COLOR_RED));
cout << "\nLe Testing.\n";
wattroff(stdscr, A_BOLD | COLOR_PAIR(COLOR_RED));

// This does nothing.  I have no idea why. //
wattron(stdscr, A_BOLD | COLOR_PAIR(COLOR_RED));
wprintw(stdscr, "\nLe Testing.\n");
wattroff(stdscr, A_BOLD | COLOR_PAIR(COLOR_RED));

Here is how I initialize pdcurses:

   // Open the output log which will mimic stdout. //
   if (userPath)
   {
      string filename = string(userPath) + LOG_FILENAME;
      log.open(filename.c_str());
   }

      // Initialize the pdCurses screen. //
   initscr();

      // Resize the stdout screen and create a line for input. //
   resize_window(stdscr, LINES - 1, COLS);
   inputLine = newwin(1, COLS, LINES - 1, 0);

      // Initialize colors. //
   if (has_colors())
    {
        start_color();
        for (int i = 1; i <= COLOR_WHITE; ++i)
        {
            init_pair(i, i, COLOR_BLACK);
        }
    }
    else
   {
      cout << "Terminal cannot print colors.\n";
      if (log.is_open())
         log << "Terminal cannot print colors.\n";
   }

   scrollok(stdscr, true);
    scrollok(inputLine, true);

   leaveok(stdscr, true);
    leaveok(inputLine, true);

    nodelay(inputLine, true);
    cbreak();
    noecho();
    keypad(inputLine, true);

What am I doing wrong?


Solution

  • You're incorrectly assuming that writing to standard output will write to stdscr. In fact doing so completely bypasses PDCurses and writes directly to the console, just as if you weren't using PDCurses at all. You need to use PDCurses function to write to PDCurses windows, including stdscr. You'll need to convince any libraries you're using than send output to stdout not to do this, as this will confuse PDCurses.

    The obvious reason why wprintw(stdstc, "\nLe Testing.\n"); didn't work is that you used stdstc instead of stdscr. Assuming though that's just a typo in your post, and you really did write stdscr in your program, then that should work. Did you remember call refresh to actually have your changes to stdscr displayed on screen?