コード例 #1
0
ファイル: nxterm_register.c プロジェクト: dagar/NuttX
FAR struct nxterm_state_s *
  nxterm_register(NXTERM handle, FAR struct nxterm_window_s *wndo,
                 FAR const struct nxterm_operations_s *ops, int minor)
{
  FAR struct nxterm_state_s *priv;
  FAR const struct nx_font_s *fontset;
  char devname[NX_DEVNAME_SIZE];
  NXHANDLE hfont;
  int ret;

  DEBUGASSERT(handle && wndo && ops && (unsigned)minor < 256);

  /* Allocate the driver structure */

  priv = (FAR struct nxterm_state_s *)kmm_zalloc(sizeof(struct nxterm_state_s));
  if (!priv)
    {
      gerr("ERROR: Failed to allocate the NX driver structure\n");
      return NULL;
    }

  /* Initialize the driver structure */

  priv->ops     = ops;
  priv->handle  = handle;
  priv->minor   = minor;
  memcpy(&priv->wndo, wndo, sizeof(struct nxterm_window_s));

  nxsem_init(&priv->exclsem, 0, 1);
#ifdef CONFIG_DEBUG_FEATURES
  priv->holder  = NO_HOLDER;
#endif

#ifdef CONFIG_NXTERM_NXKBDIN
  /* The waitsem semaphore is used for signaling and, hence, should not have
   * priority inheritance enabled.
   */

  nxsem_init(&priv->waitsem, 0, 0);
  nxsem_setprotocol(&priv->waitsem, SEM_PRIO_NONE);
#endif

  /* Connect to the font cache for the configured font characteristics */

  priv->fcache = nxf_cache_connect(wndo->fontid, wndo->fcolor[0],
                                   wndo->wcolor[0], CONFIG_NXTERM_BPP,
                                   CONFIG_NXTERM_CACHESIZE);
  if (priv->fcache == NULL)
    {
      gerr("ERROR: Failed to connect to font cache for font ID %d: %d\n",
           wndo->fontid, errno);
      goto errout;
    }

  /* Get the handle of the font managed by the font cache */

  hfont = nxf_cache_getfonthandle(priv->fcache);
  if (hfont == NULL)
    {
      gerr("ERROR: Failed to get handlr for font ID %d: %d\n",
           wndo->fontid, errno);
      goto errout;
    }

  /* Get information about the font set being used and save this in the
   * state structure
   */

  fontset         = nxf_getfontset(hfont);
  priv->fheight   = fontset->mxheight;
  priv->fwidth    = fontset->mxwidth;
  priv->spwidth   = fontset->spwidth;

  /* Set up the text cache */

  priv->maxchars  = CONFIG_NXTERM_MXCHARS;

  /* Set the initial display position */

  nxterm_home(priv);

  /* Show the cursor */

  priv->cursor.code = CONFIG_NXTERM_CURSORCHAR;
  nxterm_showcursor(priv);

  /* Register the driver */

  snprintf(devname, NX_DEVNAME_SIZE, NX_DEVNAME_FORMAT, minor);
  ret = register_driver(devname, &g_nxterm_drvrops, 0666, priv);
  if (ret < 0)
    {
      gerr("ERROR: Failed to register %s\n", devname);
    }

  return (NXTERM)priv;

errout:
  kmm_free(priv);
  return NULL;
}
コード例 #2
0
ファイル: nxterm_driver.c プロジェクト: a1ien/nuttx
static ssize_t nxterm_write(FAR struct file *filep, FAR const char *buffer,
                            size_t buflen)
{
    FAR struct nxterm_state_s *priv;
    enum nxterm_vt100state_e state;
    ssize_t remaining;
    char ch;
    int ret;

    /* Recover our private state structure */

    DEBUGASSERT(filep && filep->f_priv);
    priv = (FAR struct nxterm_state_s *)filep->f_priv;

    /* Get exclusive access */

    ret = nxterm_semwait(priv);
    if (ret < 0)
    {
        return ret;
    }

    /* Hide the cursor while we update the display */

    nxterm_hidecursor(priv);

    /* Loop writing each character to the display */

    for (remaining = (ssize_t)buflen; remaining > 0; remaining--)
    {
        /* Get the next character from the user buffer */

        ch = *buffer++;

        /* Check if this character is part of a VT100 escape sequence */

        do
        {
            /* Is the character part of a VT100 escape sequnce? */

            state = nxterm_vt100(priv, ch);
            switch (state)
            {
            /* Character is not part of a VT100 escape sequence (and no
             * characters are buffer.
             */

            default:
            case VT100_NOT_CONSUMED:
            {
                /* We can output the character to the window */

                nxterm_putc(priv, (uint8_t)ch);
            }
            break;

            /* The full VT100 escape sequence was processed (and the new
             * character was consumed)
             */

            case VT100_PROCESSED:

            /* Character was consumed as part of the VT100 escape processing
             * (but the escape sequence is still incomplete.
             */

            case VT100_CONSUMED:
            {
                /* Do nothing... the VT100 logic owns the character */
            }
            break;

            /* Invalid/unsupported character in escape sequence */

            case VT100_ABORT:
            {
                int i;

                /* Add the first unhandled character to the window */

                nxterm_putc(priv, (uint8_t)priv->seq[0]);

                /* Move all buffer characters down one */

                for (i = 1; i < priv->nseq; i++)
                {
                    priv->seq[i-1] = priv->seq[i];
                }
                priv->nseq--;

                /* Then loop again and check if what remains is part of a
                 * VT100 escape sequence.  We could speed this up by
                 * checking if priv->seq[0] == ASCII_ESC.
                 */
            }
            break;
            }
        }
        while (state == VT100_ABORT);
    }

    /* Show the cursor at its new position */

    nxterm_showcursor(priv);
    nxterm_sempost(priv);
    return (ssize_t)buflen;
}