vbox: support multi touch input events

Fixes #1444
This commit is contained in:
Alexander Boettcher 2015-03-06 16:46:47 +01:00 committed by Christian Helmuth
parent c745f9b48c
commit 2ad6a3b934
5 changed files with 74 additions and 10 deletions

View File

@ -1 +1 @@
21c8fc5eade0a7bc64c3a494b53228a57cbfe995
7e0d7dd26169ee60eea603a22fd068bd0b879a79

View File

@ -25,9 +25,6 @@
#include "ConsoleImpl.h"
#include <base/printf.h>
/* 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());
}
};

View File

@ -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"

View File

@ -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);

View File

@ -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];
}