in charlcd.c [365:462]
static void charlcd_write_char(struct charlcd *lcd, char c)
{
struct charlcd_priv *priv = charlcd_to_priv(lcd);
/* first, we'll test if we're in escape mode */
if ((c != '\n') && priv->esc_seq.len >= 0) {
/* yes, let's add this char to the buffer */
priv->esc_seq.buf[priv->esc_seq.len++] = c;
priv->esc_seq.buf[priv->esc_seq.len] = '\0';
} else {
/* aborts any previous escape sequence */
priv->esc_seq.len = -1;
switch (c) {
case LCD_ESCAPE_CHAR:
/* start of an escape sequence */
priv->esc_seq.len = 0;
priv->esc_seq.buf[priv->esc_seq.len] = '\0';
break;
case '\b':
/* go back one char and clear it */
if (lcd->addr.x > 0) {
/* back one char */
if (!lcd->ops->shift_cursor(lcd,
CHARLCD_SHIFT_LEFT))
lcd->addr.x--;
}
/* replace with a space */
charlcd_print(lcd, ' ');
/* back one char again */
if (!lcd->ops->shift_cursor(lcd, CHARLCD_SHIFT_LEFT))
lcd->addr.x--;
break;
case '\f':
/* quickly clear the display */
charlcd_clear_display(lcd);
break;
case '\n':
/*
* flush the remainder of the current line and
* go to the beginning of the next line
*/
for (; lcd->addr.x < lcd->width; lcd->addr.x++)
lcd->ops->print(lcd, ' ');
lcd->addr.x = 0;
lcd->addr.y = (lcd->addr.y + 1) % lcd->height;
lcd->ops->gotoxy(lcd, lcd->addr.x, lcd->addr.y);
break;
case '\r':
/* go to the beginning of the same line */
lcd->addr.x = 0;
lcd->ops->gotoxy(lcd, lcd->addr.x, lcd->addr.y);
break;
case '\t':
/* print a space instead of the tab */
charlcd_print(lcd, ' ');
break;
default:
/* simply print this char */
charlcd_print(lcd, c);
break;
}
}
/*
* now we'll see if we're in an escape mode and if the current
* escape sequence can be understood.
*/
if (priv->esc_seq.len >= 2) {
int processed = 0;
if (!strcmp(priv->esc_seq.buf, "[2J")) {
/* clear the display */
charlcd_clear_display(lcd);
processed = 1;
} else if (!strcmp(priv->esc_seq.buf, "[H")) {
/* cursor to home */
charlcd_home(lcd);
processed = 1;
}
/* codes starting with ^[[L */
else if ((priv->esc_seq.len >= 3) &&
(priv->esc_seq.buf[0] == '[') &&
(priv->esc_seq.buf[1] == 'L')) {
processed = handle_lcd_special_code(lcd);
}
/* LCD special escape codes */
/*
* flush the escape sequence if it's been processed
* or if it is getting too long.
*/
if (processed || (priv->esc_seq.len >= LCD_ESCAPE_LEN))
priv->esc_seq.len = -1;
} /* escape codes */
}