Terminal.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Noncopyable.h>
  8. #include <AK/NonnullOwnPtrVector.h>
  9. #include <AK/String.h>
  10. #include <AK/Vector.h>
  11. #include <Kernel/API/KeyCode.h>
  12. #include <LibVT/EscapeSequenceParser.h>
  13. #include <LibVT/Position.h>
  14. #ifndef KERNEL
  15. # include <LibVT/Attribute.h>
  16. # include <LibVT/Line.h>
  17. #else
  18. namespace Kernel {
  19. class VirtualConsole;
  20. }
  21. # include <LibVT/Attribute.h>
  22. #endif
  23. namespace VT {
  24. class TerminalClient {
  25. public:
  26. virtual ~TerminalClient() { }
  27. virtual void beep() = 0;
  28. virtual void set_window_title(const StringView&) = 0;
  29. virtual void set_window_progress(int value, int max) = 0;
  30. virtual void terminal_did_resize(u16 columns, u16 rows) = 0;
  31. virtual void terminal_history_changed() = 0;
  32. virtual void emit(const u8*, size_t) = 0;
  33. };
  34. class Terminal : public EscapeSequenceExecutor {
  35. public:
  36. #ifndef KERNEL
  37. explicit Terminal(TerminalClient&);
  38. #else
  39. explicit Terminal(Kernel::VirtualConsole&);
  40. #endif
  41. virtual ~Terminal()
  42. {
  43. }
  44. bool m_need_full_flush { false };
  45. #ifndef KERNEL
  46. void invalidate_cursor();
  47. #else
  48. virtual void invalidate_cursor() = 0;
  49. #endif
  50. void on_input(u8);
  51. void set_cursor(unsigned row, unsigned column);
  52. #ifndef KERNEL
  53. void clear();
  54. void clear_including_history();
  55. #else
  56. virtual void clear() = 0;
  57. virtual void clear_including_history() = 0;
  58. #endif
  59. #ifndef KERNEL
  60. void set_size(u16 columns, u16 rows);
  61. #else
  62. virtual void set_size(u16 columns, u16 rows) = 0;
  63. #endif
  64. u16 columns() const
  65. {
  66. return m_columns;
  67. }
  68. u16 rows() const { return m_rows; }
  69. u16 cursor_column() const { return m_cursor_column; }
  70. u16 cursor_row() const { return m_cursor_row; }
  71. #ifndef KERNEL
  72. size_t line_count() const
  73. {
  74. return m_history.size() + m_lines.size();
  75. }
  76. Line& line(size_t index)
  77. {
  78. if (index < m_history.size())
  79. return m_history[(m_history_start + index) % m_history.size()];
  80. return m_lines[index - m_history.size()];
  81. }
  82. const Line& line(size_t index) const
  83. {
  84. return const_cast<Terminal*>(this)->line(index);
  85. }
  86. Line& visible_line(size_t index)
  87. {
  88. return m_lines[index];
  89. }
  90. const Line& visible_line(size_t index) const
  91. {
  92. return m_lines[index];
  93. }
  94. size_t max_history_size() const { return m_max_history_lines; }
  95. void set_max_history_size(size_t value)
  96. {
  97. if (value == 0) {
  98. m_max_history_lines = 0;
  99. m_history_start = 0;
  100. m_history.clear();
  101. m_client.terminal_history_changed();
  102. return;
  103. }
  104. if (m_max_history_lines > value) {
  105. NonnullOwnPtrVector<Line> new_history;
  106. new_history.ensure_capacity(value);
  107. auto existing_line_count = min(m_history.size(), value);
  108. for (size_t i = m_history.size() - existing_line_count; i < m_history.size(); ++i) {
  109. auto j = (m_history_start + i) % m_history.size();
  110. new_history.unchecked_append(move(static_cast<Vector<NonnullOwnPtr<Line>>&>(m_history).at(j)));
  111. }
  112. m_history = move(new_history);
  113. m_history_start = 0;
  114. m_client.terminal_history_changed();
  115. }
  116. m_max_history_lines = value;
  117. }
  118. size_t history_size() const { return m_history.size(); }
  119. #endif
  120. void inject_string(const StringView&);
  121. void handle_key_press(KeyCode, u32, u8 flags);
  122. #ifndef KERNEL
  123. Attribute attribute_at(const Position&) const;
  124. #endif
  125. protected:
  126. // ^EscapeSequenceExecutor
  127. virtual void emit_code_point(u32) override;
  128. virtual void execute_control_code(u8) override;
  129. virtual void execute_escape_sequence(Intermediates intermediates, bool ignore, u8 last_byte) override;
  130. virtual void execute_csi_sequence(Parameters parameters, Intermediates intermediates, bool ignore, u8 last_byte) override;
  131. virtual void execute_osc_sequence(OscParameters parameters, u8 last_byte) override;
  132. virtual void dcs_hook(Parameters parameters, Intermediates intermediates, bool ignore, u8 last_byte) override;
  133. virtual void receive_dcs_char(u8 byte) override;
  134. virtual void execute_dcs_sequence() override;
  135. void carriage_return();
  136. #ifndef KERNEL
  137. void scroll_up();
  138. void scroll_down();
  139. void linefeed();
  140. void put_character_at(unsigned row, unsigned column, u32 ch);
  141. void set_window_title(const String&);
  142. #else
  143. virtual void scroll_up() = 0;
  144. virtual void scroll_down() = 0;
  145. virtual void linefeed() = 0;
  146. virtual void put_character_at(unsigned row, unsigned column, u32 ch) = 0;
  147. virtual void set_window_title(const String&) = 0;
  148. #endif
  149. void unimplemented_control_code(u8);
  150. void unimplemented_escape_sequence(Intermediates, u8 last_byte);
  151. void unimplemented_csi_sequence(Parameters, Intermediates, u8 last_byte);
  152. void unimplemented_osc_sequence(OscParameters, u8 last_byte);
  153. void emit_string(const StringView&);
  154. void alter_mode(bool should_set, Parameters, Intermediates);
  155. // CUU – Cursor Up
  156. void CUU(Parameters);
  157. // CUD – Cursor Down
  158. void CUD(Parameters);
  159. // CUF – Cursor Forward
  160. void CUF(Parameters);
  161. // CUB – Cursor Backward
  162. void CUB(Parameters);
  163. // CUP - Cursor Position
  164. void CUP(Parameters);
  165. // ED - Erase in Display
  166. void ED(Parameters);
  167. // EL - Erase in Line
  168. void EL(Parameters);
  169. // SGR – Select Graphic Rendition
  170. void SGR(Parameters);
  171. // Save Current Cursor Position
  172. void SCOSC();
  173. // Restore Saved Cursor Position
  174. void SCORC(Parameters);
  175. // DECSTBM – Set Top and Bottom Margins ("Scrolling Region")
  176. void DECSTBM(Parameters);
  177. // RM – Reset Mode
  178. void RM(Parameters, Intermediates);
  179. // SM – Set Mode
  180. void SM(Parameters, Intermediates);
  181. // DA - Device Attributes
  182. void DA(Parameters);
  183. // HVP – Horizontal and Vertical Position
  184. void HVP(Parameters);
  185. // NEL - Next Line
  186. void NEL();
  187. // IND - Index (move down)
  188. void IND();
  189. // RI - Reverse Index (move up)
  190. void RI();
  191. // DSR - Device Status Reports
  192. void DSR(Parameters);
  193. #ifndef KERNEL
  194. // ICH - Insert Character
  195. void ICH(Parameters);
  196. #else
  197. virtual void ICH(Parameters) = 0;
  198. #endif
  199. // SU - Scroll Up (called "Pan Down" in VT510)
  200. void SU(Parameters);
  201. // SD - Scroll Down (called "Pan Up" in VT510)
  202. void SD(Parameters);
  203. #ifndef KERNEL
  204. // IL - Insert Line
  205. void IL(Parameters);
  206. // DCH - Delete Character
  207. void DCH(Parameters);
  208. // DL - Delete Line
  209. void DL(Parameters);
  210. #else
  211. virtual void IL(Parameters) = 0;
  212. virtual void DCH(Parameters) = 0;
  213. virtual void DL(Parameters) = 0;
  214. #endif
  215. // CHA - Cursor Horizontal Absolute
  216. void CHA(Parameters);
  217. // REP - Repeat
  218. void REP(Parameters);
  219. // VPA - Vertical Line Position Absolute
  220. void VPA(Parameters);
  221. // ECH - Erase Character
  222. void ECH(Parameters);
  223. // FIXME: Find the right names for these.
  224. void XTERM_WM(Parameters);
  225. #ifndef KERNEL
  226. TerminalClient& m_client;
  227. #else
  228. Kernel::VirtualConsole& m_client;
  229. #endif
  230. EscapeSequenceParser m_parser;
  231. #ifndef KERNEL
  232. size_t m_history_start = 0;
  233. NonnullOwnPtrVector<Line> m_history;
  234. void add_line_to_history(NonnullOwnPtr<Line>&& line)
  235. {
  236. if (max_history_size() == 0)
  237. return;
  238. if (m_history.size() < max_history_size()) {
  239. VERIFY(m_history_start == 0);
  240. m_history.append(move(line));
  241. return;
  242. }
  243. m_history.ptr_at(m_history_start) = move(line);
  244. m_history_start = (m_history_start + 1) % m_history.size();
  245. }
  246. NonnullOwnPtrVector<Line> m_lines;
  247. #endif
  248. size_t m_scroll_region_top { 0 };
  249. size_t m_scroll_region_bottom { 0 };
  250. u16 m_columns { 1 };
  251. u16 m_rows { 1 };
  252. u16 m_cursor_row { 0 };
  253. u16 m_cursor_column { 0 };
  254. u16 m_saved_cursor_row { 0 };
  255. u16 m_saved_cursor_column { 0 };
  256. bool m_swallow_current { false };
  257. bool m_stomp { false };
  258. Attribute m_current_attribute;
  259. Attribute m_saved_attribute;
  260. #ifndef KERNEL
  261. u32 m_next_href_id { 0 };
  262. #endif
  263. Vector<bool> m_horizontal_tabs;
  264. u32 m_last_code_point { 0 };
  265. size_t m_max_history_lines { 1024 };
  266. };
  267. }