mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-07 03:40:15 +00:00
vbox6: sync capslock state on boot / LED change
Thanks to Peter for the initial patch.
This commit is contained in:
parent
9965b2b72a
commit
db90656483
@ -210,7 +210,9 @@ struct Main : Event_handler
|
|||||||
|
|
||||||
Signal_handler<Main> _capslock_handler { _env.ep(), *this, &Main::_handle_capslock };
|
Signal_handler<Main> _capslock_handler { _env.ep(), *this, &Main::_handle_capslock };
|
||||||
|
|
||||||
void _handle_capslock();
|
void _handle_capslock() { Libc::with_libc([&] { _sync_capslock(); }); }
|
||||||
|
|
||||||
|
void _sync_capslock();
|
||||||
|
|
||||||
struct Capslock
|
struct Capslock
|
||||||
{
|
{
|
||||||
@ -238,6 +240,9 @@ struct Main : Event_handler
|
|||||||
|
|
||||||
bool update_from_rom()
|
bool update_from_rom()
|
||||||
{
|
{
|
||||||
|
if (mode != Mode::ROM)
|
||||||
|
return false;
|
||||||
|
|
||||||
_rom->update();
|
_rom->update();
|
||||||
|
|
||||||
bool const rom = _rom->xml().attribute_value("enabled", _guest);
|
bool const rom = _rom->xml().attribute_value("enabled", _guest);
|
||||||
@ -245,14 +250,11 @@ struct Main : Event_handler
|
|||||||
bool trigger = false;
|
bool trigger = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If guest didn't respond with led change last time, we have to
|
* Trigger CapsLock change whenever the ROM state changes. This
|
||||||
* trigger CapsLock change - mainly assuming that guest don't use the
|
* helps with guests that do not use the keyboard led to indicate
|
||||||
* led to externalize its internal state.
|
* the CapsLock state.
|
||||||
*/
|
*/
|
||||||
if (rom != _host && _host != _guest)
|
if (rom != _host || rom != _guest)
|
||||||
trigger = true;
|
|
||||||
|
|
||||||
if (rom != _guest)
|
|
||||||
trigger = true;
|
trigger = true;
|
||||||
|
|
||||||
/* remember last seen host capslock state */
|
/* remember last seen host capslock state */
|
||||||
@ -361,6 +363,7 @@ struct Main : Event_handler
|
|||||||
event_types.push_back(VBoxEventType_OnMousePointerShapeChanged);
|
event_types.push_back(VBoxEventType_OnMousePointerShapeChanged);
|
||||||
event_types.push_back(VBoxEventType_OnKeyboardLedsChanged);
|
event_types.push_back(VBoxEventType_OnKeyboardLedsChanged);
|
||||||
event_types.push_back(VBoxEventType_OnStateChanged);
|
event_types.push_back(VBoxEventType_OnStateChanged);
|
||||||
|
event_types.push_back(VBoxEventType_OnAdditionsStateChanged);
|
||||||
|
|
||||||
ievent_source->RegisterListener(listener, ComSafeArrayAsInParam(event_types), true);
|
ievent_source->RegisterListener(listener, ComSafeArrayAsInParam(event_types), true);
|
||||||
}
|
}
|
||||||
@ -377,13 +380,12 @@ struct Main : Event_handler
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Main::_handle_capslock()
|
/* must be called in Libc::with_libc() context */
|
||||||
|
void Main::_sync_capslock()
|
||||||
{
|
{
|
||||||
if (_capslock.update_from_rom()) {
|
if (_capslock.update_from_rom()) {
|
||||||
Libc::with_libc([&] {
|
_input_adapter.handle_input_event(Input::Event { Input::Press { Input::KEY_CAPSLOCK } });
|
||||||
_input_adapter.handle_input_event(Input::Event { Input::Press { Input::KEY_CAPSLOCK } });
|
_input_adapter.handle_input_event(Input::Event { Input::Release { Input::KEY_CAPSLOCK } });
|
||||||
_input_adapter.handle_input_event(Input::Event { Input::Release { Input::KEY_CAPSLOCK } });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,10 +472,18 @@ void Main::handle_vbox_event(VBoxEventType_T ev_type, IEvent &ev)
|
|||||||
|
|
||||||
case VBoxEventType_OnKeyboardLedsChanged:
|
case VBoxEventType_OnKeyboardLedsChanged:
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Use CapsLock LED as indicator for guest assumption about the
|
||||||
|
* state and optionally resync to host state. This is required
|
||||||
|
* because the guest may try to switch CapsLock (off) on its own,
|
||||||
|
* e.g. during startup.
|
||||||
|
*/
|
||||||
|
|
||||||
ComPtr<IKeyboardLedsChangedEvent> led_ev = &ev;
|
ComPtr<IKeyboardLedsChangedEvent> led_ev = &ev;
|
||||||
BOOL capslock;
|
BOOL capslock;
|
||||||
led_ev->COMGETTER(CapsLock)(&capslock);
|
led_ev->COMGETTER(CapsLock)(&capslock);
|
||||||
_capslock.update_guest(!!capslock);
|
_capslock.update_guest(!!capslock);
|
||||||
|
_sync_capslock();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case VBoxEventType_OnStateChanged:
|
case VBoxEventType_OnStateChanged:
|
||||||
@ -487,6 +497,27 @@ void Main::handle_vbox_event(VBoxEventType_T ev_type, IEvent &ev)
|
|||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case VBoxEventType_OnAdditionsStateChanged:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Try to sync initial CapsLock state when starting a guest OS.
|
||||||
|
* Usually this is only a problem when CapsLock is already on
|
||||||
|
* during startup, because the guest will assume it's off or
|
||||||
|
* deliberately clear the CapsLock state during boot.
|
||||||
|
*
|
||||||
|
* Ideally this should only be done once, after the guest is ready
|
||||||
|
* to process the CapsLock key but before it's ready for login. The
|
||||||
|
* OnAdditionsStateChanged event will fire a few times during boot,
|
||||||
|
* but maybe not when we really need it to. Maybe there is a better
|
||||||
|
* event to listen to, once the guest additions are fulling
|
||||||
|
* working, like VBoxEventType_OnGuestSessionRegistered.
|
||||||
|
*
|
||||||
|
* For a list of "VBoxEventType_..." events see
|
||||||
|
* virtualbox6_sdk/sdk/bindings/xpcom/include/VirtualBox_XPCOM.h
|
||||||
|
*/
|
||||||
|
_sync_capslock();
|
||||||
|
} break;
|
||||||
|
|
||||||
default: /* ignore other events */ break;
|
default: /* ignore other events */ break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user