int waddch()

in graphics/pdcurs34/pdcurses/pdc_addch.c [138:342]


int waddch(WINDOW *win, const chtype ch)
{
  chtype text;
  chtype attr;
  int x;
  int y;
  bool xlat;
#ifdef CONFIG_PDCURSES_MULTITHREAD
  FAR struct pdc_context_s *ctx = PDC_ctx();
#endif

  PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
           win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));

  if (win == NULL)
    {
      return ERR;
    }

  x = win->_curx;
  y = win->_cury;

  if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
    {
      return ERR;
    }

  xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
  text = ch & A_CHARTEXT;
  attr = ch & A_ATTRIBUTES;

  if (xlat && (text < ' ' || text == 0x7f))
    {
      int x2;

      switch (text)
        {
        case '\t':
          for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
            {
              if (waddch(win, attr | ' ') == ERR)
                {
                  return ERR;
                }

              /* If tab to next line, exit the loop */

              if (!win->_curx)
                {
                  break;
                }
            }

          return OK;

        case '\n':
          /* If lf -> crlf */

          if (!SP->raw_out)
            {
              x = 0;
            }

          wclrtoeol(win);

          if (++y > win->_bmarg)
            {
              y--;

              if (wscrl(win, 1) == ERR)
                {
                  return ERR;
                }
            }

          break;

        case '\b':
          /* Don't back over left margin */

          if (--x < 0)
            {
              x = 0;
            }

          break;

        case '\r':
          x = 0;
          break;

        case 0x7f:
          if (waddch(win, attr | '^') == ERR)
            {
              return ERR;
            }

          return waddch(win, attr | '?');

        default:
          /* Handle control chars */

          if (waddch(win, attr | '^') == ERR)
            {
              return ERR;
            }

          return waddch(win, ch + '@');
        }
    }
  else
    {
      /* If the incoming character doesn't have its own attribute, then use
       * the current attributes for the window. If it has attributes but not
       * a color component, OR the attributes to the current attributes for
       * the window. If it has a color component, use the attributes solely
       * from the incoming character.
       */

      if ((attr & A_COLOR) == 0)
        {
          attr |= win->_attrs;
        }

      /* wrs (4/10/93): Apply the same sort of logic for the window
       * background, in that it only takes precedence if other color
       * attributes are not there and that the background character will
       * only print if the printing character is blank.
       */

      if ((attr & A_COLOR) == 0)
        {
          attr |= win->_bkgd & A_ATTRIBUTES;
        }
      else
        {
          attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
        }

      if (text == ' ')
        {
          text = win->_bkgd & A_CHARTEXT;
        }

      /* Add the attribute back into the character. */

      text |= attr;

      /* Only change _firstch/_lastch if the character to be added is
       * different  from the character/attribute that is already in that
       * position in the window.
       */

      if (win->_y[y][x] != text)
        {
          if (win->_firstch[y] == _NO_CHANGE)
            {
              win->_firstch[y] = win->_lastch[y] = x;
            }
          else if (x < win->_firstch[y])
            {
              win->_firstch[y] = x;
            }
          else if (x > win->_lastch[y])
            {
              win->_lastch[y] = x;
            }

          win->_y[y][x] = text;
        }

      if (++x >= win->_maxx)
        {
          /* Wrap around test */

          x = 0;

          if (++y > win->_bmarg)
            {
              y--;

              if (wscrl(win, 1) == ERR)
                {
                  PDC_sync(win);
                  return ERR;
                }
            }
        }
    }

  win->_curx = x;
  win->_cury = y;

  if (win->_immed)
    {
      wrefresh(win);
    }

  if (win->_sync)
    {
      wsyncup(win);
    }

  return OK;
}