30 |
30 |
31 #include <string.h> |
31 #include <string.h> |
32 #include "interface.h" |
32 #include "interface.h" |
33 #include "network/rconsession.h" |
33 #include "network/rconsession.h" |
34 #include "network/ipaddress.h" |
34 #include "network/ipaddress.h" |
35 |
35 #include "coloredline.h" |
36 enum |
|
37 { |
|
38 RLINE_ON_BLACK = 256, |
|
39 RLINE_ON_RED, |
|
40 RLINE_ON_GREEN, |
|
41 RLINE_ON_YELLOW, |
|
42 RLINE_ON_BLUE, |
|
43 RLINE_ON_MAGENTA, |
|
44 RLINE_ON_CYAN, |
|
45 RLINE_ON_WHITE, |
|
46 RLINE_ON_BOLD, |
|
47 RLINE_OFF_BLACK, |
|
48 RLINE_OFF_RED, |
|
49 RLINE_OFF_GREEN, |
|
50 RLINE_OFF_YELLOW, |
|
51 RLINE_OFF_BLUE, |
|
52 RLINE_OFF_MAGENTA, |
|
53 RLINE_OFF_CYAN, |
|
54 RLINE_OFF_WHITE, |
|
55 RLINE_OFF_BOLD, |
|
56 }; |
|
57 |
|
58 class RendererLine |
|
59 { |
|
60 public: |
|
61 RendererLine() {} |
|
62 |
|
63 METHOD data() const -> const Vector<int>& { return m_data; } |
|
64 METHOD length() const -> int { return m_length; } |
|
65 METHOD add_char (char ch) -> void; |
|
66 METHOD finalize() -> void; |
|
67 METHOD rows (int cols) const -> int; |
|
68 |
|
69 private: |
|
70 METHOD set_color (Color a, bool on) -> void; |
|
71 |
|
72 Vector<int> m_data; |
|
73 int m_length = 0; |
|
74 bool m_final = false; |
|
75 Color m_activeColor = DEFAULT; |
|
76 bool m_boldActive = false; |
|
77 int m_colorCodeStage = 0; |
|
78 String m_string; |
|
79 }; |
|
80 |
36 |
81 static const int g_pageSize = 10; |
37 static const int g_pageSize = 10; |
82 |
38 |
83 enum InputState |
39 enum InputState |
84 { |
40 { |
95 static bool g_needRefresh = false; |
51 static bool g_needRefresh = false; |
96 static bool g_needStatusBarRender = false; |
52 static bool g_needStatusBarRender = false; |
97 static bool g_needInputRender = false; |
53 static bool g_needInputRender = false; |
98 static bool g_needOutputRender = false; |
54 static bool g_needOutputRender = false; |
99 static struct { char ch; int x; } g_cursorChar; |
55 static struct { char ch; int x; } g_cursorChar; |
100 static Vector<RendererLine> g_output;; |
56 static Vector<ColoredLine> g_output;; |
101 static int g_outputScroll = 0; |
57 static int g_outputScroll = 0; |
102 static String g_title; |
58 static String g_title; |
103 static InputState g_inputState = INPUTSTATE_NORMAL; |
59 static InputState g_inputState = INPUTSTATE_NORMAL; |
104 static Function<void (void)> g_disconnectConfirmFunction = nullptr; |
60 static Function<void (void)> g_disconnectConfirmFunction = nullptr; |
105 static IPAddress g_address; |
61 static IPAddress g_address; |
106 static String g_statusBarText; |
62 static String g_statusBarText; |
107 |
|
108 static const struct { Color color; bool bold; } g_colorCodes['v' - 'a' + 1] = |
|
109 { |
|
110 { RED, true }, // a - brick |
|
111 { YELLOW, true }, // b - tan |
|
112 { WHITE, false }, // c - gray |
|
113 { GREEN, true }, // d - light green |
|
114 { YELLOW, false }, // e - brown |
|
115 { YELLOW, true }, // f - gold yellow |
|
116 { RED, true }, // g - bright red |
|
117 { BLUE, false }, // h - dark blue |
|
118 { YELLOW, false }, // i - orange |
|
119 { WHITE, true }, // j - white |
|
120 { YELLOW, true }, // k - fire yellow |
|
121 { DEFAULT, false }, // l - untranslated |
|
122 { BLACK, false }, // m - black |
|
123 { BLUE, true }, // n - light blue |
|
124 { YELLOW, true }, // o - cream |
|
125 { GREEN, true }, // p - olive green |
|
126 { GREEN, false }, // q - dark green |
|
127 { RED, false }, // r - dark red |
|
128 { YELLOW, false }, // s - dark brown |
|
129 { MAGENTA, false }, // t - purple |
|
130 { BLACK, true }, // u - dark gray |
|
131 { CYAN, true }, // v - cyan |
|
132 }; |
|
133 |
63 |
134 // ------------------------------------------------------------------------------------------------- |
64 // ------------------------------------------------------------------------------------------------- |
135 // |
65 // |
136 static FUNCTION |
66 static FUNCTION |
137 interface_color_pair (Color fg, Color bg) -> int |
67 interface_color_pair (Color fg, Color bg) -> int |
938 |
868 |
939 RCONSession* session = RCONSession::new_session(); |
869 RCONSession* session = RCONSession::new_session(); |
940 session->set_password (password); |
870 session->set_password (password); |
941 session->connect (g_address); |
871 session->connect (g_address); |
942 } |
872 } |
943 |
|
944 // ------------------------------------------------------------------------------------------------- |
|
945 // |
|
946 METHOD |
|
947 RendererLine::finalize() -> void |
|
948 { |
|
949 if (m_activeColor != DEFAULT) |
|
950 this->set_color (m_activeColor, false); |
|
951 |
|
952 if (m_boldActive) |
|
953 m_data << RLINE_OFF_BOLD; |
|
954 |
|
955 m_final = true; |
|
956 } |
|
957 |
|
958 // ------------------------------------------------------------------------------------------------- |
|
959 // |
|
960 METHOD |
|
961 RendererLine::add_char (char ch) -> void |
|
962 { |
|
963 if (m_final) |
|
964 return; // Don't touch finalized lines. |
|
965 |
|
966 if (ch == '\x1C' and m_colorCodeStage == 0) |
|
967 { |
|
968 m_colorCodeStage = 1; |
|
969 return; |
|
970 } |
|
971 |
|
972 if (m_colorCodeStage == 1) |
|
973 { |
|
974 if (m_activeColor != DEFAULT) |
|
975 this->set_color (m_activeColor, false); |
|
976 |
|
977 if (m_boldActive) |
|
978 m_data << RLINE_OFF_BOLD; |
|
979 |
|
980 if (ch >= 'a' and ch <= 'v' and ch != 'l') |
|
981 { |
|
982 auto colorInfo = g_colorCodes[ch - 'a']; |
|
983 m_activeColor = colorInfo.color; |
|
984 m_boldActive = colorInfo.bold; |
|
985 assert (m_activeColor < 8); |
|
986 this->set_color (m_activeColor, true); |
|
987 |
|
988 if (m_boldActive) |
|
989 m_data << RLINE_ON_BOLD; |
|
990 } |
|
991 |
|
992 m_colorCodeStage = 0; |
|
993 return; |
|
994 } |
|
995 |
|
996 if (isprint (ch)) |
|
997 { |
|
998 m_string += ch; |
|
999 m_data << int (ch); |
|
1000 ++m_length; |
|
1001 } |
|
1002 } |
|
1003 |
|
1004 // ------------------------------------------------------------------------------------------------- |
|
1005 // |
|
1006 METHOD |
|
1007 RendererLine::set_color (Color a, bool on) -> void |
|
1008 { |
|
1009 switch (a) |
|
1010 { |
|
1011 case BLACK: m_data << (on ? RLINE_ON_BLACK : RLINE_OFF_BLACK); break; |
|
1012 case RED: m_data << (on ? RLINE_ON_RED : RLINE_OFF_RED); break; |
|
1013 case GREEN: m_data << (on ? RLINE_ON_GREEN : RLINE_OFF_GREEN); break; |
|
1014 case YELLOW: m_data << (on ? RLINE_ON_YELLOW : RLINE_OFF_YELLOW); break; |
|
1015 case BLUE: m_data << (on ? RLINE_ON_BLUE : RLINE_OFF_BLUE); break; |
|
1016 case MAGENTA: m_data << (on ? RLINE_ON_MAGENTA : RLINE_OFF_MAGENTA); break; |
|
1017 case CYAN: m_data << (on ? RLINE_ON_CYAN : RLINE_OFF_CYAN); break; |
|
1018 case WHITE: m_data << (on ? RLINE_ON_WHITE : RLINE_OFF_WHITE); break; |
|
1019 case NUM_COLORS: |
|
1020 case DEFAULT: assert (false); break; |
|
1021 } |
|
1022 } |
|
1023 |
|
1024 // ------------------------------------------------------------------------------------------------- |
|
1025 // How many rows does this line take up? |
|
1026 // |
|
1027 METHOD |
|
1028 RendererLine::rows (int cols) const -> int |
|
1029 { |
|
1030 int rows = length() / cols; |
|
1031 |
|
1032 if (length() % cols != 0) |
|
1033 rows++; |
|
1034 |
|
1035 return max (rows, 1); |
|
1036 } |
|