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 
46 #include "Stream.h"
47 
48 
49 
215 namespace fabgl {
216 
217 
218 
219 
220 // used by saveCursorState / restoreCursorState
221 struct TerminalCursorState {
222  TerminalCursorState * next;
223  int16_t cursorX;
224  int16_t cursorY;
225  uint8_t * tabStop;
226  bool cursorPastLastCol;
227  bool originMode;
228  GlyphOptions glyphOptions;
229  uint8_t characterSetIndex;
230  uint8_t characterSet[4];
231 };
232 
233 
234 enum KeypadMode {
235  Application, // DECKPAM
236  Numeric, // DECKPNM
237 };
238 
239 
240 struct EmuState {
241 
242  // Index of characterSet[], 0 = G0 (Standard) 1 = G1 (Alternate), 2 = G2, 3 = G3
243  uint8_t characterSetIndex;
244 
245  // 0 = DEC Special Character and Line Drawing 1 = United States (USASCII)
246  uint8_t characterSet[4];
247 
248  Color foregroundColor;
249  Color backgroundColor;
250 
251  // cursor position (topleft = 1,1)
252  int cursorX;
253  int cursorY;
254 
255  bool cursorPastLastCol;
256 
257  bool originMode;
258 
259  bool wraparound;
260 
261  // top and down scrolling regions (1 = first row)
262  int scrollingRegionTop;
263  int scrollingRegionDown;
264 
265  bool cursorEnabled;
266 
267  // true = blinking cursor, false = steady cursor
268  bool cursorBlinkingEnabled;
269 
270  // 0,1,2 = block 3,4 = underline 5,6 = bar
271  int cursorStyle;
272 
273  // column 1 at m_emuState.tabStop[0], column 2 at m_emuState.tabStop[1], etc... 0=no tab stop, 1 = tab stop
274  uint8_t * tabStop;
275 
276  // IRM (Insert Mode)
277  bool insertMode;
278 
279  // NLM (Automatic CR LF)
280  bool newLineMode;
281 
282  // DECSCLM (Smooth scroll)
283  // Smooth scroll is effective only when vertical sync refresh is enabled,
284  // hence must be VGAController.enableBackgroundPrimitiveExecution(true),
285  // that is the default.
286  bool smoothScroll;
287 
288  // DECKPAM (Keypad Application Mode)
289  // DECKPNM (Keypad Numeric Mode)
290  KeypadMode keypadMode;
291 
292  // DECCKM (Cursor Keys Mode)
293  bool cursorKeysMode;
294 
295  // DESSCL (1 = VT100 ... 5 = VT500)
296  int conformanceLevel;
297 
298  // two values allowed: 7 and 8
299  int ctrlBits;
300 
301  bool keyAutorepeat;
302 
303  bool allow132ColumnMode;
304 
305  bool reverseWraparoundMode;
306 
307  // DECBKM (false = BACKSPACE sends BS, false BACKSPACE sends DEL)
308  bool backarrowKeyMode;
309 
310  // DECANM (false = VT52 mode, true = ANSI mode)
311  bool ANSIMode;
312 
313  // VT52 Graphics Mode
314  bool VT52GraphicsMode;
315 };
316 
317 
318 
399 class TerminalClass : public Stream {
400 
401 public:
402 
408  void begin();
409 
415  void end();
416 
434  void connectSerialPort(HardwareSerial & serialPort, bool autoXONXOFF = true);
435 
449  void pollSerialPort();
450 
464  void connectLocally();
465 
473  void localWrite(uint8_t c);
474 
482  void localWrite(char const * str);
483 
497  void setLogStream(Stream & stream) { m_logStream = &stream; }
498 
499  void logFmt(const char * format, ...);
500  void log(const char * txt);
501  void log(char c);
502 
512  void loadFont(FontInfo const * font);
513 
527  void setBackgroundColor(Color color, bool setAsDefault = true);
528 
542  void setForegroundColor(Color color, bool setAsDefault = true);
543 
555  void clear();
556 
563  void flush(bool waitVSync);
564 
570  int getColumns() { return m_columns; }
571 
577  int getRows() { return m_rows; }
578 
584  void enableCursor(bool value);
585 
591  int availableForWrite();
592 
593 
596 
604  int available();
605 
613  int read();
614 
622  int peek();
623 
629  void flush();
630 
651  int write(const uint8_t * buffer, int size);
652 
662  size_t write(uint8_t c);
663 
664  using Print::write;
665 
666 
667 private:
668 
669  void reset();
670  void int_clear();
671  void clearMap(uint32_t * map);
672 
673  void freeFont();
674  void freeTabStops();
675  void freeGlyphsMap();
676 
677  void set132ColumnMode(bool value);
678 
679  bool moveUp();
680  bool moveDown();
681  void setCursorPos(int X, int Y);
682  int getAbsoluteRow(int Y);
683 
684  void int_setBackgroundColor(Color color);
685  void int_setForegroundColor(Color color);
686 
687  // tab stops
688  void nextTabStop();
689  void setTabStop(int column, bool set);
690  void resetTabStops();
691 
692  // scroll control
693  void scrollDown();
694  void scrollDownAt(int startingRow);
695  void scrollUp();
696  void scrollUpAt(int startingRow);
697  void setScrollingRegion(int top, int down, bool resetCursorPos = true);
698  void updateCanvasScrollingRegion();
699 
700  // multilevel save/restore cursor state
701  void saveCursorState();
702  void restoreCursorState();
703  void clearSavedCursorStates();
704 
705  void erase(int X1, int Y1, int X2, int Y2, char c, bool maintainDoubleWidth, bool selective);
706 
707  void consumeInputQueue();
708  void consumeESC();
709  void consumeCSI();
710  void consumeCSIQUOT(int * params, int paramsCount);
711  void consumeCSISPC(int * params, int paramsCount);
712  char consumeParamsAndGetCode(int * params, int * paramsCount, bool * questionMarkFound);
713  void consumeDECPrivateModes(int const * params, int paramsCount, char c);
714  void consumeDCS();
715  void execSGRParameters(int const * params, int paramsCount);
716  void consumeESCVT52();
717 
718  void execCtrlCode(char c);
719 
720  static void charsConsumerTask(void * pvParameters);
721  static void keyboardReaderTask(void * pvParameters);
722 
723  static void blinkTimerFunc(TimerHandle_t xTimer);
724  void blinkText();
725  bool enableBlinkingText(bool value);
726  void blinkCursor();
727  bool int_enableCursor(bool value);
728 
729  char getNextCode(bool processCtrlCodes);
730 
731  void setChar(char c);
732  GlyphOptions getGlyphOptionsAt(int X, int Y);
733 
734  void insertAt(int column, int row, int count);
735  void deleteAt(int column, int row, int count);
736 
737  void reverseVideo(bool value);
738 
739  void refresh();
740  void refresh(int X, int Y);
741  void refresh(int X1, int Y1, int X2, int Y2);
742  void beginRefresh();
743  void endRefresh();
744 
745  void setLineDoubleWidth(int row, int value);
746  int getCharWidthAt(int row);
747  int getColumnsAt(int row);
748 
749  void useAlternateScreenBuffer(bool value);
750 
751  void send(char c);
752  void send(char const * str);
753  void sendCSI();
754  void sendDCS();
755  void sendSS3();
756  void sendCursorKeyCode(char c);
757  void sendKeypadCursorKeyCode(char applicationCode, const char * numericCode);
758 
759  void ANSIDecodeVirtualKey(VirtualKey vk);
760  void VT52DecodeVirtualKey(VirtualKey vk);
761 
762  Stream * m_logStream;
763 
764  // characters, characters attributes and characters colors container
765  // you may also call this the "text screen buffer"
766  GlyphsBuffer m_glyphsBuffer;
767 
768  // used to implement alternate screen buffer
769  uint32_t * m_alternateMap;
770 
771  // true when m_alternateMap and m_glyphBuffer.map has been swapped
772  bool m_alternateScreenBuffer;
773 
774  // just to restore cursor X and Y pos when swapping screens (alternate screen)
775  int m_alternateCursorX;
776  int m_alternateCursorY;
777 
778  FontInfo m_font;
779 
780  PaintOptions m_paintOptions;
781  GlyphOptions m_glyphOptions;
782 
783  EmuState m_emuState;
784 
785  Color m_defaultForegroundColor;
786  Color m_defaultBackgroundColor;
787 
788  // states of cursor and blinking text before consumeInputQueue()
789  bool m_prevCursorEnabled;
790  bool m_prevBlinkingTextEnabled;
791 
792  // task that reads and processes incoming characters
793  TaskHandle_t m_charsConsumerTaskHandle;
794 
795  // task that reads keyboard input and send ANSI/VT100 codes to serial port
796  TaskHandle_t m_keyboardReaderTaskHandle;
797 
798  // true = cursor in reverse state (visible), false = cursor invisible
799  volatile bool m_cursorState;
800 
801  // timer used to blink
802  TimerHandle_t m_blinkTimer;
803  volatile SemaphoreHandle_t m_blinkTimerMutex;
804 
805  volatile bool m_blinkingTextVisible; // true = blinking text is currently visible
806  volatile bool m_blinkingTextEnabled;
807 
808  volatile int m_columns;
809  volatile int m_rows;
810 
811  // optional serial port
812  // data from serial port is processed and displayed
813  // keys from keyboard are processed and sent to serial port
814  HardwareSerial * m_serialPort;
815 
816  // contains characters to be processed (from write() calls)
817  QueueHandle_t m_inputQueue;
818 
819  // contains characters received and decoded from keyboard (or as replyed to ANSI-VT queries)
820  QueueHandle_t m_outputQueue;
821 
822  // linked list that contains saved cursor states (first item is the last added)
823  TerminalCursorState * m_savedCursorStateList;
824 
825  // a reset has been requested
826  bool m_resetRequested;
827 
828  bool m_autoXONOFF;
829  bool m_XOFF; // true = XOFF sent
830 
831  // used to implement m_emuState.keyAutorepeat
832  VirtualKey m_lastPressedKey;
833 
834 };
835 
836 
837 } // end of namespace
838 
void connectSerialPort(HardwareSerial &serialPort, bool autoXONXOFF=true)
Connects a remove host using the specified serial port.
Definition: terminal.cpp:132
void flush()
Waits for all codes sent to the display has been processed.
Definition: terminal.cpp:963
void pollSerialPort()
Pools the serial port for incoming data.
Definition: terminal.cpp:969
void clear()
Clears the screen.
Definition: terminal.cpp:413
Color
This enum defines named colors.
Definition: vgacontroller.h:212
This file contains fabgl::KeyboardClass definition and the Keyboard instance.
void localWrite(uint8_t c)
Injects keys into the keyboard queue.
Definition: terminal.cpp:916
An ANSI-VT100 compatible display terminal.
Definition: terminal.h:399
int available()
Gets the number of codes available in the keyboard queue.
Definition: terminal.cpp:939
void setForegroundColor(Color color, bool setAsDefault=true)
Sets the foreground color.
Definition: terminal.cpp:387
This file contains fabgl::CanvasClass definition and the related Canvas instance. ...
int getRows()
Returns the number of lines.
Definition: terminal.h:577
int availableForWrite()
Determines number of codes that the display input queue can still accept.
Definition: terminal.cpp:1054
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:494
Definition: canvas.cpp:47
void begin()
Initializes the terminal.
Definition: terminal.cpp:84
Specifies various glyph painting options.
Definition: vgacontroller.h:284
void end()
Finalizes the terminal.
Definition: terminal.cpp:221
int getColumns()
Returns the number of columns.
Definition: terminal.h:570
void setBackgroundColor(Color color, bool setAsDefault=true)
Sets the background color.
Definition: terminal.cpp:371
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:957
int read()
Reads codes from keyboard.
Definition: terminal.cpp:945
void loadFont(FontInfo const *font)
Sets the font to use.
Definition: terminal.cpp:310
void setLogStream(Stream &stream)
Sets the stream where to output debugging logs.
Definition: terminal.h:497
void connectLocally()
Permits using of terminal locally.
Definition: terminal.cpp:150
int write(const uint8_t *buffer, int size)
Sends specified number of codes to the display.
Definition: terminal.cpp:1072
Specifies general paint options.
Definition: vgacontroller.h:483