mirror of
https://github.com/apache/nuttx.git
synced 2026-08-25 07:27:11 +00:00
graphics/nxterm: support command-line cursor editing
Handle carriage return, cursor-left/right, and erase-to-end-of-line sequences required by readline. Restore glyphs hidden by the cursor so edited text redraws correctly. Signed-off-by: raiden00pl <raiden00@railab.me> Assisted-by: OpenAI Codex:gpt-5
This commit is contained in:
parent
4ebc8a7291
commit
856fad2ffa
2 changed files with 116 additions and 2 deletions
|
|
@ -51,10 +51,11 @@ void nxterm_putc(FAR struct nxterm_state_s *priv, uint8_t ch)
|
|||
FAR const struct nxterm_bitmap_s *bm;
|
||||
int lineheight;
|
||||
|
||||
/* Ignore carriage returns */
|
||||
/* Handle carriage returns */
|
||||
|
||||
if (ch == '\r')
|
||||
{
|
||||
priv->fpos.x = priv->spwidth;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -170,5 +171,22 @@ void nxterm_showcursor(FAR struct nxterm_state_s *priv)
|
|||
|
||||
void nxterm_hidecursor(FAR struct nxterm_state_s *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
nxterm_hidechar(priv, &priv->cursor);
|
||||
|
||||
/* A cursor moved into an existing line is drawn on top of a saved glyph.
|
||||
* Restore that glyph after erasing the cursor so command-line editing does
|
||||
* not leave a hole in the displayed text.
|
||||
*/
|
||||
|
||||
for (i = priv->nchars - 1; i >= 0; i--)
|
||||
{
|
||||
if (priv->bm[i].pos.x == priv->cursor.pos.x &&
|
||||
priv->bm[i].pos.y == priv->cursor.pos.y)
|
||||
{
|
||||
nxterm_fillchar(priv, NULL, &priv->bm[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ struct vt100_sequence_s
|
|||
****************************************************************************/
|
||||
|
||||
static int nxterm_erasetoeol(FAR struct nxterm_state_s *priv);
|
||||
static int nxterm_cursorleft(FAR struct nxterm_state_s *priv);
|
||||
static int nxterm_cursorright(FAR struct nxterm_state_s *priv);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
|
@ -63,12 +65,23 @@ static int nxterm_erasetoeol(FAR struct nxterm_state_s *priv);
|
|||
/* <esc>[K is the VT100 command erases to the end of the line. */
|
||||
|
||||
static const char g_erasetoeol[] = VT100_CLEAREOL;
|
||||
static const char g_cursorleft[] =
|
||||
{
|
||||
ASCII_ESC, '[', 'D'
|
||||
};
|
||||
|
||||
static const char g_cursorright[] =
|
||||
{
|
||||
ASCII_ESC, '[', 'C'
|
||||
};
|
||||
|
||||
/* The list of all VT100 sequences supported by the emulation */
|
||||
|
||||
static const struct vt100_sequence_s g_vt100sequences[] =
|
||||
{
|
||||
{g_erasetoeol, nxterm_erasetoeol, sizeof(g_erasetoeol)},
|
||||
{g_cursorleft, nxterm_cursorleft, sizeof(g_cursorleft)},
|
||||
{g_cursorright, nxterm_cursorright, sizeof(g_cursorright)},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
|
||||
|
|
@ -92,7 +105,90 @@ static const struct vt100_sequence_s g_vt100sequences[] =
|
|||
|
||||
static int nxterm_erasetoeol(FAR struct nxterm_state_s *priv)
|
||||
{
|
||||
/* Does nothing yet (other than consume the sequence) */
|
||||
struct nxgl_rect_s bounds;
|
||||
uint16_t dst;
|
||||
uint16_t src;
|
||||
|
||||
bounds.pt1.x = priv->fpos.x;
|
||||
bounds.pt1.y = priv->fpos.y;
|
||||
bounds.pt2.x = priv->wndo.wsize.w - 1;
|
||||
bounds.pt2.y = priv->fpos.y + priv->fheight - 1;
|
||||
|
||||
priv->ops->fill(priv, &bounds, priv->wndo.wcolor);
|
||||
|
||||
/* Discard every saved glyph covered by the erased portion of this line.
|
||||
* Keeping the bitmap list in sync is necessary for later redraw events.
|
||||
*/
|
||||
|
||||
for (src = 0, dst = 0; src < priv->nchars; src++)
|
||||
{
|
||||
if (priv->bm[src].pos.y == priv->fpos.y &&
|
||||
priv->bm[src].pos.x >= priv->fpos.x)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dst != src)
|
||||
{
|
||||
priv->bm[dst] = priv->bm[src];
|
||||
}
|
||||
|
||||
dst++;
|
||||
}
|
||||
|
||||
priv->nchars = dst;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxterm_cursorleft
|
||||
****************************************************************************/
|
||||
|
||||
static int nxterm_cursorleft(FAR struct nxterm_state_s *priv)
|
||||
{
|
||||
nxgl_coord_t x = priv->spwidth;
|
||||
uint16_t i;
|
||||
|
||||
/* Find the closest saved glyph to the left on the current line. */
|
||||
|
||||
for (i = 0; i < priv->nchars; i++)
|
||||
{
|
||||
if (priv->bm[i].pos.y == priv->fpos.y &&
|
||||
priv->bm[i].pos.x < priv->fpos.x &&
|
||||
priv->bm[i].pos.x > x)
|
||||
{
|
||||
x = priv->bm[i].pos.x;
|
||||
}
|
||||
}
|
||||
|
||||
priv->fpos.x = x;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxterm_cursorright
|
||||
****************************************************************************/
|
||||
|
||||
static int nxterm_cursorright(FAR struct nxterm_state_s *priv)
|
||||
{
|
||||
FAR const struct nxfonts_glyph_s *glyph;
|
||||
int i;
|
||||
|
||||
/* Prefer the most recently rendered glyph when editing has overdrawn a
|
||||
* character at the same location.
|
||||
*/
|
||||
|
||||
for (i = priv->nchars - 1; i >= 0; i--)
|
||||
{
|
||||
if (priv->bm[i].pos.y == priv->fpos.y &&
|
||||
priv->bm[i].pos.x == priv->fpos.x)
|
||||
{
|
||||
glyph = nxf_cache_getglyph(priv->fcache, priv->bm[i].code);
|
||||
priv->fpos.x += glyph == NULL ? priv->spwidth : glyph->width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue