Max OS 0.3
Loading...
Searching...
No Matches
keyboard.cpp
Go to the documentation of this file.
1
10
11using namespace MaxOS;
12using namespace MaxOS::common;
13using namespace MaxOS::drivers;
14using namespace MaxOS::drivers::peripherals;
15using namespace MaxOS::hardwarecommunication;
16
17KeyboardEventHandler::KeyboardEventHandler() = default;
18
19KeyboardEventHandler::~KeyboardEventHandler() = default;
20
29
38
46
47 switch (event->type) {
48
49 case KeyboardEvents::KEYDOWN:
50 this->on_key_down(((KeyDownEvent *) event)->key_code, ((KeyDownEvent *) event)->keyboard_state);
51 break;
52
53 case KeyboardEvents::KEYUP:
54 this->on_key_up(((KeyUpEvent *) event)->key_code, ((KeyUpEvent *) event)->keyboard_state);
55 break;
56
57 default:
58 break;
59 }
60
61 return event;
62}
63
68: InterruptHandler(0x21, 0x1, 0x12),
69 m_data_port(0x60),
70 m_command_port(0x64)
71{
72
73
74}
75
76KeyboardDriver::~KeyboardDriver() = default;
77
82
83 // Wait for user to stop pressing key (this is for the start-up key e.g. hold 'F12' for boot menu or hold 'del' for bios )
84 while (m_command_port.read() & 0x1)
85 m_data_port.read();
86
87 // Enable keyboard interrupts
88 m_command_port.write(0xAE);
89
90 // Get the current state of the keyboard
91 m_command_port.write(0x20);
92 uint8_t status = (m_data_port.read() | 1) & ~0x10;
93
94 // Reset the keyboard
95 m_command_port.write(0x60);
96 m_data_port.write(status);
97
98 // Activate the keyboard
99 m_data_port.write(0xF4);
100}
101
106
107 // Pass the scan code to the m_handlers
108 uint8_t key = m_data_port.read();
110 handler->on_stream_read(key);
111}
112
118 return "Keyboard";
119}
120
121KeyboardState::KeyboardState() = default;
122
123KeyboardState::~KeyboardState() = default;
124
133
134KeyboardInterpreter::~KeyboardInterpreter() = default;
135
144
145 // Pass the key event to the handlers
146 if (released)
147 raise_event(new KeyUpEvent(key_code, state));
148 else
149 raise_event(new KeyDownEvent(key_code, state));
150
151}
152
161
162KeyboardInterpreterEN_US::~KeyboardInterpreterEN_US() = default;
163
172
173
174 // Check if the key was released
175 bool released = (scan_code & 0x80)
176 && (m_extended_scan_code_bytes || (scan_code != 0xe1))
178
179 // Clear the released bit
180 if (released)
181 scan_code &= ~0x80;
182
183 // Start of a scan code that takes more than one byte
184 if (scan_code == 0xe0) {
186 return;
187 }
188
189 // Handle extended scan codes
190 ScanCodeType type = ScanCodeType::REGULAR;
192
193 type = ScanCodeType::EXTENDED;
195
196 // Check if the scan_code represents a shift key and return (fake shift)
197 if ((KeyboardInterpreterEN_US::KeyCodeEN_US) scan_code == KeyCodeEN_US::leftShift ||
198 (KeyboardInterpreterEN_US::KeyCodeEN_US) scan_code == KeyCodeEN_US::rightShift)
199 return;
200 }
201
202 // The scan code takes three bytes
203 if (scan_code == 0xe1) {
205 return;
206 }
207
208 // Take the second byte of a three-byte scan code and wait for the last byte (if applicable)
212 return;
213 }
214
215 // Take the last byte of a three-byte scan code
217 type = ScanCodeType::EXTENDED;
220 }
221
222 // Scan code value manipulations
225
226 if (type == ScanCodeType::REGULAR)
227 switch ((KeyCodeEN_US) scan_code) {
228
230 case KeyCodeEN_US::escape:
231 on_key_read(released, this->m_keyboard_state, KeyCode::escape);
232 break;
233
234 case KeyCodeEN_US::f1:
235 on_key_read(released, this->m_keyboard_state, KeyCode::f1);
236 break;
237
238 case KeyCodeEN_US::f2:
239 on_key_read(released, this->m_keyboard_state, KeyCode::f2);
240 break;
241
242 case KeyCodeEN_US::f3:
243 on_key_read(released, this->m_keyboard_state, KeyCode::f3);
244 break;
245
246 case KeyCodeEN_US::f4:
247 on_key_read(released, this->m_keyboard_state, KeyCode::f4);
248 break;
249
250 case KeyCodeEN_US::f5:
251 on_key_read(released, this->m_keyboard_state, KeyCode::f5);
252 break;
253
254 case KeyCodeEN_US::f6:
255 on_key_read(released, this->m_keyboard_state, KeyCode::f6);
256 break;
257
258 case KeyCodeEN_US::f7:
259 on_key_read(released, this->m_keyboard_state, KeyCode::f7);
260 break;
261
262 case KeyCodeEN_US::f8:
263 on_key_read(released, this->m_keyboard_state, KeyCode::f8);
264 break;
265
266 case KeyCodeEN_US::f9:
267 on_key_read(released, this->m_keyboard_state, KeyCode::f9);
268 break;
269
270 case KeyCodeEN_US::f10:
271 on_key_read(released, this->m_keyboard_state, KeyCode::f10);
272 break;
273
274 case KeyCodeEN_US::f11:
275 on_key_read(released, this->m_keyboard_state, KeyCode::f11);
276 break;
277
278 case KeyCodeEN_US::f12:
279 on_key_read(released, this->m_keyboard_state, KeyCode::f12);
280 break;
281
282 case KeyCodeEN_US::printScreen:
283 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadMultiply : KeyCode::printScreen);
284 break;
285
286 case KeyCodeEN_US::scrollLock:
287 on_key_read(released, this->m_keyboard_state, KeyCode::scrollLock);
288 break;
289
291 case KeyCodeEN_US::squigglyLine:
292 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::squigglyLine : KeyCode::slantedApostrophe);
293 break;
294
295 case KeyCodeEN_US::one:
296 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::exclamationMark : KeyCode::one);
297 break;
298
299 case KeyCodeEN_US::two:
300 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::atSign : KeyCode::two);
301 break;
302
303 case KeyCodeEN_US::three:
304 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::hash : KeyCode::three);
305 break;
306
307 case KeyCodeEN_US::four:
308 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::dollarSign : KeyCode::four);
309 break;
310
311 case KeyCodeEN_US::five:
312 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::percentSign : KeyCode::five);
313 break;
314
315 case KeyCodeEN_US::six:
316 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::powerSign : KeyCode::six);
317 break;
318
319 case KeyCodeEN_US::seven:
320 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::andSign : KeyCode::seven);
321 break;
322
323 case KeyCodeEN_US::eight:
324 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::multiply : KeyCode::eight);
325 break;
326
327 case KeyCodeEN_US::nine:
328 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::openBracket : KeyCode::nine);
329 break;
330
331 case KeyCodeEN_US::zero:
332 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::closeBracket : KeyCode::zero);
333 break;
334
335 case KeyCodeEN_US::minus:
336 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::underscore : KeyCode::minus);
337 break;
338
339 case KeyCodeEN_US::equals:
340 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::plus : KeyCode::equals);
341 break;
342
343 case KeyCodeEN_US::backspace:
344 on_key_read(released, this->m_keyboard_state, KeyCode::backspace);
345 break;
346
347 case KeyCodeEN_US::insert:
348 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadZero : KeyCode::insert);
349 break;
350
351 case KeyCodeEN_US::home:
353 ? KeyCode::numberPadSeven : KeyCode::home);
354 break;
355
356 case KeyCodeEN_US::pageUp:
357 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadNine : KeyCode::pageUp);
358 break;
359
360 case KeyCodeEN_US::numberPadLock:
361
362 // Ensure this is not a repeat
363 if (!released) {
365 }
366 on_key_read(released, this->m_keyboard_state, KeyCode::numberPadLock);
367 break;
368
369 case KeyCodeEN_US::numberPadForwardSlash:
370
371 // Check if number pad lock is on
373 on_key_read(released, this->m_keyboard_state, KeyCode::numberPadForwardSlash);
374 } else {
375
376 // Normal Forward Slash
378 should_be_upper_case ? KeyCode::questionMark : KeyCode::forwardSlash);
379 }
380 break;
381
382 // Number Pad Multiply is same as print screen
383
384 case KeyCodeEN_US::numberPadMinus:
385 on_key_read(released, this->m_keyboard_state, KeyCode::numberPadMinus);
386 break;
387
388 // Third row
389 case KeyCodeEN_US::tab:
390 on_key_read(released, this->m_keyboard_state, KeyCode::tab);
391 break;
392
393 case KeyCodeEN_US::Q:
394 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::Q : KeyCode::q);
395 break;
396
397 case KeyCodeEN_US::W:
398 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::W : KeyCode::w);
399 break;
400
401 case KeyCodeEN_US::E:
402 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::E : KeyCode::e);
403 break;
404
405 case KeyCodeEN_US::R:
406 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::R : KeyCode::r);
407 break;
408
409 case KeyCodeEN_US::T:
410 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::T : KeyCode::t);
411 break;
412
413 case KeyCodeEN_US::Y:
414 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::Y : KeyCode::y);
415 break;
416
417 case KeyCodeEN_US::U:
418 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::U : KeyCode::u);
419 break;
420
421 case KeyCodeEN_US::I:
422 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::I : KeyCode::i);
423 break;
424
425 case KeyCodeEN_US::O:
426 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::O : KeyCode::o);
427 break;
428
429 case KeyCodeEN_US::P:
430 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::P : KeyCode::p);
431 break;
432
433 case KeyCodeEN_US::openSquareBracket:
434 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::openCurlyBracket : KeyCode::openSquareBracket);
435 break;
436
437 case KeyCodeEN_US::closeSquareBracket:
438 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::closeCurlyBracket : KeyCode::closeSquareBracket);
439 break;
440
441 case KeyCodeEN_US::backslash:
442 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::lineThing : KeyCode::backslash);
443 break;
444
445 case KeyCodeEN_US::deleteKey:
447 ? KeyCode::numberPadFullStop : KeyCode::deleteKey);
448 break;
449
450 case KeyCodeEN_US::end:
451 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadOne : KeyCode::end);
452 break;
453
454 case KeyCodeEN_US::pageDown:
456 ? KeyCode::numberPadThree : KeyCode::pageDown);
457 break;
458
459 // Number pad 7 is same as home
460
461 case KeyCodeEN_US::numberPadEight:
462 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadEight : KeyCode::upArrow);
463 break;
464
465 // Number pad 9 is same as page up
466
467 case KeyCodeEN_US::numberPadPlus:
468 on_key_read(released, this->m_keyboard_state, KeyCode::numberPadPlus);
469 break;
470
472 case KeyCodeEN_US::capsLock:
473 // Ensure this is not a repeat
474 if (!released) {
476 }
477
478 on_key_read(released, this->m_keyboard_state, KeyCode::capsLock);
479 break;
480
481 case KeyCodeEN_US::A:
482 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::A : KeyCode::a);
483 break;
484
485 case KeyCodeEN_US::S:
486 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::S : KeyCode::s);
487 break;
488
489 case KeyCodeEN_US::D:
490 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::D : KeyCode::d);
491 break;
492
493 case KeyCodeEN_US::F:
494 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::F : KeyCode::f);
495 break;
496
497 case KeyCodeEN_US::G:
498 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::G : KeyCode::g);
499 break;
500
501 case KeyCodeEN_US::H:
502 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::H : KeyCode::h);
503 break;
504
505 case KeyCodeEN_US::J:
506 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::J : KeyCode::j);
507 break;
508
509 case KeyCodeEN_US::K:
510 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::K : KeyCode::k);
511 break;
512
513 case KeyCodeEN_US::L:
514 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::L : KeyCode::l);
515 break;
516
517 case KeyCodeEN_US::semicolon:
518 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::colon : KeyCode::semicolon);
519 break;
520
521 case KeyCodeEN_US::apostrophe:
522 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::quotationMark : KeyCode::apostrophe);
523 break;
524
525 case KeyCodeEN_US::enter:
526 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadEnter : KeyCode::enter);
527 break;
528
529 case KeyCodeEN_US::numberPadFour:
530 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadFour : KeyCode::leftArrow);
531 break;
532
533 case KeyCodeEN_US::numberPadFive:
534 on_key_read(released, this->m_keyboard_state, KeyCode::numberPadFive);
535 break;
536
537 case KeyCodeEN_US::numberPadSix:
538 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadSix : KeyCode::rightArrow);
539 break;
540
542 case KeyCodeEN_US::leftShift:
544 on_key_read(released, this->m_keyboard_state, KeyCode::leftShift);
545 break;
546
547 case KeyCodeEN_US::Z:
548 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::Z : KeyCode::z);
549 break;
550
551 case KeyCodeEN_US::X:
552 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::X : KeyCode::x);
553 break;
554
555 case KeyCodeEN_US::C:
556 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::C : KeyCode::c);
557 break;
558
559 case KeyCodeEN_US::V:
560 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::V : KeyCode::v);
561 break;
562
563 case KeyCodeEN_US::B:
564 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::B : KeyCode::b);
565 break;
566
567 case KeyCodeEN_US::N:
568 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::N : KeyCode::n);
569 break;
570
571 case KeyCodeEN_US::M:
572 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::M : KeyCode::m);
573 break;
574
575 case KeyCodeEN_US::comma:
576 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::lessThan : KeyCode::comma);
577 break;
578
579 case KeyCodeEN_US::fullStop:
580 on_key_read(released, this->m_keyboard_state, should_be_upper_case ? KeyCode::greaterThan : KeyCode::fullStop);
581 break;
582
583 // Forward slash is same as number pad forward slash
584
585 case KeyCodeEN_US::rightShift:
586 // Check if this is a repeat
587 if (!released) {
589 }
590
591 on_key_read(released, this->m_keyboard_state, KeyCode::rightShift);
592 break;
593
594 // Up Arrow is the same as number pad 8
595
596 // Number pad 1 is the same as end
597
598 case KeyCodeEN_US::numberPadTwo:
599 on_key_read(released, this->m_keyboard_state, this->m_keyboard_state.number_pad_lock ? KeyCode::numberPadTwo : KeyCode::downArrow);
600 break;
601
602 // Number pad 3 is the same as page down
603
604 // Number pad enter is the same as enter
605
607 case KeyCodeEN_US::leftControl:
608 // Check if this is a repeat
609 if (!released) {
612 }
613
614 on_key_read(released, this->m_keyboard_state, KeyCode::leftControl);
615 break;
616
617 case KeyCodeEN_US::leftOS:
618 on_key_read(released, this->m_keyboard_state, KeyCode::leftOS);
619 break;
620
621 case KeyCodeEN_US::leftAlt:
622 // Check if this is a repeat
623 if (!released) {
626 }
627
628 on_key_read(released, this->m_keyboard_state, KeyCode::leftAlt);
629 break;
630
631 case KeyCodeEN_US::space:
632 on_key_read(released, this->m_keyboard_state, KeyCode::space);
633 break;
634
635 // Right Alt is the same as left alt
636
637 // Right Control is the same as left control
638
639 // Left Arrow is the same as number pad 4
640
641 // Down Arrow is the same as number pad 2
642
643 // Right Arrow is the same as number pad 6
644
645 // Number pad 0 is the same as insert
646
647 // Number pad full stop is the same as delete
648
649 default:
650 break;
651
652 }
653
654}
655
662KeyDownEvent::KeyDownEvent(KeyCode key_code, const KeyboardState &keyboard_state)
664 key_code(key_code),
665 keyboard_state(keyboard_state)
666{
667}
668
669KeyDownEvent::~KeyDownEvent() = default;
670
677KeyUpEvent::KeyUpEvent(KeyCode key_code, const KeyboardState &keyboard_state)
679 key_code(key_code),
680 keyboard_state(keyboard_state)
681{
682}
683
684KeyUpEvent::~KeyUpEvent() = default;
Vector< Event< KeyboardEvents > * > raise_event(Event< KeyboardEvents > *event)
Calls the on_event function of all the event m_handlers connected to the event manager and returns a ...
Used to store information about an event, has a type and a return value.
common::Vector< InputStreamEventHandler< uint8_t > * > m_input_stream_event_handlers
List of streams being observed by this handler.
Handles read and end of stream events from a set of streams.
Definition inputStream.h:29
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
Event that is triggered when a key is pressed.
Definition keyboard.h:261
KeyDownEvent(KeyCode, const KeyboardState &)
Constructor for the KeyDownEvent class.
Definition keyboard.cpp:662
Event that is triggered when a key is released.
Definition keyboard.h:248
KeyUpEvent(KeyCode, const KeyboardState &)
Constructor for the KeyUpEvent class.
Definition keyboard.cpp:677
void handle_interrupt() final
deactivate the keyboard driver
Definition keyboard.cpp:105
KeyboardDriver()
Construct a new Keyboard Driver object, registering it as an interrupt handler for interrupt 0x21.
Definition keyboard.cpp:67
string device_name() final
Get the device name.
Definition keyboard.cpp:117
void activate() final
activate the keyboard driver
Definition keyboard.cpp:81
virtual void on_key_up(KeyCode, const KeyboardState &)
Handle the key up event.
Definition keyboard.cpp:36
virtual void on_key_down(KeyCode, const KeyboardState &)
Handle the key down event.
Definition keyboard.cpp:27
common::Event< KeyboardEvents > * on_event(common::Event< KeyboardEvents > *) override
Handle the trigger of an event.
Definition keyboard.cpp:45
KeyboardInterpreterEN_US()
Construct a new Keyboard Interpreter for the EN_US layout.
Definition keyboard.cpp:156
KeyCodeEN_US
The scan codes for the EN_US keyboard layout.
Definition keyboard.h:318
void on_stream_read(uint8_t scan_code) final
Handle the key down event.
Definition keyboard.cpp:171
Interprets the scan codes from the keyboard.
Definition keyboard.h:289
KeyboardInterpreter()
Construct a new Keyboard Interpreter object.
Definition keyboard.cpp:128
bool m_next_is_first_extended_code
If true, the next code should be interpreted as an extended code (set when receiving 0xE0)
Definition keyboard.h:294
void on_key_read(bool, const KeyboardState &, KeyCode)
Handle the key event.
Definition keyboard.cpp:143
uint8_t m_extended_scan_code_bytes
How many bytes are left to read for the current extended scan code.
Definition keyboard.h:295
uint16_t m_extended_code_buffer
The storage for scan codes that take more than one byte.
Definition keyboard.h:296
KeyboardState m_keyboard_state
The current state of what special keys are pressed on the keyboard.
Definition keyboard.h:292
Holds the state of the keyboard.
Definition keyboard.h:216
bool left_control
Is the left control key pressed.
Definition keyboard.h:224
bool left_shift
Is the left shift key pressed.
Definition keyboard.h:222
bool right_control
Is the right control key pressed.
Definition keyboard.h:225
bool number_pad_lock
Is number pad lock enabled.
Definition keyboard.h:231
bool caps_lock
Is caps lock enabled.
Definition keyboard.h:230
bool right_alt
Is the right alt key pressed.
Definition keyboard.h:227
bool left_alt
Is the left alt key pressed.
Definition keyboard.h:226
bool right_shift
Is the right shift key pressed.
Definition keyboard.h:223
Handles a certain interrupt number.
Definition interrupts.h:30
virtual uint8_t read()
read a byte from the port
Definition port.cpp:51
virtual void write(uint8_t data)
write a byte to the port
Definition port.cpp:41
Defines a Keyboard and related classes for handling keyboard input.
ScanCodeType
The type of scan code being sent by the keyboard.
Definition keyboard.h:30
KeyCode
A mapping of key codes to their values.
Definition keyboard.h:40
KeyboardEvents
The events that can be triggered by the Keyboard Driver.
Definition keyboard.h:239