diff --git a/repos/ports/ports/virtualbox.hash b/repos/ports/ports/virtualbox.hash index b261ef6b6a..17c905d69c 100644 --- a/repos/ports/ports/virtualbox.hash +++ b/repos/ports/ports/virtualbox.hash @@ -1 +1 @@ -21c8fc5eade0a7bc64c3a494b53228a57cbfe995 +7e0d7dd26169ee60eea603a22fd068bd0b879a79 diff --git a/repos/ports/src/virtualbox/frontend/console.h b/repos/ports/src/virtualbox/frontend/console.h index 9a1c663492..d648032f6f 100644 --- a/repos/ports/src/virtualbox/frontend/console.h +++ b/repos/ports/src/virtualbox/frontend/console.h @@ -25,9 +25,6 @@ #include "ConsoleImpl.h" #include -/* XXX */ -enum { KMOD_RCTRL = 0, SDLK_RCTRL = 0 }; - class Scan_code { @@ -138,8 +135,17 @@ class GenodeConsole : public Console { void eventWait(IKeyboard * gKeyboard, IMouse * gMouse) { + static LONG64 mt_events [64]; + unsigned mt_number = 0; + _receiver.wait_for_signal(); + /* read out input capabilities of guest */ + bool guest_abs = false, guest_rel = false, guest_multi = false; + gMouse->COMGETTER(AbsoluteSupported)(&guest_abs); + gMouse->COMGETTER(RelativeSupported)(&guest_rel); + gMouse->COMGETTER(MultiTouchSupported)(&guest_multi); + for (int i = 0, num_ev = _input.flush(); i < num_ev; ++i) { Input::Event &ev = _ev_buf[i]; @@ -148,6 +154,7 @@ class GenodeConsole : public Console { bool const is_key = is_press || is_release; bool const is_motion = ev.type() == Input::Event::MOTION; bool const is_wheel = ev.type() == Input::Event::WHEEL; + bool const is_touch = ev.type() == Input::Event::TOUCH; if (is_key) { Scan_code scan_code(ev.keycode()); @@ -184,13 +191,19 @@ class GenodeConsole : public Console { | (_key_status[Input::BTN_RIGHT] ? MouseButtonState_RightButton : 0) | (_key_status[Input::BTN_MIDDLE] ? MouseButtonState_MiddleButton : 0); if (ev.is_absolute_motion()) { - int const rx = ev.ax() - _ax; _ax = ev.ax(); - int const ry = ev.ay() - _ay; _ay = ev.ay(); - gMouse->PutMouseEvent(rx, ry, 0, 0, buttons); - gMouse->PutMouseEventAbsolute(ev.ax(), ev.ay(), 0, 0, buttons); + /* transform absolute to relative if guest is so odd */ + if (!guest_abs && guest_rel) { + int const boundary = 20; + int rx = ev.ax() - _ax; _ax = ev.ax(); + int ry = ev.ay() - _ay; _ay = ev.ay(); + rx = Genode::min(boundary, Genode::max(-boundary, rx)); + ry = Genode::min(boundary, Genode::max(-boundary, ry)); + gMouse->PutMouseEvent(rx, ry, 0, 0, buttons); + } else + gMouse->PutMouseEventAbsolute(ev.ax(), ev.ay(), 0, + 0, buttons); } else if (ev.is_relative_motion()) gMouse->PutMouseEvent(ev.rx(), ev.ry(), 0, 0, buttons); - /* only the buttons changed */ else gMouse->PutMouseEvent(0, 0, 0, 0, buttons); @@ -198,6 +211,42 @@ class GenodeConsole : public Console { if (is_wheel) gMouse->PutMouseEvent(0, 0, ev.rx(), ev.ry(), 0); + + if (is_touch) { + /* if multitouch queue is full - send it */ + if (mt_number >= sizeof(mt_events) / sizeof(mt_events[0])) { + gMouse->PutEventMultiTouch(mt_number, mt_number, + mt_events, RTTimeMilliTS()); + mt_number = 0; + } + + int x = ev.ax(); + int y = ev.ay(); + int slot = ev.code(); + + /* Mouse::putEventMultiTouch drops values of 0 */ + if (x <= 0) x = 1; + if (y <= 0) y = 1; + + enum MultiTouch { + None = 0x0, + InContact = 0x01, + InRange = 0x02 + }; + + int status = MultiTouch::InContact | MultiTouch::InRange; + if (ev.is_touch_release()) + status = MultiTouch::None; + + uint16_t const s = RT_MAKE_U16(slot, status); + mt_events[mt_number++] = RT_MAKE_U64_FROM_U16(x, y, s, 0); + } + } + + /* if there are elements - send it */ + if (mt_number) + gMouse->PutEventMultiTouch(mt_number, mt_number, mt_events, + RTTimeMilliTS()); } }; diff --git a/repos/ports/src/virtualbox/libc.cc b/repos/ports/src/virtualbox/libc.cc index 13e34d148c..bfb337e891 100644 --- a/repos/ports/src/virtualbox/libc.cc +++ b/repos/ports/src/virtualbox/libc.cc @@ -116,6 +116,7 @@ extern "C" char *getenv(const char *name) // "+dev_pic.e.l.f" // "+dev_apic.e.l.f" "+dev_vmm.e" +// "+usb_mouse.e.l.f" // "+main.e.l.f" // "+hgcm.e.l.f" // "+shared_folders.e.l.f" diff --git a/repos/ports/src/virtualbox/patches/vbox_main.patch b/repos/ports/src/virtualbox/patches/vbox_main.patch index c14a7d6b6d..583a28c122 100644 --- a/repos/ports/src/virtualbox/patches/vbox_main.patch +++ b/repos/ports/src/virtualbox/patches/vbox_main.patch @@ -1626,3 +1626,17 @@ CheckComArgNotNull(aTarget); CheckComArgOutPointerValid(aProgress); CheckComArgSafeArrayNotNull(aVariant); ++++ src/app/virtualbox/src/VBox/Main/src-client/MouseImpl.cpp +@@ -816,7 +818,11 @@ + } + } + +- if (SUCCEEDED(rc)) ++ /* ++ * Contrary to the comment of the previous if clause, the usb model ++ * triggers various assertions if 0 contacts are propagated. ++ */ ++ if (SUCCEEDED(rc) && cContacts) + { + rc = reportMultiTouchEventToDevice(cContacts, cContacts? pau64Contacts: NULL, (uint32_t)aScanTime); + diff --git a/repos/ports/src/virtualbox/thread.cc b/repos/ports/src/virtualbox/thread.cc index 49f0f03fff..3d10f1f235 100644 --- a/repos/ports/src/virtualbox/thread.cc +++ b/repos/ports/src/virtualbox/thread.cc @@ -57,7 +57,7 @@ static Genode::Cpu_session * get_cpu_session(RTTHREADTYPE type) { /* upgrade memory of cpu session for frequent used thread type */ if (type == RTTHREADTYPE_IO) - Genode::env()->parent()->upgrade(con[type - 1]->cap(), "ram_quota=8192"); + Genode::env()->parent()->upgrade(con[type - 1]->cap(), "ram_quota=16384"); return con[type - 1]; }