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; }
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; }