void console_write(console_t* const console, const char* message) { char c; const lcd_color_t prior_background = lcd_set_background(console->lcd, console->background); const lcd_color_t prior_foreground = lcd_set_foreground(console->lcd, console->foreground); while( (c = *(message++)) != 0 ) { const lcd_glyph_t* const glyph = lcd_get_glyph(console->lcd, c); if( (console->x + glyph->advance) > console->lcd->size.w ) { console_crlf(console); } lcd_draw_char( console->lcd, console->x, lcd_scroll_area_y(console->lcd, console->y), c ); console->x += glyph->advance; } lcd_set_background(console->lcd, prior_background); lcd_set_foreground(console->lcd, prior_foreground); }
void console_writeln(console_t* const console, const char* message) { console_write(console, message); console_crlf(console); }
int console_readline(char *prompt,char *str,int maxlen) { int reading = 1; int ch; int idx = 0; int len = 0; int t; int klen; int recall; int nosave = 0; char *x; char env[10]; console_inreadline++; recall = console_nextsave; if (console_savedlines[console_nextsave]) { KFREE(console_savedlines[console_nextsave]); console_savedlines[console_nextsave] = NULL; } console_savedlines[console_nextsave] = strdup(""); if (prompt && *prompt) console_write(prompt,strlen(prompt)); POLL(); while (reading) { /* * If someone used console_log (above) or hit Control-C (below), * redisplay the prompt and the string we've got so far. */ if (console_redisplay) { if (prompt && *prompt) console_write(prompt,strlen(prompt)); console_write(str,idx); console_redisplay = 0; continue; } #if defined(CONFIG_MIPS_BRCM) /* * If a background process has set the global g_console_abort flag, stop * reading from the keyboard. */ if (g_console_abort) { g_console_abort = 0; break; } #endif /* * if nobody's typed anything, keep polling */ if (console_status() == 0) { POLL(); continue; } /* * Get the char from the keyboard */ ch = console_readkey(); if (ch < 0) break; if (ch == 0) continue; /* * And dispatch it. Lots of yucky character manipulation follows */ switch (ch) { case CTRL('C'): /* Ctrl-C - cancel line */ console_write("^C\r\n",4); console_redisplay = 1; nosave = 1; idx = 0; break; case 0x7f: /* Backspace, Delete */ case CTRL('H'): if (idx > 0) { nosave = 0; len--; idx--; console_write("\b",1); if (len != idx) { for (t = idx; t < len; t++) str[t] = str[t+1]; console_write(&str[idx],len-idx); console_whiteout(1); console_backspace(len-idx); } else { console_whiteout(1); } } break; case CTRL('D'): /* Ctrl-D */ if ((idx >= 0) && (len != idx)) { nosave = 0; len--; for (t = idx; t < len; t++) str[t] = str[t+1]; console_write(&str[idx],len-idx); console_whiteout(1); console_backspace(len-idx); } break; case CTRL('B'): /* cursor left */ case VKEY_LEFT: if (idx > 0) { idx--; console_backspace(1); } break; case CTRL('F'): /* cursor right */ case VKEY_RIGHT: if (idx < len) { console_write(&str[idx],1); idx++; } break; case CTRL('A'): /* cursor to BOL */ console_backspace(idx); idx = 0; break; case CTRL('E'): /* cursor to EOL */ if (len-idx > 0) console_write(&str[idx],len-idx); idx = len; break; case CTRL('K'): /* Kill to EOL */ if (idx != len) { str[len] = '\0'; if (console_killbuffer) KFREE(console_killbuffer); console_killbuffer = strdup(&str[idx]); console_whiteout(len-idx); len = idx; nosave = 0; } break; case CTRL('Y'): /* Yank killed data */ if (console_killbuffer == NULL) break; klen = strlen(console_killbuffer); if (klen == 0) break; if (len + klen > maxlen) break; nosave = 0; for (t = len + klen; t > idx; t--) { str[t-1] = str[t-klen-1]; } for (t = 0; t < klen; t++) str[t+idx] = console_killbuffer[t]; len += klen; console_write(&str[idx],len-idx); idx += klen; console_backspace(len-idx-1); break; case CTRL('R'): /* Redisplay line */ str[len] = 0; console_crlf(); console_write(prompt,strlen(prompt)); console_write(str,len); console_backspace(len-idx); break; case CTRL('U'): /* Cancel line */ console_backspace(idx); console_eraseeol(); if (len > 0) nosave = 1; idx = 0; len = 0; break; case CTRL('M'): /* terminate */ case CTRL('J'): console_crlf(); reading = 0; break; case CTRL('P'): case VKEY_UP: /* recall previous line */ t = recall; t--; if (t < 0) t = MAXSAVELINES-1; if (console_savedlines[t] == NULL) break; recall = t; console_backspace(idx); strcpy(str,console_savedlines[recall]); len = idx = strlen(console_savedlines[recall]); console_eraseeol(); console_write(str,len); nosave = (t == ((console_nextsave - 1) % MAXSAVELINES)); break; case CTRL('N'): case VKEY_DOWN: /* Recall next line */ t = recall; t++; if (t == MAXSAVELINES) t = 0; if (console_savedlines[t] == NULL) break; recall = t; console_backspace(idx); strcpy(str,console_savedlines[recall]); len = idx = strlen(console_savedlines[recall]); console_eraseeol(); console_write(str,len); nosave = 1; break; case VKEY_F1: case VKEY_F2: case VKEY_F3: case VKEY_F4: case VKEY_F5: case VKEY_F6: case VKEY_F7: case VKEY_F8: case VKEY_F9: case VKEY_F10: case VKEY_F11: case VKEY_F12: sprintf(env,"F%d",ch-VKEY_F1+1); x = env_getenv(env); if (x) { console_backspace(idx); strcpy(str,x); idx = len = strlen(str); console_eraseeol(); console_write(str,len); console_crlf(); reading = 0; nosave = 1; } /* * If F12 is undefined, it means "repeat last command" */ if (ch == VKEY_F12) { t = recall; t--; if (t < 0) t = MAXSAVELINES-1; if (console_savedlines[t] == NULL) break; recall = t; console_backspace(idx); strcpy(str,console_savedlines[recall]); len = idx = strlen(console_savedlines[recall]); console_eraseeol(); console_write(str,len); console_crlf(); reading = 0; nosave = 1; } break; default: /* insert character */ if (ch >= ' ') { if (idx < (maxlen-1)) { nosave = 0; for (t = len; t > idx; t--) { str[t] = str[t-1]; } str[idx] = ch; len++; if (len != idx) { console_write(&str[idx],len-idx); console_backspace(len-idx-1); } idx++; } } break; } } POLL(); console_inreadline--; str[len] = 0; if ((len != 0) && !nosave) { if (console_savedlines[console_nextsave]) { KFREE(console_savedlines[console_nextsave]); } console_savedlines[console_nextsave] = strdup(str); console_nextsave++; if (console_nextsave == MAXSAVELINES) console_nextsave = 0; } return len; }