]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/vkey.cpp
b4cfd7a61e76cf4a94cbe32e32916a188b0802ae
[l4.git] / kernel / fiasco / src / kern / vkey.cpp
1 INTERFACE:
2
3 class Irq_base;
4
5 class Vkey
6 {
7 public:
8   enum Echo_type { Echo_off = 0, Echo_on = 1, Echo_crnl = 2 };
9 };
10
11
12 // ---------------------------------------------------------------------------
13 IMPLEMENTATION:
14
15 #include "irq_chip.h"
16
17 static Irq_base *vkey_irq;
18
19 PUBLIC static
20 void
21 Vkey::irq(Irq_base *i)
22 { vkey_irq = i; }
23
24 // ---------------------------------------------------------------------------
25 IMPLEMENTATION [debug && serial && !ux]:
26
27 #include <cstdio>
28
29 #include "config.h"
30 #include "cpu.h"
31 #include "globals.h"
32 #include "kernel_console.h"
33 #include "keycodes.h"
34 #include "uart.h"
35
36 static Vkey::Echo_type vkey_echo;
37 static char     vkey_buffer[256];
38 static unsigned vkey_tail, vkey_head;
39 static Console *uart = Kconsole::console()->find_console(Console::UART);
40
41 PUBLIC static
42 void
43 Vkey::set_echo(Echo_type echo)
44 {
45   vkey_echo = echo;
46 }
47
48 PRIVATE static
49 bool
50 Vkey::add(int c)
51 {
52   bool hit = false;
53   unsigned nh = (vkey_head + 1) % sizeof(vkey_buffer);
54   unsigned oh = vkey_head;
55   if (nh != vkey_tail)
56     {
57       vkey_buffer[vkey_head] = c;
58       vkey_head = nh;
59     }
60
61   if (oh == vkey_tail)
62     hit = true;
63
64   if (vkey_echo == Vkey::Echo_crnl && c == '\r')
65     c = '\n';
66
67   if (vkey_echo)
68     putchar(c);
69
70   return hit;
71 }
72
73 PRIVATE static
74 bool
75 Vkey::add(const char *seq)
76 {
77   bool hit = false;
78   for (; *seq; ++seq)
79     hit |= add(*seq);
80   return hit;
81 }
82
83 PRIVATE static
84 void
85 Vkey::trigger()
86 {
87   if (vkey_irq)
88     vkey_irq->hit(0);
89 }
90
91 PUBLIC static
92 void
93 Vkey::add_char(int v)
94 {
95   if (add(v))
96     trigger();
97 }
98
99 PUBLIC static
100 int
101 Vkey::check_()
102 {
103   if (!uart)
104     return 1;
105
106   int  ret = 1;
107   bool hit = false;
108
109   // disable last branch recording, branch trace recording ...
110   Cpu::cpus.cpu(current_cpu()).debugctl_disable();
111
112   while (1)
113     {
114       int c = uart->getchar(false);
115
116       if (c == -1)
117         break;
118
119       if (c == KEY_ESC)
120         {
121           ret = 0;  // break into kernel debugger
122           break;
123         }
124
125       switch (c)
126         {
127         case KEY_CURSOR_UP:    hit |= add("\033[A"); break;
128         case KEY_CURSOR_DOWN:  hit |= add("\033[B"); break;
129         case KEY_CURSOR_LEFT:  hit |= add("\033[D"); break;
130         case KEY_CURSOR_RIGHT: hit |= add("\033[C"); break;
131         case KEY_CURSOR_HOME:  hit |= add("\033[1~"); break;
132         case KEY_CURSOR_END:   hit |= add("\033[4~"); break;
133         case KEY_PAGE_UP:      hit |= add("\033[5~"); break;
134         case KEY_PAGE_DOWN:    hit |= add("\033[6~"); break;
135         case KEY_INSERT:       hit |= add("\033[2~"); break;
136         case KEY_DELETE:       hit |= add("\033[3~"); break;
137         case KEY_F1:           hit |= add("\033OP"); break;
138         case KEY_BACKSPACE:    hit |= add(127); break;
139         case KEY_TAB:          hit |= add(9); break;
140         case KEY_ESC:          hit |= add(27); break;
141         case KEY_RETURN:       hit |= add(13); break;
142         default:               hit |= add(c); break;
143         }
144     }
145
146   if (hit)
147     trigger();
148
149   // Hmmm, we assume that a console with the UART flag set is of type Uart
150   if (Config::serial_esc == Config::SERIAL_ESC_IRQ)
151     static_cast<Uart*>(uart)->enable_rcv_irq();
152
153   // reenable debug stuff (undo debugctl_disable)
154   Cpu::cpus.cpu(current_cpu()).debugctl_enable();
155
156   return ret;
157 }
158
159 PUBLIC static
160 int
161 Vkey::get()
162 {
163   if (vkey_tail != vkey_head)
164     return vkey_buffer[vkey_tail];
165
166   return -1;
167 }
168
169 PUBLIC static
170 void
171 Vkey::clear()
172 {
173   if (vkey_tail != vkey_head)
174     vkey_tail = (vkey_tail + 1) % sizeof(vkey_buffer);
175 }
176
177 //----------------------------------------------------------------------------
178 IMPLEMENTATION [!debug || !serial || ux]:
179
180 PUBLIC static inline
181 void
182 Vkey::set_echo(Echo_type)
183 {}
184
185 PUBLIC static inline
186 void
187 Vkey::clear()
188 {}
189
190 PUBLIC static inline
191 void
192 Vkey::add_char(int)
193 {}
194
195 //----------------------------------------------------------------------------
196 IMPLEMENTATION [debug && (!serial || ux)]:
197
198 #include "kernel_console.h"
199
200 PUBLIC static
201 int
202 Vkey::get()
203 {
204   return Kconsole::console()->getchar(0);
205 }
206
207 //----------------------------------------------------------------------------
208 IMPLEMENTATION [!debug && serial]:
209
210 #include "kernel_console.h"
211 #include "kernel_uart.h"
212
213 static Console *uart = Kconsole::console()->find_console(Console::UART);
214
215 PUBLIC static
216 int
217 Vkey::get()
218 {
219   return uart->getchar(false);
220 }
221
222 //----------------------------------------------------------------------------
223 IMPLEMENTATION[!debug && !serial]:
224
225 PUBLIC static
226 int
227 Vkey::get()
228 { return -1; }
229
230 //----------------------------------------------------------------------------
231 IMPLEMENTATION[!debug || !serial]:
232
233 PUBLIC static inline
234 int
235 Vkey::check_(int = -1)
236 { return 0; }