xaizek / vifm-pdcurses (License: mostly public domain) (since 2019-03-20)
PDCurses 3.4 with vifm-specific patches applied (a couple were upstreamed)
<root> / pdcurses / bkgd.c (083239e1da5a27c8d60de0720421c4664198f868) (5,561B) (mode 100644) [raw]
/* Public Domain Curses */

#include <curspriv.h>

RCSID("$Id: bkgd.c,v 1.39 2008/07/13 16:08:18 wmcbrine Exp $")

/*man-start**************************************************************

  Name:                                                         bkgd

  Synopsis:
        int bkgd(chtype ch);
        void bkgdset(chtype ch);
        chtype getbkgd(WINDOW *win);
        int wbkgd(WINDOW *win, chtype ch);
        void wbkgdset(WINDOW *win, chtype ch);

        int bkgrnd(const cchar_t *wch);
        void bkgrndset(const cchar_t *wch);
        int getbkgrnd(cchar_t *wch);
        int wbkgrnd(WINDOW *win, const cchar_t *wch);
        void wbkgrndset(WINDOW *win, const cchar_t *wch);
        int wgetbkgrnd(WINDOW *win, cchar_t *wch);

  Description:
        bkgdset() and wbkgdset() manipulate the background of a window.
        The background is a chtype consisting of any combination of
        attributes and a character; it is combined with each chtype
        added or inserted to the window by waddch() or winsch(). Only
        the attribute part is used to set the background of non-blank
        characters, while both character and attributes are used for
        blank positions.

        bkgd() and wbkgd() not only change the background, but apply it
        immediately to every cell in the window.

        The attributes that are defined with the attrset()/attron() set
        of functions take precedence over the background attributes if
        there is a conflict (e.g., different color pairs).

  Return Value:
        bkgd() and wbkgd() return OK, unless the window is NULL, in 
        which case they return ERR.

  Portability                                X/Open    BSD    SYS V
        bkgd                                    Y       -      4.0
        bkgdset                                 Y       -      4.0
        getbkgd                                 Y
        wbkgd                                   Y       -      4.0
        wbkgdset                                Y       -      4.0
        bkgrnd                                  Y
        bkgrndset                               Y
        getbkgrnd                               Y
        wbkgrnd                                 Y
        wbkgrndset                              Y
        wgetbkgrnd                              Y

**man-end****************************************************************/

int wbkgd(WINDOW *win, chtype ch)
{
    int x, y;
    chtype oldcolr, oldch, newcolr, newch, colr, attr;
    chtype oldattr = 0, newattr = 0;
    chtype *winptr;

    PDC_LOG(("wbkgd() - called\n"));

    if (!win)
        return ERR;

    if (win->_bkgd == ch)
        return OK;

    oldcolr = win->_bkgd & A_COLOR;
    if (oldcolr)
        oldattr = (win->_bkgd & A_ATTRIBUTES) ^ oldcolr;

    oldch = win->_bkgd & A_CHARTEXT;

    wbkgdset(win, ch);

    newcolr = win->_bkgd & A_COLOR;
    if (newcolr)
        newattr = (win->_bkgd & A_ATTRIBUTES) ^ newcolr;

    newch = win->_bkgd & A_CHARTEXT;

    /* what follows is what seems to occur in the System V 
       implementation of this routine */

    for (y = 0; y < win->_maxy; y++)
    {
        for (x = 0; x < win->_maxx; x++)
        {
            winptr = win->_y[y] + x;

            ch = *winptr;

            /* determine the colors and attributes of the character read 
               from the window */

            colr = ch & A_COLOR;
            attr = ch & (A_ATTRIBUTES ^ A_COLOR);

            /* if the color is the same as the old background color, 
               then make it the new background color, otherwise leave it */

            if (colr == oldcolr)
                colr = newcolr;

            /* remove any attributes (non color) from the character that 
               were part of the old background, then combine the 
               remaining ones with the new background */

            attr ^= oldattr;
            attr |= newattr;

            /* change character if it is there because it was the old 
               background character */

            ch &= A_CHARTEXT;
            if (ch == oldch)
                ch = newch;

            ch |= (attr | colr);

            *winptr = ch;

        }
    }

    touchwin(win);
    PDC_sync(win);
    return OK;
}

int bkgd(chtype ch)
{
    PDC_LOG(("bkgd() - called\n"));

    return wbkgd(stdscr, ch);
}

void wbkgdset(WINDOW *win, chtype ch)
{
    PDC_LOG(("wbkgdset() - called\n"));

    if (win)
    {
        if (!(ch & A_CHARTEXT))
            ch |= ' ';

        win->_bkgd = ch;
    }
}

void bkgdset(chtype ch)
{
    PDC_LOG(("bkgdset() - called\n"));

    wbkgdset(stdscr, ch);
}

chtype getbkgd(WINDOW *win)
{
    PDC_LOG(("getbkgd() - called\n"));

    return win ? win->_bkgd : (chtype)ERR;
}

#ifdef PDC_WIDE
int wbkgrnd(WINDOW *win, const cchar_t *wch)
{
    PDC_LOG(("wbkgrnd() - called\n"));

    return wch ? wbkgd(win, *wch) : ERR;
}

int bkgrnd(const cchar_t *wch)
{
    PDC_LOG(("bkgrnd() - called\n"));

    return wbkgrnd(stdscr, wch);
}

void wbkgrndset(WINDOW *win, const cchar_t *wch)
{
    PDC_LOG(("wbkgdset() - called\n"));

    if (wch)
        wbkgdset(win, *wch);
}

void bkgrndset(const cchar_t *wch)
{
    PDC_LOG(("bkgrndset() - called\n"));

    wbkgrndset(stdscr, wch);
}

int wgetbkgrnd(WINDOW *win, cchar_t *wch)
{
    PDC_LOG(("wgetbkgrnd() - called\n"));

    if (!win || !wch)
        return ERR;

    *wch = win->_bkgd;

    return OK;
}

int getbkgrnd(cchar_t *wch)
{
    PDC_LOG(("getbkgrnd() - called\n"));

    return wgetbkgrnd(stdscr, wch);
}
#endif
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm-pdcurses

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm-pdcurses

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master