input/ps2: defer led update on pending events

Issue #2888
This commit is contained in:
Christian Helmuth 2018-08-17 14:40:54 +02:00
parent d909715f1b
commit db376bfddb

View File

@ -365,23 +365,41 @@ class Ps2::Keyboard : public Input_driver
*/ */
Scan_code_state_machine *_state_machine = nullptr; Scan_code_state_machine *_state_machine = nullptr;
bool _capslock = false; struct Led_state
bool _numlock = false; {
bool _scrlock = false; bool capslock = false;
bool numlock = false;
bool scrlock = false;
bool operator == (Led_state const &other) const {
return other.capslock == capslock
&& other.numlock == numlock
&& other.scrlock == scrlock; }
};
Led_state _led_state { };
Led_state _next_led_state { };
void _update_leds() void _update_leds()
{ {
/* don't interfere with pending events when applying next led state */
if (event_pending() || _led_state == _next_led_state)
return;
_kbd.write(0xed); _kbd.write(0xed);
if (_kbd.read() != ACK) { if (_kbd.read() != ACK) {
Genode::warning("setting of mode indicators failed (0xed)"); Genode::warning("setting of mode indicators failed (0xed)");
return; return;
} }
_kbd.write((_capslock ? 4:0) | (_numlock ? 2:0) | (_scrlock ? 1:0)); _kbd.write((_next_led_state.capslock ? 4:0) | (_next_led_state.numlock ? 2:0)
| (_next_led_state.scrlock ? 1:0));
if (_kbd.read() != ACK) { if (_kbd.read() != ACK) {
Genode::warning("setting of mode indicators failed"); Genode::warning("setting of mode indicators failed");
return; return;
} }
_led_state = _next_led_state;
} }
public: public:
@ -420,9 +438,9 @@ class Ps2::Keyboard : public Input_driver
void led_enabled(Led led, bool enabled) void led_enabled(Led led, bool enabled)
{ {
switch (led) { switch (led) {
case CAPSLOCK_LED: _capslock = enabled; break; case CAPSLOCK_LED: _next_led_state.capslock = enabled; break;
case NUMLOCK_LED: _numlock = enabled; break; case NUMLOCK_LED: _next_led_state.numlock = enabled; break;
case SCRLOCK_LED: _scrlock = enabled; break; case SCRLOCK_LED: _next_led_state.scrlock = enabled; break;
} }
_update_leds(); _update_leds();
} }
@ -476,6 +494,7 @@ class Ps2::Keyboard : public Input_driver
*/ */
if (_key_state[key_code] == press) { if (_key_state[key_code] == press) {
_state_machine->reset(); _state_machine->reset();
_update_leds();
return; return;
} }
@ -499,6 +518,7 @@ class Ps2::Keyboard : public Input_driver
/* start with new packet */ /* start with new packet */
_state_machine->reset(); _state_machine->reset();
_update_leds();
} }
bool event_pending() const { return _kbd.data_read_ready(); } bool event_pending() const { return _kbd.data_read_ready(); }