FabGL
ESP32 Display Controller and Graphics Library
terminal.h
Go to the documentation of this file.
1 /*
2  Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
3  Copyright (c) 2019 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6  This file is part of FabGL Library.
7 
8  FabGL is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  FabGL is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with FabGL. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #pragma once
24 
25 
26 
35 #include "Arduino.h"
36 
37 #include "freertos/FreeRTOS.h"
38 #include "freertos/task.h"
39 #include "freertos/timers.h"
40 #include "freertos/semphr.h"
41 
42 #include "fabglconf.h"
43 #include "canvas.h"
44 #include "devdrivers/keyboard.h"
45 #include "terminfo.h"
46 
47 #include "Stream.h"
48 
49 
50 
216 namespace fabgl {
217 
218 
219 
220 
221 // used by saveCursorState / restoreCursorState
222 struct TerminalCursorState {
223  TerminalCursorState * next;
224  int16_t cursorX;
225  int16_t cursorY;
226  uint8_t * tabStop;
227  bool cursorPastLastCol;
228  bool originMode;
229  GlyphOptions glyphOptions;
230  uint8_t characterSetIndex;
231  uint8_t characterSet[4];
232 };
233 
234 
235 enum KeypadMode {
236  Application, // DECKPAM
237  Numeric, // DECKPNM
238 };
239 
240 
241 struct EmuState {
242 
243  // Index of characterSet[], 0 = G0 (Standard) 1 = G1 (Alternate), 2 = G2, 3 = G3
244  uint8_t characterSetIndex;
245 
246  // 0 = DEC Special Character and Line Drawing 1 = United States (USASCII)
247  uint8_t characterSet[4];
248 
249  Color foregroundColor;
250  Color backgroundColor;
251 
252  // cursor position (topleft = 1,1)
253  int cursorX;
254  int cursorY;
255 
256  bool cursorPastLastCol;
257 
258  bool originMode;
259 
260  bool wraparound;
261 
262  // top and down scrolling regions (1 = first row)
263  int scrollingRegionTop;
264  int scrollingRegionDown;
265 
266  bool cursorEnabled;
267 
268  // true = blinking cursor, false = steady cursor
269  bool cursorBlinkingEnabled;
270 
271  // 0,1,2 = block 3,4 = underline 5,6 = bar
272  int cursorStyle;
273 
274  // column 1 at m_emuState.tabStop[0], column 2 at m_emuState.tabStop[1], etc... 0=no tab stop, 1 = tab stop
275  uint8_t * tabStop;
276 
277  // IRM (Insert Mode)
278  bool insertMode;
279 
280  // NLM (Automatic CR LF)
281  bool newLineMode;
282 
283  // DECSCLM (Smooth scroll)
284  // Smooth scroll is effective only when vertical sync refresh is enabled,
285  // hence must be DisplayController.enableBackgroundPrimitiveExecution(true),
286  // that is the default.
287  bool smoothScroll;
288 
289  // DECKPAM (Keypad Application Mode)
290  // DECKPNM (Keypad Numeric Mode)
291  KeypadMode keypadMode;
292 
293  // DECCKM (Cursor Keys Mode)
294  bool cursorKeysMode;
295 
296  // DESSCL (1 = VT100 ... 5 = VT500)
297  int conformanceLevel;
298 
299  // two values allowed: 7 and 8
300  int ctrlBits;
301 
302  bool keyAutorepeat;
303 
304  bool allow132ColumnMode;
305 
306  bool reverseWraparoundMode;
307 
308  // DECBKM (false = BACKSPACE sends BS, false BACKSPACE sends DEL)
309  bool backarrowKeyMode;
310 
311  // DECANM (false = VT52 mode, true = ANSI mode)
312  bool ANSIMode;
313 
314  // VT52 Graphics Mode
315  bool VT52GraphicsMode;
316 };
317 
318 
319 
402 class Terminal : public Stream {
403 
404 public:
405 
406  Terminal();
407 
408  ~Terminal();
409 
418  void begin(DisplayController * displayController, Keyboard * keyboard = nullptr);
419 
425  void end();
426 
444  void connectSerialPort(HardwareSerial & serialPort, bool autoXONXOFF = true);
445 
459  void pollSerialPort();
460 
474  void connectLocally();
475 
483  void localWrite(uint8_t c);
484 
492  void localWrite(char const * str);
493 
507  void setLogStream(Stream & stream) { m_logStream = &stream; }
508 
509  void logFmt(const char * format, ...);
510  void log(const char * txt);
511  void log(char c);
512 
523  void loadFont(FontInfo const * font);
524 
538  void setBackgroundColor(Color color, bool setAsDefault = true);
539 
553  void setForegroundColor(Color color, bool setAsDefault = true);
554 
566  void clear();
567 
574  void flush(bool waitVSync);
575 
581  int getColumns() { return m_columns; }
582 
588  int getRows() { return m_rows; }
589 
595  void enableCursor(bool value);
596 
602  int availableForWrite();
603 
611  void setTerminalType(TermInfo const * value);
612 
620  void setTerminalType(TermType value);
621 
627  TermInfo const & terminalType() { return *m_termInfo; }
628 
629 
632 
640  int available();
641 
649  int read();
650 
658  int peek();
659 
665  void flush();
666 
687  int write(const uint8_t * buffer, int size);
688 
698  size_t write(uint8_t c);
699 
700  using Print::write;
701 
702 
703 private:
704 
705  void reset();
706  void int_clear();
707  void clearMap(uint32_t * map);
708 
709  void freeFont();
710  void freeTabStops();
711  void freeGlyphsMap();
712 
713  void set132ColumnMode(bool value);
714 
715  bool moveUp();
716  bool moveDown();
717  void setCursorPos(int X, int Y);
718  int getAbsoluteRow(int Y);
719 
720  void int_setBackgroundColor(Color color);
721  void int_setForegroundColor(Color color);
722 
723  // tab stops
724  void nextTabStop();
725  void setTabStop(int column, bool set);
726  void resetTabStops();
727 
728  // scroll control
729  void scrollDown();
730  void scrollDownAt(int startingRow);
731  void scrollUp();
732  void scrollUpAt(int startingRow);
733  void setScrollingRegion(int top, int down, bool resetCursorPos = true);
734  void updateCanvasScrollingRegion();
735 
736  // multilevel save/restore cursor state
737  void saveCursorState();
738  void restoreCursorState();
739  void clearSavedCursorStates();
740 
741  void erase(int X1, int Y1, int X2, int Y2, char c, bool maintainDoubleWidth, bool selective);
742 
743  void consumeInputQueue();
744  void consumeESC();
745  void consumeCSI();
746  void consumeCSIQUOT(int * params, int paramsCount);
747  void consumeCSISPC(int * params, int paramsCount);
748  char consumeParamsAndGetCode(int * params, int * paramsCount, bool * questionMarkFound);
749  void consumeDECPrivateModes(int const * params, int paramsCount, char c);
750  void consumeDCS();
751  void execSGRParameters(int const * params, int paramsCount);
752  void consumeESCVT52();
753 
754  void execCtrlCode(char c);
755 
756  static void charsConsumerTask(void * pvParameters);
757  static void keyboardReaderTask(void * pvParameters);
758 
759  static void blinkTimerFunc(TimerHandle_t xTimer);
760  void blinkText();
761  bool enableBlinkingText(bool value);
762  void blinkCursor();
763  bool int_enableCursor(bool value);
764 
765  char getNextCode(bool processCtrlCodes);
766 
767  void setChar(char c);
768  GlyphOptions getGlyphOptionsAt(int X, int Y);
769 
770  void insertAt(int column, int row, int count);
771  void deleteAt(int column, int row, int count);
772 
773  void reverseVideo(bool value);
774 
775  void refresh();
776  void refresh(int X, int Y);
777  void refresh(int X1, int Y1, int X2, int Y2);
778 
779  void setLineDoubleWidth(int row, int value);
780  int getCharWidthAt(int row);
781  int getColumnsAt(int row);
782 
783  void useAlternateScreenBuffer(bool value);
784 
785  void send(char c);
786  void send(char const * str);
787  void sendCSI();
788  void sendDCS();
789  void sendSS3();
790  void sendCursorKeyCode(char c);
791  void sendKeypadCursorKeyCode(char applicationCode, const char * numericCode);
792 
793  void ANSIDecodeVirtualKey(VirtualKey vk);
794  void VT52DecodeVirtualKey(VirtualKey vk);
795 
796  void convHandleTranslation(uint8_t c);
797  void convSendCtrl(ConvCtrl ctrl);
798  void convQueue(const char * str = nullptr);
799  void TermDecodeVirtualKey(VirtualKey vk);
800 
801  DisplayController * m_displayController;
802  Canvas * m_canvas;
803 
804  Keyboard * m_keyboard;
805 
806  Stream * m_logStream;
807 
808  // characters, characters attributes and characters colors container
809  // you may also call this the "text screen buffer"
810  GlyphsBuffer m_glyphsBuffer;
811 
812  // used to implement alternate screen buffer
813  uint32_t * m_alternateMap;
814 
815  // true when m_alternateMap and m_glyphBuffer.map has been swapped
816  bool m_alternateScreenBuffer;
817 
818  // just to restore cursor X and Y pos when swapping screens (alternate screen)
819  int m_alternateCursorX;
820  int m_alternateCursorY;
821 
822  FontInfo m_font;
823 
824  PaintOptions m_paintOptions;
825  GlyphOptions m_glyphOptions;
826 
827  EmuState m_emuState;
828 
829  Color m_defaultForegroundColor;
830  Color m_defaultBackgroundColor;
831 
832  // states of cursor and blinking text before consumeInputQueue()
833  bool m_prevCursorEnabled;
834  bool m_prevBlinkingTextEnabled;
835 
836  // task that reads and processes incoming characters
837  TaskHandle_t m_charsConsumerTaskHandle;
838 
839  // task that reads keyboard input and send ANSI/VT100 codes to serial port
840  TaskHandle_t m_keyboardReaderTaskHandle;
841 
842  // true = cursor in reverse state (visible), false = cursor invisible
843  volatile bool m_cursorState;
844 
845  // timer used to blink
846  TimerHandle_t m_blinkTimer;
847  volatile SemaphoreHandle_t m_blinkTimerMutex;
848 
849  volatile bool m_blinkingTextVisible; // true = blinking text is currently visible
850  volatile bool m_blinkingTextEnabled;
851 
852  volatile int m_columns;
853  volatile int m_rows;
854 
855  // optional serial port
856  // data from serial port is processed and displayed
857  // keys from keyboard are processed and sent to serial port
858  HardwareSerial * m_serialPort;
859 
860  // contains characters to be processed (from write() calls)
861  QueueHandle_t m_inputQueue;
862 
863  // contains characters received and decoded from keyboard (or as replyes from ANSI-VT queries)
864  QueueHandle_t m_outputQueue;
865 
866  // linked list that contains saved cursor states (first item is the last added)
867  TerminalCursorState * m_savedCursorStateList;
868 
869  // a reset has been requested
870  bool m_resetRequested;
871 
872  bool m_autoXONOFF;
873  bool m_XOFF; // true = XOFF sent
874 
875  // used to implement m_emuState.keyAutorepeat
876  VirtualKey m_lastPressedKey;
877 
878  uint8_t m_convMatchedCount;
879  char m_convMatchedChars[EmuTerminalMaxChars];
880  TermInfoVideoConv const * m_convMatchedItem;
881  TermInfo const * m_termInfo;
882 
883 };
884 
885 
886 } // end of namespace
887 
A class with a set of drawing methods.
Definition: canvas.h:66
void clear()
Clears the screen.
Definition: terminal.cpp:441
void localWrite(uint8_t c)
Injects keys into the keyboard queue.
Definition: terminal.cpp:944
void begin(DisplayController *displayController, Keyboard *keyboard=nullptr)
Initializes the terminal.
Definition: terminal.cpp:97
TermInfo const & terminalType()
Determines current terminal type.
Definition: terminal.h:627
Color
This enum defines named colors.
Definition: displaycontroller.h:180
This file contains terminal emulation definitions.
int write(const uint8_t *buffer, int size)
Sends specified number of codes to the display.
Definition: terminal.cpp:1103
This file contains fabgl::Keyboard definition.
int available()
Gets the number of codes available in the keyboard queue.
Definition: terminal.cpp:967
void connectSerialPort(HardwareSerial &serialPort, bool autoXONXOFF=true)
Connects a remove host using the specified serial port.
Definition: terminal.cpp:157
void connectLocally()
Permits using of terminal locally.
Definition: terminal.cpp:175
The PS2 Keyboard controller class.
Definition: keyboard.h:160
This file contains fabgl::Canvas definition.
void loadFont(FontInfo const *font)
Sets the font to use.
Definition: terminal.cpp:338
void setBackgroundColor(Color color, bool setAsDefault=true)
Sets the background color.
Definition: terminal.cpp:400
int peek()
Reads a code from the keyboard without advancing to the next one.
Definition: terminal.cpp:985
int read()
Reads codes from keyboard.
Definition: terminal.cpp:973
void pollSerialPort()
Pools the serial port for incoming data.
Definition: terminal.cpp:997
void enableCursor(bool value)
Enables or disables cursor.
Definition: terminal.cpp:522
VirtualKey
Represents each possible real or derived (SHIFT + real) key.
Definition: fabutils.h:534
Definition: canvas.cpp:31
Specifies various glyph painting options.
Definition: displaycontroller.h:315
TermType
This enum defines supported terminals.
Definition: terminfo.h:103
This file contains FabGL library configuration settings, like number of supported colors...
void flush()
Waits for all codes sent to the display has been processed.
Definition: terminal.cpp:991
An ANSI-VT100 compatible display terminal.
Definition: terminal.h:402
void setTerminalType(TermInfo const *value)
Sets the terminal type to emulate specifying conversion tables.
Definition: terminal.cpp:1111
Represents the base abstract class for display controllers.
Definition: displaycontroller.h:596
int getRows()
Returns the number of lines.
Definition: terminal.h:588
int getColumns()
Returns the number of columns.
Definition: terminal.h:581
int availableForWrite()
Determines number of codes that the display input queue can still accept.
Definition: terminal.cpp:1082
void end()
Finalizes the terminal.
Definition: terminal.cpp:246
void setLogStream(Stream &stream)
Sets the stream where to output debugging logs.
Definition: terminal.h:507
Specifies general paint options.
Definition: displaycontroller.h:542
void setForegroundColor(Color color, bool setAsDefault=true)
Sets the foreground color.
Definition: terminal.cpp:415