system/termcurses: Add terminate operation into the termcurses_ops_s interface

The existing implementation of the termcurses_deinitterm calls
termcurses_setcolors with some hard-coded values, leading to different
terminal emulators' behavior. Instead, a reset call needs to be made to
the implementation to roll back changes.

A new operation (terminate) has been added to the termcurses_ops interface
to achieve this functionality.

The vt100's terminate implementation ensures that default foreground and
background colors are applied portably across different terminals emulators.
This commit is contained in:
Erdem Meydanli 2021-08-22 13:50:50 +02:00 committed by Xiang Xiao
parent 4f095a193e
commit c222043ed1
3 changed files with 54 additions and 21 deletions

View File

@ -110,6 +110,10 @@ struct termcurses_ops_s
/* Check for cached keycode value */ /* Check for cached keycode value */
CODE bool (*checkkey)(FAR struct termcurses_s *dev); CODE bool (*checkkey)(FAR struct termcurses_s *dev);
/* Terminate */
CODE int (*terminate)(FAR struct termcurses_s *dev);
}; };
struct termcurses_dev_s struct termcurses_dev_s
@ -157,7 +161,7 @@ extern "C"
****************************************************************************/ ****************************************************************************/
int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd, int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd,
FAR struct termcurses_s **dev); FAR struct termcurses_s **term);
/**************************************************************************** /****************************************************************************
* Name: termcurses_deinitterm * Name: termcurses_deinitterm
@ -168,7 +172,7 @@ int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd,
* *
****************************************************************************/ ****************************************************************************/
int termcurses_deinitterm(FAR struct termcurses_s *dev); int termcurses_deinitterm(FAR struct termcurses_s *term);
/**************************************************************************** /****************************************************************************
* Name: termcurses_moveyx * Name: termcurses_moveyx

View File

@ -93,6 +93,7 @@ static int tcurses_vt100_setattributes(FAR struct termcurses_s *dev,
static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev, static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev,
FAR int *specialkey, FAR int *keymodifers); FAR int *specialkey, FAR int *keymodifers);
static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev); static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev);
static int tcurses_vt100_terminate(FAR struct termcurses_s *dev);
/************************************************************************************ /************************************************************************************
* Private Data * Private Data
@ -107,7 +108,8 @@ static const struct termcurses_ops_s g_vt100_ops =
tcurses_vt100_setcolors, tcurses_vt100_setcolors,
tcurses_vt100_setattributes, tcurses_vt100_setattributes,
tcurses_vt100_getkeycode, tcurses_vt100_getkeycode,
tcurses_vt100_checkkey tcurses_vt100_checkkey,
tcurses_vt100_terminate
}; };
/* VT100 terminal codes */ /* VT100 terminal codes */
@ -129,6 +131,10 @@ static const char *g_setnoblink = ";25";
static const char *g_setunderline = ";4"; static const char *g_setunderline = ";4";
static const char *g_setnounderline = ";24"; static const char *g_setnounderline = ";24";
/* Set default background and foreground colors. */
static const char *g_setdefcolors = "\x1b[39;m\x1b[49;m";
struct keycodes_s struct keycodes_s
{ {
#ifdef CONFIG_TERMCURSES_INCLUDE_TERMINFO_NAME #ifdef CONFIG_TERMCURSES_INCLUDE_TERMINFO_NAME
@ -1479,3 +1485,28 @@ FAR struct termcurses_s *tcurses_vt100_initialize(int in_fd, int out_fd)
return (FAR struct termcurses_s *) priv; return (FAR struct termcurses_s *) priv;
} }
/************************************************************************************
* Name: tcurses_vt100_terminate
*
* Description:
* Terminates a specific instance of the VT100 TermCurses handler.
*
************************************************************************************/
static int tcurses_vt100_terminate(FAR struct termcurses_s *dev)
{
FAR struct tcurses_vt100_s *priv;
int fd;
priv = (FAR struct tcurses_vt100_s *) dev;
fd = priv->out_fd;
/* Set default foreground and background colors.
* (Ignore the return result.)
*/
write(fd, g_setdefcolors, strlen(g_setdefcolors));
return OK;
}

View File

@ -62,7 +62,7 @@ static struct termcurses_dev_s *g_termcurses_devices[] =
************************************************************************************/ ************************************************************************************/
int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd, int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd,
FAR struct termcurses_s **dev) FAR struct termcurses_s **term)
{ {
FAR struct termcurses_dev_s *pnext; FAR struct termcurses_dev_s *pnext;
int c; int c;
@ -94,11 +94,11 @@ int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd,
{ {
/* Allocate a new structure for this termcurses */ /* Allocate a new structure for this termcurses */
if (*dev == NULL) if (*term == NULL)
{ {
/* Call the termcurses_dev init function */ /* Call the termcurses_dev init function */
*dev = pnext->ops->init(in_fd, out_fd); *term = pnext->ops->init(in_fd, out_fd);
} }
return OK; return OK;
@ -111,7 +111,7 @@ int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd,
/* Not found! */ /* Not found! */
*dev = NULL; *term = NULL;
return -ENOSYS; return -ENOSYS;
} }
@ -124,26 +124,24 @@ int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd,
* *
************************************************************************************/ ************************************************************************************/
int termcurses_deinitterm(FAR struct termcurses_s *dev) int termcurses_deinitterm(FAR struct termcurses_s *term)
{ {
struct termcurses_colors_s colors; FAR struct termcurses_dev_s *dev = (FAR struct termcurses_dev_s *) term;
int result = OK;
/* Ensure terminal has default color scheme */ /* Call the dev function */
colors.fg_red = 255; if (dev->ops->terminate)
colors.fg_green = 255; {
colors.fg_blue = 255; result = dev->ops->terminate(term);
colors.bg_red = 0; }
colors.bg_green = 0;
colors.bg_blue = 0;
colors.color_mask = 0xff;
termcurses_setcolors(dev, &colors);
/* For now, simply free the memory */ /* Free the memory if termination is successful. */
free(dev); if (result == OK)
free(dev);
return OK; return result;
} }
/************************************************************************************ /************************************************************************************