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 */
CODE bool (*checkkey)(FAR struct termcurses_s *dev);
/* Terminate */
CODE int (*terminate)(FAR struct termcurses_s *dev);
};
struct termcurses_dev_s
@ -157,7 +161,7 @@ extern "C"
****************************************************************************/
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
@ -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

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,
FAR int *specialkey, FAR int *keymodifers);
static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev);
static int tcurses_vt100_terminate(FAR struct termcurses_s *dev);
/************************************************************************************
* Private Data
@ -107,7 +108,8 @@ static const struct termcurses_ops_s g_vt100_ops =
tcurses_vt100_setcolors,
tcurses_vt100_setattributes,
tcurses_vt100_getkeycode,
tcurses_vt100_checkkey
tcurses_vt100_checkkey,
tcurses_vt100_terminate
};
/* VT100 terminal codes */
@ -129,6 +131,10 @@ static const char *g_setnoblink = ";25";
static const char *g_setunderline = ";4";
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
{
#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;
}
/************************************************************************************
* 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,
FAR struct termcurses_s **dev)
FAR struct termcurses_s **term)
{
FAR struct termcurses_dev_s *pnext;
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 */
if (*dev == NULL)
if (*term == NULL)
{
/* Call the termcurses_dev init function */
*dev = pnext->ops->init(in_fd, out_fd);
*term = pnext->ops->init(in_fd, out_fd);
}
return OK;
@ -111,7 +111,7 @@ int termcurses_initterm(FAR const char *term_type, int in_fd, int out_fd,
/* Not found! */
*dev = NULL;
*term = NULL;
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;
colors.fg_green = 255;
colors.fg_blue = 255;
colors.bg_red = 0;
colors.bg_green = 0;
colors.bg_blue = 0;
colors.color_mask = 0xff;
termcurses_setcolors(dev, &colors);
if (dev->ops->terminate)
{
result = dev->ops->terminate(term);
}
/* For now, simply free the memory */
/* Free the memory if termination is successful. */
if (result == OK)
free(dev);
return OK;
return result;
}
/************************************************************************************