FabGL
ESP32 VGA 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 "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 VGAController.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 
400 class TerminalClass : public Stream {
401 
402 public:
403 
409  void begin();
410 
416  void end();
417 
435  void connectSerialPort(HardwareSerial & serialPort, bool autoXONXOFF = true);
436 
450  void pollSerialPort();
451 
465  void connectLocally();
466 
474  void localWrite(uint8_t c);
475 
483  void localWrite(char const * str);
484 
498  void setLogStream(Stream & stream) { m_logStream = &stream; }
499 
500  void logFmt(const char * format, ...);
501  void log(const char * txt);
502  void log(char c);
503 
513  void loadFont(FontInfo const * font);
514 
528  void setBackgroundColor(Color color, bool setAsDefault = true);
529 
543  void setForegroundColor(Color color, bool setAsDefault = true);
544 
556  void clear();
557 
564  void flush(bool waitVSync);
565 
571  int getColumns() { return m_columns; }
572 
578  int getRows() { return m_rows; }
579 
585  void enableCursor(bool value);
586 
592  int availableForWrite();
593 
601  void setTerminalType(TermInfo const * value);
602 
610  void setTerminalType(TermType value);
611 
617  TermInfo const & terminalType() { return *m_termInfo; }
618 
619 
622 
630  int available();
631 
639  int read();
640 
648  int peek();
649 
655  void flush();
656 
677  int write(const uint8_t * buffer, int size);
678 
688  size_t write(uint8_t c);
689 
690  using Print::write;
691 
692 
693 private:
694 
695  void reset();
696  void int_clear();
697  void clearMap(uint32_t * map);
698 
699  void freeFont();
700  void freeTabStops();
701  void freeGlyphsMap();
702 
703  void set132ColumnMode(bool value);
704 
705  bool moveUp();
706  bool moveDown();
707  void setCursorPos(int X, int Y);
708  int getAbsoluteRow(int Y);
709 
710  void int_setBackgroundColor(Color color);
711  void int_setForegroundColor(Color color);
712 
713  // tab stops
714  void nextTabStop();
715  void setTabStop(int column, bool set);
716  void resetTabStops();
717 
718  // scroll control
719  void scrollDown();
720  void scrollDownAt(int startingRow);
721  void scrollUp();
722  void scrollUpAt(int startingRow);
723  void setScrollingRegion(int top, int down, bool resetCursorPos = true);
724  void updateCanvasScrollingRegion();
725 
726  // multilevel save/restore cursor state
727  void saveCursorState();
728  void restoreCursorState();
729  void clearSavedCursorStates();
730 
731  void erase(int X1, int Y1, int X2, int Y2, char c, bool maintainDoubleWidth, bool selective);
732 
733  void consumeInputQueue();
734  void consumeESC();
735  void consumeCSI();
736  void consumeCSIQUOT(int * params, int paramsCount);
737  void consumeCSISPC(int * params, int paramsCount);
738  char consumeParamsAndGetCode(int * params, int * paramsCount, bool * questionMarkFound);
739  void consumeDECPrivateModes(int const * params, int paramsCount, char c);
740  void consumeDCS();
741  void execSGRParameters(int const * params, int paramsCount);
742  void consumeESCVT52();
743 
744  void execCtrlCode(char c);
745 
746  static void charsConsumerTask(void * pvParameters);
747  static void keyboardReaderTask(void * pvParameters);
748 
749  static void blinkTimerFunc(TimerHandle_t xTimer);
750  void blinkText();
751  bool enableBlinkingText(bool value);
752  void blinkCursor();
753  bool int_enableCursor(bool value);
754 
755  char getNextCode(bool processCtrlCodes);
756 
757  void setChar(char c);
758  GlyphOptions getGlyphOptionsAt(int X, int Y);
759 
760  void insertAt(int column, int row, int count);
761  void deleteAt(int column, int row, int count);
762 
763  void reverseVideo(bool value);
764 
765  void refresh();
766  void refresh(int X, int Y);
767  void refresh(int X1, int Y1, int X2, int Y2);
768  void beginRefresh();
769  void endRefresh();
770 
771  void setLineDoubleWidth(int row, int value);
772  int getCharWidthAt(int row);
773  int getColumnsAt(int row);
774 
775  void useAlternateScreenBuffer(bool value);
776 
777  void send(char c);
778  void send(char const * str);
779  void sendCSI();
780  void sendDCS();
781  void sendSS3();
782  void sendCursorKeyCode(char c);
783  void sendKeypadCursorKeyCode(char applicationCode, const char * numericCode);
784 
785  void ANSIDecodeVirtualKey(VirtualKey vk);
786  void VT52DecodeVirtualKey(VirtualKey vk);
787 
788  void convHandleTranslation(uint8_t c);
789  void convSendCtrl(ConvCtrl ctrl);
790  void convQueue(const char * str = nullptr);
791  void TermDecodeVirtualKey(VirtualKey vk);
792 
793 
794  Stream * m_logStream;
795 
796  // characters, characters attributes and characters colors container
797  // you may also call this the "text screen buffer"
798  GlyphsBuffer m_glyphsBuffer;
799 
800  // used to implement alternate screen buffer
801  uint32_t * m_alternateMap;
802 
803  // true when m_alternateMap and m_glyphBuffer.map has been swapped
804  bool m_alternateScreenBuffer;
805 
806  // just to restore cursor X and Y pos when swapping screens (alternate screen)
807  int m_alternateCursorX;
808  int m_alternateCursorY;
809 
810  FontInfo m_font;
811 
812  PaintOptions m_paintOptions;
813  GlyphOptions m_glyphOptions;
814 
815  EmuState m_emuState;
816 
817  Color m_defaultForegroundColor;
818  Color m_defaultBackgroundColor;
819 
820  // states of cursor and blinking text before consumeInputQueue()
821  bool m_prevCursorEnabled;
822  bool m_prevBlinkingTextEnabled;
823 
824  // task that reads and processes incoming characters
825  TaskHandle_t m_charsConsumerTaskHandle;
826 
827  // task that reads keyboard input and send ANSI/VT100 codes to serial port
828  TaskHandle_t m_keyboardReaderTaskHandle;
829 
830  // true = cursor in reverse state (visible), false = cursor invisible
831  volatile bool m_cursorState;
832 
833  // timer used to blink
834  TimerHandle_t m_blinkTimer;
835  volatile SemaphoreHandle_t m_blinkTimerMutex;
836 
837  volatile bool m_blinkingTextVisible; // true = blinking text is currently visible
838  volatile bool m_blinkingTextEnabled;
839 
840  volatile int m_columns;
841  volatile int m_rows;
842 
843  // optional serial port
844  // data from serial port is processed and displayed
845  // keys from keyboard are processed and sent to serial port
846  HardwareSerial * m_serialPort;
847 
848  // contains characters to be processed (from write() calls)
849  QueueHandle_t m_inputQueue;
850 
851  // contains characters received and decoded from keyboard (or as replyes from ANSI-VT queries)
852  QueueHandle_t m_outputQueue;
853 
854  // linked list that contains saved cursor states (first item is the last added)
855  TerminalCursorState * m_savedCursorStateList;
856 
857  // a reset has been requested
858  bool m_resetRequested;
859 
860  bool m_autoXONOFF;
861  bool m_XOFF; // true = XOFF sent
862 
863  // used to implement m_emuState.keyAutorepeat
864  VirtualKey m_lastPressedKey;
865 
866  uint8_t m_convMatchedCount;
867  char m_convMatchedChars[EmuTerminalMaxChars];
868  TermInfoVideoConv const * m_convMatchedItem;
869  TermInfo const * m_termInfo;
870 
871 };
872 
873 
874 } // end of namespace
875 
void connectSerialPort(HardwareSerial &serialPort, bool autoXONXOFF=true)
Connects a remove host using the specified serial port.
Definition: terminal.cpp:135
void flush()
Waits for all codes sent to the display has been processed.
Definition: terminal.cpp:968
void pollSerialPort()
Pools the serial port for incoming data.
Definition: terminal.cpp:974
void setTerminalType(TermInfo const *value)
Sets the terminal type to emulate specifying conversion tables.
Definition: terminal.cpp:1088
void clear()
Clears the screen.
Definition: terminal.cpp:418
Color
This enum defines named colors.
Definition: vgacontroller.h:212
This file contains terminal emulation definitions.
This file contains fabgl::KeyboardClass definition and the Keyboard instance.
void localWrite(uint8_t c)
Injects keys into the keyboard queue.
Definition: terminal.cpp:921
An ANSI-VT100 compatible display terminal.
Definition: terminal.h:400
int available()
Gets the number of codes available in the keyboard queue.
Definition: terminal.cpp:944
void setForegroundColor(Color color, bool setAsDefault=true)
Sets the foreground color.
Definition: terminal.cpp:392
This file contains fabgl::CanvasClass definition and the related Canvas instance. ...
int getRows()
Returns the number of lines.
Definition: terminal.h:578
int availableForWrite()
Determines number of codes that the display input queue can still accept.
Definition: terminal.cpp:1059
VirtualKey
Represents each possible real or derived (SHIFT + real) key.
Definition: fabutils.h:366
void enableCursor(bool value)
Enables or disables cursor.
Definition: terminal.cpp:499
Definition: canvas.cpp:47
void begin()
Initializes the terminal.
Definition: terminal.cpp:85
Specifies various glyph painting options.
Definition: vgacontroller.h:284
void end()
Finalizes the terminal.
Definition: terminal.cpp:224
int getColumns()
Returns the number of columns.
Definition: terminal.h:571
TermType
This enum defines supported terminals.
Definition: terminfo.h:103
TermInfo const & terminalType()
Determines current terminal type.
Definition: terminal.h:617
void setBackgroundColor(Color color, bool setAsDefault=true)
Sets the background color.
Definition: terminal.cpp:377
This file contains FabGL library configuration settings, like number of supported colors...
int peek()
Reads a code from the keyboard without advancing to the next one.
Definition: terminal.cpp:962
int read()
Reads codes from keyboard.
Definition: terminal.cpp:950
void loadFont(FontInfo const *font)
Sets the font to use.
Definition: terminal.cpp:316
void setLogStream(Stream &stream)
Sets the stream where to output debugging logs.
Definition: terminal.h:498
void connectLocally()
Permits using of terminal locally.
Definition: terminal.cpp:153
int write(const uint8_t *buffer, int size)
Sends specified number of codes to the display.
Definition: terminal.cpp:1080
Specifies general paint options.
Definition: vgacontroller.h:483