mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
vbox6: add mouse pointer shape support
Implement 'MousePointerShapeChanged' event, retrieve parameters from COM pointer, and update shape report. fixes #4283
This commit is contained in:
parent
8ebc185caf
commit
2604c3cca6
@ -38,6 +38,7 @@
|
||||
#include <init.h>
|
||||
#include <fb.h>
|
||||
#include <input_adapter.h>
|
||||
#include <mouse_shape.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
@ -259,6 +260,8 @@ struct Main : Event_handler
|
||||
}
|
||||
} _capslock { _env, _config.xml(), _capslock_handler };
|
||||
|
||||
Mouse_shape _mouse_shape { _env };
|
||||
|
||||
Registry<Registered<Gui::Connection>> _gui_connections { };
|
||||
|
||||
Signal_handler<Main> _input_handler { _env.ep(), *this, &Main::_handle_input };
|
||||
@ -418,7 +421,25 @@ void Main::handle_vbox_event(VBoxEventType_T ev_type, IEvent &ev)
|
||||
_input_adapter.mouse_absolute(!!absolute);
|
||||
} break;
|
||||
|
||||
case VBoxEventType_OnMousePointerShapeChanged: break;
|
||||
case VBoxEventType_OnMousePointerShapeChanged:
|
||||
{
|
||||
ComPtr<IMousePointerShapeChangedEvent> shape_ev = &ev;
|
||||
BOOL visible, alpha;
|
||||
ULONG xHot, yHot, width, height;
|
||||
com::SafeArray <BYTE> shape;
|
||||
|
||||
shape_ev->COMGETTER(Visible)(&visible);
|
||||
shape_ev->COMGETTER(Alpha)(&alpha);
|
||||
shape_ev->COMGETTER(Xhot)(&xHot);
|
||||
shape_ev->COMGETTER(Yhot)(&yHot);
|
||||
shape_ev->COMGETTER(Width)(&width);
|
||||
shape_ev->COMGETTER(Height)(&height);
|
||||
shape_ev->COMGETTER(Shape)(ComSafeArrayAsOutParam(shape));
|
||||
|
||||
_mouse_shape.update(visible, alpha, xHot, yHot, width, height,
|
||||
ComSafeArrayAsInParam(shape));
|
||||
|
||||
} break;
|
||||
|
||||
case VBoxEventType_OnKeyboardLedsChanged:
|
||||
{
|
||||
|
120
repos/ports/src/virtualbox6/mouse_shape.h
Normal file
120
repos/ports/src/virtualbox6/mouse_shape.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* \brief VM mouse shape support
|
||||
* \author Christian Prochaska
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2021-10-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _MOUSE_SHAPE_H_
|
||||
#define _MOUSE_SHAPE_H_
|
||||
|
||||
#include <report_session/connection.h>
|
||||
#include <pointer/shape_report.h>
|
||||
|
||||
|
||||
class Mouse_shape
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Report::Connection _report_connection { _env, "shape",
|
||||
sizeof(Pointer::Shape_report) };
|
||||
|
||||
Genode::Attached_dataspace _report_ds { _env.rm(),
|
||||
_report_connection.dataspace() };
|
||||
|
||||
Pointer::Shape_report *_shape_report {
|
||||
_report_ds.local_addr<Pointer::Shape_report>() };
|
||||
|
||||
public:
|
||||
|
||||
Mouse_shape(Genode::Env &env)
|
||||
: _env(env)
|
||||
{ }
|
||||
|
||||
void update(BOOL visible,
|
||||
BOOL alpha,
|
||||
ULONG xHot,
|
||||
ULONG yHot,
|
||||
ULONG width,
|
||||
ULONG height,
|
||||
ComSafeArrayIn(BYTE,inShape))
|
||||
{
|
||||
com::SafeArray <BYTE> aShape(ComSafeArrayInArg(inShape));
|
||||
|
||||
if (visible && ((width == 0) || (height == 0)))
|
||||
return;
|
||||
|
||||
_shape_report->visible = visible;
|
||||
_shape_report->x_hot = xHot;
|
||||
_shape_report->y_hot = yHot;
|
||||
_shape_report->width = width;
|
||||
_shape_report->height = height;
|
||||
|
||||
unsigned int and_mask_size = (_shape_report->width + 7) / 8 *
|
||||
_shape_report->height;
|
||||
|
||||
const unsigned char *and_mask = aShape.raw();
|
||||
|
||||
const unsigned char *shape = and_mask + ((and_mask_size + 3) & ~3);
|
||||
|
||||
size_t shape_size = aShape.size() - (shape - and_mask);
|
||||
|
||||
if (shape_size > Pointer::MAX_SHAPE_SIZE) {
|
||||
Genode::error("mouse shape: data buffer too small for ",
|
||||
shape_size, " bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
/* convert the shape data from BGRA encoding to RGBA encoding */
|
||||
|
||||
unsigned char const *bgra_shape = shape;
|
||||
unsigned char *rgba_shape = _shape_report->shape;
|
||||
|
||||
for (unsigned int y = 0; y < _shape_report->height; y++) {
|
||||
|
||||
unsigned char const *bgra_line = &bgra_shape[y * _shape_report->width * 4];
|
||||
unsigned char *rgba_line = &rgba_shape[y * _shape_report->width * 4];
|
||||
|
||||
for (unsigned int i = 0; i < _shape_report->width * 4; i += 4) {
|
||||
rgba_line[i + 0] = bgra_line[i + 2];
|
||||
rgba_line[i + 1] = bgra_line[i + 1];
|
||||
rgba_line[i + 2] = bgra_line[i + 0];
|
||||
rgba_line[i + 3] = bgra_line[i + 3];
|
||||
}
|
||||
}
|
||||
|
||||
if (visible && !alpha) {
|
||||
|
||||
for (unsigned int i = 0; i < width * height; i++) {
|
||||
|
||||
unsigned int *color =
|
||||
&((unsigned int*)_shape_report->shape)[i];
|
||||
|
||||
/* heuristic from VBoxSDL.cpp */
|
||||
|
||||
if (and_mask[i / 8] & (1 << (7 - (i % 8)))) {
|
||||
|
||||
if (*color & 0x00ffffff)
|
||||
*color = 0xff000000;
|
||||
else
|
||||
*color = 0x00000000;
|
||||
|
||||
} else
|
||||
*color |= 0xff000000;
|
||||
}
|
||||
}
|
||||
|
||||
_report_connection.submit(sizeof(Pointer::Shape_report));
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _MOUSE_SHAPE_H_ */
|
Loading…
Reference in New Issue
Block a user