diff --git a/backends/hwcomposer/CMakeLists.txt b/backends/hwcomposer/CMakeLists.txt
index 6181b8eb9c..6d6794592c 100644
--- a/backends/hwcomposer/CMakeLists.txt
+++ b/backends/hwcomposer/CMakeLists.txt
@@ -11,6 +11,7 @@ target_link_libraries(KWinWaylandHwcomposerBackend
libhybris::libhardware
libhybris::hwcomposer
libhybris::hybriseglplatform
+ libhybris::inputstack
libhybris::sync
)
diff --git a/backends/hwcomposer/hwcomposer.json b/backends/hwcomposer/hwcomposer.json
index 404bba5384..1551bf5de1 100644
--- a/backends/hwcomposer/hwcomposer.json
+++ b/backends/hwcomposer/hwcomposer.json
@@ -1,3 +1,3 @@
{
- "input": false
+ "input": true
}
diff --git a/backends/hwcomposer/hwcomposer_backend.cpp b/backends/hwcomposer/hwcomposer_backend.cpp
index 48e44cd017..5ec3656804 100644
--- a/backends/hwcomposer/hwcomposer_backend.cpp
+++ b/backends/hwcomposer/hwcomposer_backend.cpp
@@ -25,9 +25,13 @@ along with this program. If not, see .
// KWayland
#include
#include
+#include
// hybris/android
#include
#include
+#include
+#include
+#include
// based on test_hwcomposer.c from libhybris project (Apache 2 licensed)
@@ -45,6 +49,68 @@ HwcomposerBackend::~HwcomposerBackend()
if (m_device) {
hwc_close_1(m_device);
}
+ if (m_inputListener) {
+ android_input_stack_stop();
+ android_input_stack_shutdown();
+ delete m_inputListener;
+ }
+}
+
+static QPointF eventPosition(Event *event)
+{
+ return QPointF(event->details.motion.pointer_coordinates[0].x,
+ event->details.motion.pointer_coordinates[0].y);
+}
+
+void HwcomposerBackend::inputEvent(Event *event, void *context)
+{
+ HwcomposerBackend *backend = reinterpret_cast(context);
+ switch (event->type) {
+ case KEY_EVENT_TYPE:
+ switch (event->action) {
+ case ISCL_KEY_EVENT_ACTION_DOWN:
+ // TODO: implement
+ break;
+ case ISCL_KEY_EVENT_ACTION_UP:
+ // TODO: implement
+ break;
+ case ISCL_KEY_EVENT_ACTION_MULTIPLE: // TODO: implement
+ default:
+ break;
+ }
+ break;
+ case MOTION_EVENT_TYPE: {
+ const uint buttonIndex = (event->action & ISCL_MOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> ISCL_MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ switch (event->action & ISCL_MOTION_EVENT_ACTION_MASK) {
+ case ISCL_MOTION_EVENT_ACTION_DOWN:
+ case ISCL_MOTION_EVENT_ACTION_POINTER_DOWN:
+ backend->touchDown(buttonIndex, eventPosition(event), event->details.motion.event_time);
+ break;
+ case ISCL_MOTION_EVENT_ACTION_UP:
+ case ISCL_MOTION_EVENT_ACTION_POINTER_UP:
+ // first update position - up events can contain additional motion events
+ backend->touchMotion(0, eventPosition(event), event->details.motion.event_time);
+ backend->touchFrame();
+ backend->touchUp(buttonIndex, event->details.motion.event_time);
+ break;
+ case ISCL_MOTION_EVENT_ACTION_MOVE:
+ // it's always for the first index, other touch points seem not to be provided
+ backend->touchMotion(0, eventPosition(event), event->details.motion.event_time);
+ backend->touchFrame();
+ break;
+ case ISCL_MOTION_EVENT_ACTION_CANCEL:
+ backend->touchCancel();
+ break;
+ default:
+ // TODO: implement
+ break;
+ }
+ break;
+ }
+ case HW_SWITCH_EVENT_TYPE:
+ qCDebug(KWIN_HWCOMPOSER) << "HW switch event:";
+ break;
+ }
}
static KWayland::Server::OutputInterface *createOutput(hwc_composer_device_1_t *device)
@@ -116,10 +182,36 @@ void HwcomposerBackend::init()
qCDebug(KWIN_HWCOMPOSER) << "Display size:" << m_displaySize;
m_device = hwcDevice;
+ initInput();
+
emit screensQueried();
setReady(true);
}
+void HwcomposerBackend::initInput()
+{
+ Q_ASSERT(!m_inputListener);
+ m_inputListener = new AndroidEventListener;
+ m_inputListener->on_new_event = inputEvent;
+ m_inputListener->context = this;
+
+ struct InputStackConfiguration config = {
+ true,
+ 10000,
+ m_displaySize.width(),
+ m_displaySize.height()
+ };
+
+ android_input_stack_initialize(m_inputListener, &config);
+ android_input_stack_start();
+
+ // we don't know what is really supported, but there is touch
+ // and kind of keyboard
+ waylandServer()->seat()->setHasPointer(false);
+ waylandServer()->seat()->setHasKeyboard(true);
+ waylandServer()->seat()->setHasTouch(true);
+}
+
HwcomposerWindow *HwcomposerBackend::createSurface()
{
return new HwcomposerWindow(this);
diff --git a/backends/hwcomposer/hwcomposer_backend.h b/backends/hwcomposer/hwcomposer_backend.h
index 0ab8a0aa1d..de240090b4 100644
--- a/backends/hwcomposer/hwcomposer_backend.h
+++ b/backends/hwcomposer/hwcomposer_backend.h
@@ -29,6 +29,8 @@ along with this program. If not, see .
typedef struct hwc_display_contents_1 hwc_display_contents_1_t;
typedef struct hwc_layer_1 hwc_layer_1_t;
typedef struct hwc_composer_device_1 hwc_composer_device_1_t;
+struct Event;
+struct AndroidEventListener;
namespace KWin
{
@@ -59,8 +61,11 @@ public:
}
private:
+ static void inputEvent(Event *event, void *context);
+ void initInput();
QSize m_displaySize;
hwc_composer_device_1_t *m_device = nullptr;
+ AndroidEventListener *m_inputListener = nullptr;
};
class HwcomposerWindow : public HWComposerNativeWindow
diff --git a/cmake/modules/Findlibhybris.cmake b/cmake/modules/Findlibhybris.cmake
index 68904d0e9f..1c75b205c9 100644
--- a/cmake/modules/Findlibhybris.cmake
+++ b/cmake/modules/Findlibhybris.cmake
@@ -47,6 +47,7 @@ if(NOT WIN32)
pkg_check_modules(PKG_hwcomposerwindow QUIET hwcomposer-egl)
pkg_check_modules(PKG_hybriseglplatform QUIET hybris-egl-platform)
pkg_check_modules(PKG_hybrissync QUIET libsync)
+ pkg_check_modules(PKG_hybrisinputstack QUIET libis)
set(libhardware_DEFINITIONS ${PKG_libhardware_CFLAGS_OTHER})
set(libhardware_VERSION ${PKG_libhardware_VERSION})
@@ -201,7 +202,40 @@ if(NOT WIN32)
mark_as_advanced(hybrissync_LIBRARY)
- if(libhardware_FOUND AND libhwcomposer_FOUND AND hybriseglplatform_FOUND AND hybrissync_FOUND)
+ ##############################################
+ # hybrisinputstack
+ ##############################################
+ set(hybrisinputstack_DEFINITIONS ${PKG_hybrisinputstack_CFLAGS_OTHER})
+ set(hybrisinputstack_VERSION ${PKG_hybrisinputstack_VERSION})
+
+ find_library(hybrisinputstack_LIBRARY
+ NAMES
+ libis.so
+ HINTS
+ ${PKG_hybrisinputstack_LIBRARY_DIRS}
+ )
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(hybrisinputstack
+ FOUND_VAR
+ hybrisinputstack_FOUND
+ REQUIRED_VARS
+ hybrisinputstack_LIBRARY
+ VERSION_VAR
+ hybrisinputstack_VERSION
+ )
+
+ if(hybrisinputstack_FOUND AND NOT TARGET libhybris::inputstack)
+ add_library(libhybris::inputstack UNKNOWN IMPORTED)
+ set_target_properties(libhybris::inputstack PROPERTIES
+ IMPORTED_LOCATION "${hybrisinputstack_LIBRARY}"
+ INTERFACE_COMPILE_OPTIONS "${hybrisinputstack_DEFINITIONS}"
+ )
+ endif()
+
+ mark_as_advanced(hybrisinputstack_LIBRARY)
+
+ if(libhardware_FOUND AND libhwcomposer_FOUND AND hybriseglplatform_FOUND AND hybrissync_FOUND AND hybrisinputstack_FOUND)
set(libhybris_FOUND TRUE)
else()
set(libhybris_FOUND FALSE)