Member Avatar for Mouche

Hello. I'm using ncurses with a side project I'm working on, and I'm using colored characters. To use colors, you have to wrap each mvprintw() function with some code to set the color. I thought I'd write a function that wraps mvprintw() so I could just specify the color whenever I print something.

Here's what I've got:

void mvprintw_color(int y, int x, int color, char* fmt, ...)
{
    /* This is for the variable length arguments */
    va_list args;
    va_start(args, fmt);

    if (has_colors() == TRUE)
    {
        /* If colors are supported, set the fg and bg colors */
        attron(COLOR_PAIR(color));

        mvprintw(y, x, fmt, args);

        /* Turn off the coloring */
        attroff(COLOR_PAIR(color));
    }
    else
    {
        mvprintw(y, x, fmt, args);
    }
    /* Variable length arguments macro*/
    va_end(args);
}

When I test it, I get random characters instead of what I want to print, but it is the correct color. It seems like I've messed up something with the variable length arguments stuff, but I looked at example functions on several websites and I did it similar to them.

Any idea what's going wrong here?

mvprintw() takes a variable argument list, not a va_list object. A cursory (pun intended) look at the documentation shows that vwprintw() takes a va_list, but doesn't support the coordinates. So your next step would probably be figuring out how to set the coordinates before a call to vwprintw() as that would produce the desired behavior.

Member Avatar for Mouche

Great, that helped. I looked at the definition of mvprintw() in the ncurses source to see how to move the cursor.

Here's my working function:

void mvprintw_color(int y, int x, int color, char* fmt, ...)
{
    /* This is for the variable length arguments */
    va_list args_list;
    va_start(args_list, fmt);

    /* Move the cursor to (x,y) */
    int code = move(y, x);

    if (has_colors() == TRUE)
    {
        /* If colors are supported, set the fg and bg colors */
        attron(COLOR_PAIR(color));

        /* This is the only version of the printw functions that
           takes a varargs parameter, so I had to add the move()
           code above and then use vwprintw to print to
           stdscr, the main screen */
        vwprintw(stdscr, fmt, args_list);

        /* Turn off the coloring */
        attroff(COLOR_PAIR(color));
    }
    else
    {
        vwprintw(stdscr, fmt, args_list);
    }
    /* Variable length arguments macro */
    va_end(args_list);
}

Thanks, Narue.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.