diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc
index c56434050..7e672adec 100644
--- a/repos/ports/run/vbox_win.inc
+++ b/repos/ports/run/vbox_win.inc
@@ -242,6 +242,16 @@ for { set i 1} { $i <= $use_vms } { incr i} {
}
append config_of_app {
+
+
+
+
+
+
+
+
+
+
@@ -261,11 +271,11 @@ for { set i 1} { $i <= $use_vms } { incr i} {
}
if { $use_vms eq 1 } {
append config_of_app "
- "
+ "
} else {
append config_of_app "
- "
+ "
}
append config_of_app {
@@ -307,6 +317,7 @@ for { set i 1} { $i <= $use_vms } { incr i} {
append config_of_app {
+
}
diff --git a/repos/ports/src/virtualbox/README b/repos/ports/src/virtualbox/README
index 7ec2f238a..eec7691b6 100644
--- a/repos/ports/src/virtualbox/README
+++ b/repos/ports/src/virtualbox/README
@@ -1,6 +1,11 @@
VirtualBox configuration options
################################
+The configuration requires an attribute named vbox_file with the name of the
+vbox configuration to be used (.vbox).
+
+
+
XHCI controller
===============
@@ -22,3 +27,12 @@ methods (for example Genode/NOVA), the configuration option
enforces the delivery of PCI IRQs to the IOAPIC.
+CAPSLOCK
+========
+
+
+
+If the capslock attribute is set to "ROM", virtualbox will open a connection
+to the ROM named "capslock" and expect in the top-level node a attribute
+'enabled' (yes|no). If the ROM capslock differ from the internal VM capslock,
+the VMM will trigger aritifical capslock key events to the VM.
diff --git a/repos/ports/src/virtualbox/frontend/console.cc b/repos/ports/src/virtualbox/frontend/console.cc
index 818b6f210..907ec0297 100644
--- a/repos/ports/src/virtualbox/frontend/console.cc
+++ b/repos/ports/src/virtualbox/frontend/console.cc
@@ -106,7 +106,6 @@ HRESULT Console::setDiskEncryptionKeys(const Utf8Str &strCfg)
void Console::onAdditionsOutdated() DUMMY()
-void Console::onKeyboardLedsChange(bool, bool, bool) TRACE()
HRESULT Console::onVideoCaptureChange() DUMMY(E_FAIL)
HRESULT Console::onSharedFolderChange(BOOL aGlobal) DUMMY(E_FAIL)
HRESULT Console::onUSBControllerChange() DUMMY(E_FAIL)
@@ -567,3 +566,46 @@ int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient)
return VINF_SUCCESS;
}
+
+/**
+ * Sticky key handling
+ */
+static bool host_caps_lock = false;
+static bool guest_caps_lock = false;
+
+void Console::onKeyboardLedsChange(bool num_lock, bool caps_lock, bool scroll_lock)
+{
+ guest_caps_lock = caps_lock;
+}
+
+void GenodeConsole::handle_sticky_keys()
+{
+ /* no keyboard - no sticky key handling */
+ if (!_vbox_keyboard || !_caps_lock.constructed())
+ return;
+
+ _caps_lock->update();
+
+ if (!_caps_lock->valid())
+ return;
+
+ bool const caps_lock = _caps_lock->xml().attribute_value("enabled",
+ guest_caps_lock);
+ bool trigger_caps_lock = false;
+
+ /*
+ * If guest didn't respond with led change last time, we have to
+ * trigger caps_lock change - mainly assuming that guest don't use the
+ * led to externalize its internal caps_lock state.
+ */
+ if (caps_lock != host_caps_lock && host_caps_lock != guest_caps_lock)
+ trigger_caps_lock = true;
+
+ if (caps_lock != guest_caps_lock)
+ trigger_caps_lock = true;
+
+ if (trigger_caps_lock) {
+ _vbox_keyboard->PutScancode(Input::KEY_CAPSLOCK);
+ _vbox_keyboard->PutScancode(Input::KEY_CAPSLOCK | 0x80);
+ }
+}
diff --git a/repos/ports/src/virtualbox/frontend/console.h b/repos/ports/src/virtualbox/frontend/console.h
index f05f28de4..6e53e8d56 100644
--- a/repos/ports/src/virtualbox/frontend/console.h
+++ b/repos/ports/src/virtualbox/frontend/console.h
@@ -116,6 +116,7 @@ class GenodeConsole : public Console {
bool _last_received_motion_event_was_absolute;
Report::Connection _shape_report_connection;
Genode::Attached_dataspace _shape_report_ds;
+ Genode::Constructible _caps_lock;
Vbox_pointer::Shape_report *_shape_report;
Genode::Reporter *_clipboard_reporter;
Genode::Attached_rom_dataspace *_clipboard_rom;
@@ -124,6 +125,7 @@ class GenodeConsole : public Console {
Genode::Signal_handler _input_signal_dispatcher;
Genode::Signal_handler _mode_change_signal_dispatcher;
Genode::Signal_handler _clipboard_signal_dispatcher;
+ Genode::Signal_handler _input_sticky_keys_dispatcher;
bool _key_status[Input::KEY_MAX + 1];
@@ -152,12 +154,22 @@ class GenodeConsole : public Console {
_vbox_mouse(0),
_input_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_input),
_mode_change_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_mode_change),
- _clipboard_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_cb_rom_change)
+ _clipboard_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_cb_rom_change),
+ _input_sticky_keys_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_sticky_keys)
{
for (unsigned i = 0; i <= Input::KEY_MAX; i++)
_key_status[i] = 0;
_input.sigh(_input_signal_dispatcher);
+
+ Genode::Attached_rom_dataspace config(genode_env(), "config");
+
+ /* by default we take the capslock key from the input stream */
+ Genode::String<10> capslock("input");
+ if (config.xml().attribute_value("capslock", capslock) == "ROM") {
+ _caps_lock.construct(genode_env(), "capslock");
+ _caps_lock->sigh(_input_sticky_keys_dispatcher);
+ }
}
void init_clipboard();
@@ -231,4 +243,5 @@ class GenodeConsole : public Console {
void handle_input();
void handle_mode_change();
void handle_cb_rom_change();
+ void handle_sticky_keys();
};
diff --git a/repos/ports/src/virtualbox5/README b/repos/ports/src/virtualbox5/README
new file mode 100644
index 000000000..eec7691b6
--- /dev/null
+++ b/repos/ports/src/virtualbox5/README
@@ -0,0 +1,38 @@
+VirtualBox configuration options
+################################
+
+The configuration requires an attribute named vbox_file with the name of the
+vbox configuration to be used (.vbox).
+
+
+
+XHCI controller
+===============
+
+The virtual XHCI controller can be enabled with the following
+configuration option:
+
+
+
+IOAPIC
+======
+
+The virtual PCI model delivers IRQs to the PIC by default and to the IOAPIC
+only if the guest operating system selected the IOAPIC with the '_PIC' ACPI
+method and if it called the '_PRT' ACPI method afterwards. When running a
+guest operating system which uses the IOAPIC, but does not call these ACPI
+methods (for example Genode/NOVA), the configuration option
+
+
+
+enforces the delivery of PCI IRQs to the IOAPIC.
+
+CAPSLOCK
+========
+
+
+
+If the capslock attribute is set to "ROM", virtualbox will open a connection
+to the ROM named "capslock" and expect in the top-level node a attribute
+'enabled' (yes|no). If the ROM capslock differ from the internal VM capslock,
+the VMM will trigger aritifical capslock key events to the VM.
diff --git a/repos/ports/src/virtualbox5/frontend/VBoxEvents.h b/repos/ports/src/virtualbox5/frontend/VBoxEvents.h
index 86b9c22ee..10780b630 100644
--- a/repos/ports/src/virtualbox5/frontend/VBoxEvents.h
+++ b/repos/ports/src/virtualbox5/frontend/VBoxEvents.h
@@ -5,6 +5,9 @@ void fireStateChangedEvent(IEventSource* aSource, MachineState_T a_state);
void fireRuntimeErrorEvent(IEventSource* aSource, BOOL a_fatal, CBSTR a_id,
CBSTR a_message);
+void fireKeyboardLedsChangedEvent(IEventSource *aSource, bool fNumLock,
+ bool fCapsLock, bool fScrollLock);
+
#define fireAdditionsStateChangedEvent(a)
#define fireBandwidthGroupChangedEvent(a, b)
@@ -23,8 +26,6 @@ void fireRuntimeErrorEvent(IEventSource* aSource, BOOL a_fatal, CBSTR a_id,
#define fireHostNameResolutionConfigurationChangeEvent(a)
#define fireHostPCIDevicePlugEvent(a, b, c, d, e, f)
-#define fireKeyboardLedsChangedEvent(a, b, c, d)
-
#define fireMediumChangedEvent(a, b)
#define fireMousePointerShapeChangedEvent(a, b, c, d, e, f, g, h)
#define fireMouseCapabilityChangedEvent(a, b, c, d, e)
diff --git a/repos/ports/src/virtualbox5/frontend/console.cc b/repos/ports/src/virtualbox5/frontend/console.cc
index d903b0fa7..a033f12a1 100644
--- a/repos/ports/src/virtualbox5/frontend/console.cc
+++ b/repos/ports/src/virtualbox5/frontend/console.cc
@@ -519,3 +519,51 @@ int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient)
return VINF_SUCCESS;
}
+
+/**
+ * Sticky key handling
+ */
+static bool host_caps_lock = false;
+static bool guest_caps_lock = false;
+
+void fireKeyboardLedsChangedEvent(IEventSource *, bool num_lock,
+ bool caps_lock, bool scroll_lock)
+{
+ guest_caps_lock = caps_lock;
+}
+
+void GenodeConsole::handle_sticky_keys()
+{
+ /* no keyboard - no sticky key handling */
+ if (!_vbox_keyboard || !_caps_lock.constructed())
+ return;
+
+ _caps_lock->update();
+
+ if (!_caps_lock->valid())
+ return;
+
+ bool const caps_lock = _caps_lock->xml().attribute_value("enabled",
+ guest_caps_lock);
+
+ bool trigger_caps_lock = false;
+
+ /*
+ * If guest didn't respond with led change last time, we have to
+ * trigger caps_lock change - mainly assuming that guest don't use the
+ * led to externalize its internal caps_lock state.
+ */
+ if (caps_lock != host_caps_lock && host_caps_lock != guest_caps_lock)
+ trigger_caps_lock = true;
+
+ if (caps_lock != guest_caps_lock)
+ trigger_caps_lock = true;
+
+ /* remember last seen host caps lock state */
+ host_caps_lock = caps_lock;
+
+ if (trigger_caps_lock) {
+ _vbox_keyboard->PutScancode(Input::KEY_CAPSLOCK);
+ _vbox_keyboard->PutScancode(Input::KEY_CAPSLOCK | 0x80);
+ }
+}
diff --git a/repos/ports/src/virtualbox5/frontend/console.h b/repos/ports/src/virtualbox5/frontend/console.h
index 1f6162178..a2234b0e8 100644
--- a/repos/ports/src/virtualbox5/frontend/console.h
+++ b/repos/ports/src/virtualbox5/frontend/console.h
@@ -116,6 +116,7 @@ class GenodeConsole : public Console {
bool _last_received_motion_event_was_absolute;
Report::Connection _shape_report_connection;
Genode::Attached_dataspace _shape_report_ds;
+ Genode::Constructible _caps_lock;
Vbox_pointer::Shape_report *_shape_report;
Genode::Reporter *_clipboard_reporter;
Genode::Attached_rom_dataspace *_clipboard_rom;
@@ -124,6 +125,7 @@ class GenodeConsole : public Console {
Genode::Signal_handler _input_signal_dispatcher;
Genode::Signal_handler _mode_change_signal_dispatcher;
Genode::Signal_handler _clipboard_signal_dispatcher;
+ Genode::Signal_handler _input_sticky_keys_dispatcher;
bool _key_status[Input::KEY_MAX + 1];
@@ -152,12 +154,22 @@ class GenodeConsole : public Console {
_vbox_mouse(0),
_input_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_input),
_mode_change_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_mode_change),
- _clipboard_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_cb_rom_change)
+ _clipboard_signal_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_cb_rom_change),
+ _input_sticky_keys_dispatcher(genode_env().ep(), *this, &GenodeConsole::handle_sticky_keys)
{
for (unsigned i = 0; i <= Input::KEY_MAX; i++)
_key_status[i] = 0;
_input.sigh(_input_signal_dispatcher);
+
+ Genode::Attached_rom_dataspace config(genode_env(), "config");
+
+ /* by default we take the capslock key from the input stream */
+ Genode::String<10> capslock("input");
+ if (config.xml().attribute_value("capslock", capslock) == "ROM") {
+ _caps_lock.construct(genode_env(), "capslock");
+ _caps_lock->sigh(_input_sticky_keys_dispatcher);
+ }
}
void init_clipboard();
@@ -231,4 +243,5 @@ class GenodeConsole : public Console {
void handle_input();
void handle_mode_change();
void handle_cb_rom_change();
+ void handle_sticky_keys();
};