diff --git a/CMakeLists.txt b/CMakeLists.txt index d38de0bb..edb5a023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,19 +109,7 @@ if(FEATURE_aurora_compositor_quick) endif() endif() if(FEATURE_aurora_qpa) - add_subdirectory(src/platformheaders) -# add_subdirectory(src/platformsupport/logind) -# add_subdirectory(src/platformsupport/udev) # add_subdirectory(src/platformsupport/libinput) -# add_subdirectory(src/platformsupport/edid) -# add_subdirectory(src/platformsupport/kmsconvenience) -# add_subdirectory(src/plugins/platforms/eglfs) -# add_subdirectory(src/plugins/platforms/eglfs/deviceintegration/eglfs_kms) -# #add_subdirectory(src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice) -# add_subdirectory(src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support) -# if(FEATURE_aurora_qpa_x11) -# add_subdirectory(src/plugins/platforms/eglfs/deviceintegration/eglfs_x11) -# endif() endif() if(FEATURE_aurora_deviceintegration_wayland) add_subdirectory(src/plugins/deviceintegration/wayland) @@ -134,12 +122,6 @@ if(BUILD_TESTING) add_subdirectory(tests/manual/scaling-compositor) add_subdirectory(tests/manual/subsurface) endif() - if(TARGET Liri::AuroraLogind) -# add_subdirectory(tests/auto/logind) - endif() - if(TARGET Liri::AuroraUdev) -# add_subdirectory(tests/auto/udev) - endif() if(TARGET Liri::AuroraLibInput) # add_subdirectory(tests/manual/libinput) endif() diff --git a/features.cmake b/features.cmake index 9599dbd6..549334ab 100644 --- a/features.cmake +++ b/features.cmake @@ -332,34 +332,6 @@ if(FEATURE_aurora_qpa) message(WARNING "You need gbm for Aurora::QPA") set(FEATURE_aurora_qpa OFF) endif() - #if(NOT TARGET Qt${QT_MAJOR_VERSION}FontDatabaseSupport::Qt${QT_MAJOR_VERSION}FontDatabaseSupport) - # message(WARNING "You need Qt${QT_MAJOR_VERSION}FontDatabaseSupport for Aurora::QPA") - # set(FEATURE_aurora_qpa OFF) - #endif() - #if(NOT TARGET Qt${QT_MAJOR_VERSION}ThemeSupport::Qt${QT_MAJOR_VERSION}ThemeSupport) - # message(WARNING "You need Qt${QT_MAJOR_VERSION}ThemeSupport for Aurora::QPA") - # set(FEATURE_aurora_qpa OFF) - #endif() - #if(NOT TARGET Qt${QT_MAJOR_VERSION}EventDispatcherSupport::Qt${QT_MAJOR_VERSION}EventDispatcherSupport) - # message(WARNING "You need Qt${QT_MAJOR_VERSION}EventDispatcherSupport for Aurora::QPA") - # set(FEATURE_aurora_qpa OFF) - #endif() - #if(NOT TARGET Qt${QT_MAJOR_VERSION}EglSupport::Qt${QT_MAJOR_VERSION}EglSupport) - # message(WARNING "You need Qt${QT_MAJOR_VERSION}EglSupport for Aurora::QPA") - # set(FEATURE_aurora_qpa OFF) - #endif() - #if(NOT TARGET Qt${QT_MAJOR_VERSION}PlatformCompositorSupport::Qt${QT_MAJOR_VERSION}PlatformCompositorSupport) - # message(WARNING "You need Qt${QT_MAJOR_VERSION}PlatformCompositorSupport for Aurora::QPA") - # set(FEATURE_aurora_qpa OFF) - #endif() - #if(NOT TARGET Qt${QT_MAJOR_VERSION}ServiceSupport::Qt${QT_MAJOR_VERSION}ServiceSupport) - # message(WARNING "You need Qt${QT_MAJOR_VERSION}ServiceSupport for Aurora::QPA") - # set(FEATURE_aurora_qpa OFF) - #endif() - #if(NOT TARGET Qt${QT_MAJOR_VERSION}FbSupport::Qt${QT_MAJOR_VERSION}FbSupport) - # message(WARNING "You need Qt${QT_MAJOR_VERSION}FbSupport for Aurora::QPA") - # set(FEATURE_aurora_qpa OFF) - #endif() if(NOT FEATURE_aurora_xkbcommon) message(WARNING "You need XkbCommon support for Aurora::QPA") set(FEATURE_aurora_qpa OFF) @@ -368,28 +340,6 @@ endif() add_feature_info("Aurora::QPA" FEATURE_aurora_qpa "Build Qt platform plugin for Wayland compositors") set(LIRI_FEATURE_aurora_qpa "$") -# x11 -if(FEATURE_aurora_qpa) - option(FEATURE_aurora_qpa_x11 "Qt platform plugin for Wayland compositors: X11 support" ON) - if(FEATURE_aurora_qpa_x11) - find_package(X11) - if(NOT X11_FOUND) - message(WARNING "You need X11 for Aurora::QPA::X11") - set(FEATURE_aurora_qpa_x11 OFF) - endif() - - find_package(XCB COMPONENTS XCB) - if(NOT XCB_FOUND) - message(WARNING "You need XCB for Aurora::QPA::X11") - set(FEATURE_aurora_qpa_x11 OFF) - endif() - endif() -else() - set(FEATURE_aurora_qpa_x11 OFF) -endif() -add_feature_info("Aurora::QPA::X11" FEATURE_aurora_qpa "Build X11 support for the Qt platform plugin for Wayland compositors") -set(LIRI_FEATURE_aurora_qpa_x11 "$") - # shm-emulation-server option(FEATURE_aurora_shm_emulation_server "Shm emulation server" ON) if(FEATURE_aurora_shm_emulation_server) diff --git a/src/platformheaders/CMakeLists.txt b/src/platformheaders/CMakeLists.txt deleted file mode 100644 index 306e8eab..00000000 --- a/src/platformheaders/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2024 Pier Luigi Fiorini -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_module(AuroraPlatformHeaders - DESCRIPTION - "Platform-specific functionality" - SOURCES - lirieglfsfunctions.cpp lirieglfsfunctions.h - CLASS_HEADERS - LiriEglFSFunctions:lirieglfsfunctions.h - DEFINES - QT_NO_CAST_FROM_ASCII - QT_NO_FOREACH - PUBLIC_LIBRARIES - Qt6::Core - Qt6::Gui - PKGCONFIG_DEPENDENCIES - Qt6Core - Qt6Gui -) - -liri_finalize_module(AuroraPlatformHeaders) diff --git a/src/platformheaders/lirieglfsfunctions.cpp b/src/platformheaders/lirieglfsfunctions.cpp deleted file mode 100644 index b0dea69d..00000000 --- a/src/platformheaders/lirieglfsfunctions.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include "lirieglfsfunctions.h" - -namespace Aurora { - -namespace PlatformSupport { - -QByteArray EglFSFunctions::setCursorThemeIdentifier() -{ - return QByteArrayLiteral("LiriEglFSSetCursorTheme"); -} - -void EglFSFunctions::setCursorTheme(const QString &name, int size) -{ - SetCursorThemeType func = reinterpret_cast(QGuiApplication::platformFunction(setCursorThemeIdentifier())); - if (func) - func(name, size); -} - -QByteArray EglFSFunctions::getPowerStateIdentifier() -{ - return QByteArrayLiteral("LiriEglFSGetPowerState"); -} - -EglFSFunctions::PowerState EglFSFunctions::getPowerState(QScreen *screen) -{ - GetPowerStateType func = reinterpret_cast(QGuiApplication::platformFunction(getPowerStateIdentifier())); - if (func) - return func(screen); - return PowerStateOn; -} - -QByteArray EglFSFunctions::setPowerStateIdentifier() -{ - return QByteArrayLiteral("LiriEglFSSetPowerState"); -} - -void EglFSFunctions::setPowerState(QScreen *screen, PowerState state) -{ - SetPowerStateType func = reinterpret_cast(QGuiApplication::platformFunction(setPowerStateIdentifier())); - if (func) - func(screen, state); -} - -QByteArray EglFSFunctions::testScreenChangesIdentifier() -{ - return "LiriEglFSTestScreenChanges"; -} - -bool EglFSFunctions::testScreenChanges(const QVector &changes) -{ - TestScreenChangesType func = reinterpret_cast(QGuiApplication::platformFunction(testScreenChangesIdentifier())); - if (func) - return func(changes); - return false; -} - -QByteArray EglFSFunctions::applyScreenChangesIdentifier() -{ - return "LiriEglFSApplyScreenChanges"; -} - -bool EglFSFunctions::applyScreenChanges(const QVector &changes) -{ - ApplyScreenChangesType func = reinterpret_cast(QGuiApplication::platformFunction(applyScreenChangesIdentifier())); - if (func) - return func(changes); - return false; -} - -QByteArray EglFSFunctions::enableScreenCastIdentifier() -{ - return QByteArrayLiteral("LiriEglFSEnableScreenCast"); -} - -void EglFSFunctions::enableScreenCast(QScreen *screen) -{ - EnableScreenCastType func = reinterpret_cast(QGuiApplication::platformFunction(enableScreenCastIdentifier())); - if (func) - func(screen); -} - -QByteArray EglFSFunctions::disableScreenCastIdentifier() -{ - return QByteArrayLiteral("LiriEglFSDisableStreaming"); -} - -void EglFSFunctions::disableScreenCast(QScreen *screen) -{ - DisableScreenCastType func = reinterpret_cast(QGuiApplication::platformFunction(disableScreenCastIdentifier())); - if (func) - func(screen); -} - -/* - * Screencast - */ - -QEvent::Type ScreenCastFrameEvent::eventType = QEvent::None; - -ScreenCastFrameEvent::ScreenCastFrameEvent() - : QEvent(registeredType()) -{ -} - -QEvent::Type ScreenCastFrameEvent::registeredType() -{ - if (eventType == QEvent::None) { - int generatedType = QEvent::registerEventType(); - eventType = static_cast(generatedType); - } - - return eventType; -} - - -QEvent::Type ScreenCastObjectEvent::eventType = QEvent::None; - -ScreenCastObjectEvent::ScreenCastObjectEvent() - : QEvent(registeredType()) -{ -} - -QEvent::Type ScreenCastObjectEvent::registeredType() -{ - if (eventType == QEvent::None) { - int generatedType = QEvent::registerEventType(); - eventType = static_cast(generatedType); - } - - return eventType; -} - - -QEvent::Type ScreenCastReadyEvent::eventType = QEvent::None; - -ScreenCastReadyEvent::ScreenCastReadyEvent() - : QEvent(registeredType()) -{ -} - -QEvent::Type ScreenCastReadyEvent::registeredType() -{ - if (eventType == QEvent::None) { - int generatedType = QEvent::registerEventType(); - eventType = static_cast(generatedType); - } - - return eventType; -} - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformheaders/lirieglfsfunctions.h b/src/platformheaders/lirieglfsfunctions.h deleted file mode 100644 index 957c2505..00000000 --- a/src/platformheaders/lirieglfsfunctions.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include -#include - -#include - -namespace Aurora { - -namespace PlatformSupport { - -class LIRIAURORAPLATFORMHEADERS_EXPORT ScreenChange -{ -public: - explicit ScreenChange() = default; - - QScreen *screen = nullptr; - bool enabled = false; - QPoint position; - QSize resolution; - int refreshRate = 60; - qreal scale = 1.0f; -}; - -class LIRIAURORAPLATFORMHEADERS_EXPORT EglFSFunctions -{ -public: - enum PowerState { - PowerStateOn, - PowerStateStandby, - PowerStateSuspend, - PowerStateOff - }; - - typedef void (*SetCursorThemeType)(const QString &name, int size); - static QByteArray setCursorThemeIdentifier(); - static void setCursorTheme(const QString &name, int size); - - typedef PowerState (*GetPowerStateType)(QScreen *screen); - static QByteArray getPowerStateIdentifier(); - static PowerState getPowerState(QScreen *screen); - - typedef void (*SetPowerStateType)(QScreen *screen, PowerState state); - static QByteArray setPowerStateIdentifier(); - static void setPowerState(QScreen *screen, PowerState state); - - typedef bool (*TestScreenChangesType)(const QVector &changes); - static QByteArray testScreenChangesIdentifier(); - static bool testScreenChanges(const QVector &changes); - - typedef bool (*ApplyScreenChangesType)(const QVector &changes); - static QByteArray applyScreenChangesIdentifier(); - static bool applyScreenChanges(const QVector &changes); - - typedef void (*EnableScreenCastType)(QScreen *screen); - static QByteArray enableScreenCastIdentifier(); - static void enableScreenCast(QScreen *screen); - - typedef void (*DisableScreenCastType)(QScreen *screen); - static QByteArray disableScreenCastIdentifier(); - static void disableScreenCast(QScreen *screen); -}; - -class LIRIAURORAPLATFORMHEADERS_EXPORT ScreenCastFrameEvent : public QEvent -{ -public: - explicit ScreenCastFrameEvent(); - - QScreen *screen = nullptr; - QPoint offset; - QSize size; - quint32 drmFormat = 0; - quint64 modifier = 0; - quint32 numObjects = 0; - - static QEvent::Type eventType; - - static QEvent::Type registeredType(); -}; - -class LIRIAURORAPLATFORMHEADERS_EXPORT ScreenCastObjectEvent : public QEvent -{ -public: - explicit ScreenCastObjectEvent(); - - QScreen *screen = nullptr; - quint32 index = 0; - int fd = -1; - quint32 size = 0; - quint32 offset = 0; - quint32 stride = 0; - quint32 planeIndex = 0; - - static QEvent::Type eventType; - - static QEvent::Type registeredType(); -}; - -class LIRIAURORAPLATFORMHEADERS_EXPORT ScreenCastReadyEvent : public QEvent -{ -public: - explicit ScreenCastReadyEvent(); - - QScreen *screen = nullptr; - quint64 tv_sec = 0; - quint32 tv_nsec = 0; - - static QEvent::Type eventType; - - static QEvent::Type registeredType(); -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformheaders/liriplatformheadersglobal.h b/src/platformheaders/liriplatformheadersglobal.h deleted file mode 100644 index 732af5b6..00000000 --- a/src/platformheaders/liriplatformheadersglobal.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -#if defined(LIRI_BUILD_PLATFORMHEADERS) -# define LIRIPLATFORMHEADERS_EXPORT Q_DECL_EXPORT -#else -# define LIRIPLATFORMHEADERS_EXPORT Q_DECL_IMPORT -#endif -#define LIRIPLATFORMHEADERS_NO_EXPORT Q_DECL_HIDDEN - diff --git a/src/platformsupport/edid/CMakeLists.txt b/src/platformsupport/edid/CMakeLists.txt deleted file mode 100644 index 9bf54e41..00000000 --- a/src/platformsupport/edid/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_module(AuroraEdidSupport - DESCRIPTION - "EDID parser for EGL device integration" - SOURCES - auroraedidparser.cpp auroraedidparser_p.h - auroraedidvendortable_p.h - PRIVATE_HEADERS - auroraedidparser_p.h - auroraedidvendortable_p.h - DEFINES - QT_NO_CAST_FROM_ASCII - QT_NO_FOREACH - LIBRARIES - Qt::Core - NO_CMAKE - NO_PKGCONFIG - STATIC -) - -liri_finalize_module(AuroraEdidSupport) diff --git a/src/platformsupport/edid/auroraedidparser.cpp b/src/platformsupport/edid/auroraedidparser.cpp deleted file mode 100644 index c33b62f5..00000000 --- a/src/platformsupport/edid/auroraedidparser.cpp +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright (C) 2017 Pier Luigi Fiorini -// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#include -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -# include -#endif - -#include "auroraedidparser_p.h" -#include "auroraedidvendortable_p.h" - -#define EDID_DESCRIPTOR_ALPHANUMERIC_STRING 0xfe -#define EDID_DESCRIPTOR_PRODUCT_NAME 0xfc -#define EDID_DESCRIPTOR_SERIAL_NUMBER 0xff - -#define EDID_DATA_BLOCK_COUNT 4 -#define EDID_OFFSET_DATA_BLOCKS 0x36 -#define EDID_OFFSET_LAST_BLOCK 0x6c -#define EDID_OFFSET_PNP_ID 0x08 -#define EDID_OFFSET_SERIAL 0x0c -#define EDID_PHYSICAL_WIDTH 0x15 -#define EDID_OFFSET_PHYSICAL_HEIGHT 0x16 -#define EDID_TRANSFER_FUNCTION 0x17 -#define EDID_FEATURE_SUPPORT 0x18 -#define EDID_CHROMATICITIES_BLOCK 0x19 - -namespace Aurora { - -namespace PlatformSupport { - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -using namespace Qt::StringLiterals; - -static QString lookupVendorIdInSystemDatabase(QByteArrayView id) -{ - QString result; - - const QString fileName = "/usr/share/hwdata/pnp.ids"_L1; - QFile file(fileName); - if (!file.open(QFile::ReadOnly)) - return result; - - // On Ubuntu 20.04 the longest line in the file is 85 bytes, so this - // leaves plenty of room... - constexpr int MaxLineSize = 512; - char buf[MaxLineSize]; - - while (!file.atEnd()) { - auto read = file.readLine(buf, MaxLineSize); - if (read < 0 || read == MaxLineSize) // read error - break; - - QByteArrayView line(buf, read - 1); // -1 to remove the trailing newline - if (line.isEmpty()) - continue; - - if (line.startsWith('#')) - continue; - - auto tabPosition = line.indexOf('\t'); - if (tabPosition <= 0) // no vendor id - continue; - if (tabPosition + 1 == line.size()) // no vendor name - continue; - - if (line.first(tabPosition) == id) { - auto vendor = line.sliced(tabPosition + 1); - result = QString::fromUtf8(vendor.data(), vendor.size()); - break; - } - } - - return result; -} -#else -static QString lookupVendorIdInSystemDatabase(const QByteArray &id) -{ - QString result; - - const QString fileName = QLatin1String("/usr/share/hwdata/pnp.ids"); - QFile file(fileName); - if (!file.open(QFile::ReadOnly)) - return result; - - // On Ubuntu 20.04 the longest line in the file is 85 bytes, so this - // leaves plenty of room... - constexpr int MaxLineSize = 512; - char buf[MaxLineSize]; - - while (!file.atEnd()) { - auto read = file.readLine(buf, MaxLineSize); - if (read < 0 || read == MaxLineSize) // read error - break; - - QByteArray line(buf, read - 1); // -1 to remove the trailing newline - if (line.isEmpty()) - continue; - - if (line.startsWith('#')) - continue; - - auto tabPosition = line.indexOf('\t'); - if (tabPosition <= 0) // no vendor id - continue; - if (tabPosition + 1 == line.size()) // no vendor name - continue; - - if (qstrncmp(line.constData(), id.constData(), tabPosition) == 0) { - QByteArray vendor(line); - vendor.truncate(tabPosition + 1); - result = QString::fromUtf8(vendor.data(), vendor.size()); - break; - } - } - - return result; -} -#endif - -bool EdidParser::parse(const QByteArray &blob) -{ - const quint8 *data = reinterpret_cast(blob.constData()); - const size_t length = blob.length(); - - // Verify header - if (length < 128) - return false; - if (data[0] != 0x00 || data[1] != 0xff) - return false; - - /* Decode the PNP ID from three 5 bit words packed into 2 bytes - * /--08--\/--09--\ - * 7654321076543210 - * |\---/\---/\---/ - * R C1 C2 C3 */ - char pnpId[3]; - pnpId[0] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x7c) / 4) - 1; - pnpId[1] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x3) * 8) + ((data[EDID_OFFSET_PNP_ID + 1] & 0xe0) / 32) - 1; - pnpId[2] = 'A' + (data[EDID_OFFSET_PNP_ID + 1] & 0x1f) - 1; - - // Clear manufacturer - manufacturer = QString(); - - // Serial number, will be overwritten by an ASCII descriptor - // when and if it will be found - quint32 serial = data[EDID_OFFSET_SERIAL] - + (data[EDID_OFFSET_SERIAL + 1] << 8) - + (data[EDID_OFFSET_SERIAL + 2] << 16) - + (data[EDID_OFFSET_SERIAL + 3] << 24); - if (serial > 0) - serialNumber = QString::number(serial); - else - serialNumber = QString(); - - // Parse EDID data - for (int i = 0; i < EDID_DATA_BLOCK_COUNT; ++i) { - const uint offset = EDID_OFFSET_DATA_BLOCKS + i * 18; - - if (data[offset] != 0 || data[offset + 1] != 0 || data[offset + 2] != 0) - continue; - - if (data[offset + 3] == EDID_DESCRIPTOR_PRODUCT_NAME) - model = parseEdidString(&data[offset + 5]); - else if (data[offset + 3] == EDID_DESCRIPTOR_ALPHANUMERIC_STRING) - identifier = parseEdidString(&data[offset + 5]); - else if (data[offset + 3] == EDID_DESCRIPTOR_SERIAL_NUMBER) - serialNumber = parseEdidString(&data[offset + 5]); - } - - // Try to use cache first because it is potentially more updated - manufacturer = lookupVendorIdInSystemDatabase(pnpId); - - if (manufacturer.isEmpty()) { - // Find the manufacturer from the vendor lookup table - const auto compareVendorId = [](const VendorTable &vendor, const char *str) - { - return strncmp(vendor.id, str, 3) < 0; - }; - - const auto b = std::begin(s_edidVendorTable); - const auto e = std::end(s_edidVendorTable); - auto it = std::lower_bound(b, - e, - pnpId, - compareVendorId); - - if (it != e && strncmp(it->id, pnpId, 3) == 0) - manufacturer = QString::fromUtf8(it->name); - } - - // If we don't know the manufacturer, fallback to PNP ID - if (manufacturer.isEmpty()) - manufacturer = QString::fromUtf8(pnpId, std::size(pnpId)); - - // Physical size - physicalSize = QSizeF(data[EDID_PHYSICAL_WIDTH], data[EDID_OFFSET_PHYSICAL_HEIGHT]) * 10; - - // Gamma and transfer function - const uint igamma = data[EDID_TRANSFER_FUNCTION]; - if (igamma != 0xff) { - gamma = 1.0 + (igamma / 100.0f); - useTables = false; - } else { - gamma = 0.0; // Defined in DI-EXT - useTables = true; - } - sRgb = data[EDID_FEATURE_SUPPORT] & 0x04; - - // Chromaticities - int rx = (data[EDID_CHROMATICITIES_BLOCK] >> 6) & 0x03; - int ry = (data[EDID_CHROMATICITIES_BLOCK] >> 4) & 0x03; - int gx = (data[EDID_CHROMATICITIES_BLOCK] >> 2) & 0x03; - int gy = (data[EDID_CHROMATICITIES_BLOCK] >> 0) & 0x03; - int bx = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 6) & 0x03; - int by = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 4) & 0x03; - int wx = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 2) & 0x03; - int wy = (data[EDID_CHROMATICITIES_BLOCK + 1] >> 0) & 0x03; - rx |= data[EDID_CHROMATICITIES_BLOCK + 2] << 2; - ry |= data[EDID_CHROMATICITIES_BLOCK + 3] << 2; - gx |= data[EDID_CHROMATICITIES_BLOCK + 4] << 2; - gy |= data[EDID_CHROMATICITIES_BLOCK + 5] << 2; - bx |= data[EDID_CHROMATICITIES_BLOCK + 6] << 2; - by |= data[EDID_CHROMATICITIES_BLOCK + 7] << 2; - wx |= data[EDID_CHROMATICITIES_BLOCK + 8] << 2; - wy |= data[EDID_CHROMATICITIES_BLOCK + 9] << 2; - - redChromaticity.setX(rx * (1.0f / 1024.0f)); - redChromaticity.setY(ry * (1.0f / 1024.0f)); - greenChromaticity.setX(gx * (1.0f / 1024.0f)); - greenChromaticity.setY(gy * (1.0f / 1024.0f)); - blueChromaticity.setX(bx * (1.0f / 1024.0f)); - blueChromaticity.setY(by * (1.0f / 1024.0f)); - whiteChromaticity.setX(wx * (1.0f / 1024.0f)); - whiteChromaticity.setY(wy * (1.0f / 1024.0f)); - - // Find extensions - for (uint i = 1; i < length / 128; ++i) { - uint extensionId = data[i * 128]; - if (extensionId == 0x40) { // DI-EXT - // 0x0E (sub-pixel layout) - // 0x20->0x22 (bits per color) - // 0x51->0x7e Transfer characteristics - const uchar desc = data[i * 128 + 0x51]; - const uchar len = desc & 0x3f; - if ((desc & 0xc0) == 0x40) { - if (len > 45) - return false; - QList whiteTRC; - whiteTRC.reserve(len + 1); - for (uint j = 0; j < len; ++j) - whiteTRC[j] = data[0x52 + j] * 0x101; - whiteTRC[len] = 0xffff; - tables.append(whiteTRC); - } else if ((desc & 0xc0) == 0x80) { - if (len > 15) - return false; - QList redTRC; - QList greenTRC; - QList blueTRC; - blueTRC.reserve(len + 1); - greenTRC.reserve(len + 1); - redTRC.reserve(len + 1); - for (uint j = 0; j < len; ++j) - blueTRC[j] = data[0x52 + j] * 0x101; - blueTRC[len] = 0xffff; - for (uint j = 0; j < len; ++j) - greenTRC[j] = data[0x61 + j] * 0x101; - greenTRC[len] = 0xffff; - for (uint j = 0; j < len; ++j) - redTRC[j] = data[0x70 + j] * 0x101; - redTRC[len] = 0xffff; - tables.append(redTRC); - tables.append(greenTRC); - tables.append(blueTRC); - } - } - } - - return true; -} - -QString EdidParser::parseEdidString(const quint8 *data) -{ - QByteArray buffer(reinterpret_cast(data), 13); - - // Erase carriage return and line feed - buffer = buffer.replace('\r', '\0').replace('\n', '\0'); - - // Replace non-printable characters with dash - for (int i = 0; i < buffer.size(); ++i) { - if (buffer[i] < '\040' || buffer[i] > '\176') - buffer[i] = '-'; - } - - return QString::fromLatin1(buffer.trimmed()); -} - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/edid/auroraedidparser_p.h b/src/platformsupport/edid/auroraedidparser_p.h deleted file mode 100644 index 4b86fdba..00000000 --- a/src/platformsupport/edid/auroraedidparser_p.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2017 Pier Luigi Fiorini -// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#pragma once - -#include -#include -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include - -#include - -namespace Aurora { - -namespace PlatformSupport { - -class LIRIAURORAEDIDSUPPORT_EXPORT EdidParser -{ -public: - bool parse(const QByteArray &blob); - - QString identifier; - QString manufacturer; - QString model; - QString serialNumber; - QSizeF physicalSize; - qreal gamma; - QPointF redChromaticity; - QPointF greenChromaticity; - QPointF blueChromaticity; - QPointF whiteChromaticity; - QList> tables; - bool sRgb; - bool useTables; - -private: - QString parseEdidString(const quint8 *data); -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/edid/auroraedidvendortable_p.h b/src/platformsupport/edid/auroraedidvendortable_p.h deleted file mode 100644 index f7696786..00000000 --- a/src/platformsupport/edid/auroraedidvendortable_p.h +++ /dev/null @@ -1,2507 +0,0 @@ -// Copyright (C) 2017 Pier Luigi Fiorini -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -/* - * This lookup table was generated from https://github.com/vcrhonek/hwdata/raw/master/pnp.ids - * - * Do not change this file directly, instead edit the - * src/platformsupport/edid/qedidvendortable.py script and regenerate this file. - */ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -namespace Aurora { - -namespace PlatformSupport { - -struct VendorTable { - const char id[4]; - const char name[78]; -}; - -static const VendorTable s_edidVendorTable[] = { - { "AAA", "Avolites Ltd" }, - { "AAE", "Anatek Electronics Inc." }, - { "AAM", "Aava Mobile Oy" }, - { "AAN", "AAEON Technology Inc." }, - { "AAT", "Ann Arbor Technologies" }, - { "ABA", "ABBAHOME INC." }, - { "ABC", "AboCom System Inc." }, - { "ABD", "Allen Bradley Company" }, - { "ABE", "Alcatel Bell" }, - { "ABO", "D-Link Systems Inc" }, - { "ABS", "Abaco Systems, Inc." }, - { "ABT", "Anchor Bay Technologies, Inc." }, - { "ABV", "Advanced Research Technology" }, - { "ACA", "Ariel Corporation" }, - { "ACB", "Aculab Ltd" }, - { "ACC", "Accton Technology Corporation" }, - { "ACD", "AWETA BV" }, - { "ACE", "Actek Engineering Pty Ltd" }, - { "ACG", "A&R Cambridge Ltd." }, - { "ACH", "Archtek Telecom Corporation" }, - { "ACI", "Ancor Communications Inc" }, - { "ACK", "Acksys" }, - { "ACL", "Apricot Computers" }, - { "ACM", "Acroloop Motion Control Systems Inc" }, - { "ACO", "Allion Computer Inc." }, - { "ACP", "Aspen Tech Inc" }, - { "ACR", "Acer Technologies" }, - { "ACS", "Altos Computer Systems" }, - { "ACT", "Applied Creative Technology" }, - { "ACU", "Acculogic" }, - { "ACV", "ActivCard S.A" }, - { "ADA", "Addi-Data GmbH" }, - { "ADB", "Aldebbaron" }, - { "ADC", "Acnhor Datacomm" }, - { "ADD", "Advanced Peripheral Devices Inc" }, - { "ADE", "Arithmos, Inc." }, - { "ADH", "Aerodata Holdings Ltd" }, - { "ADI", "ADI Systems Inc" }, - { "ADK", "Adtek System Science Company Ltd" }, - { "ADL", "ASTRA Security Products Ltd" }, - { "ADM", "Ad Lib MultiMedia Inc" }, - { "ADN", "Analog & Digital Devices Tel. Inc" }, - { "ADP", "Adaptec Inc" }, - { "ADR", "Nasa Ames Research Center" }, - { "ADS", "Analog Devices Inc" }, - { "ADT", "Adtek" }, - { "ADV", "Advanced Micro Devices Inc" }, - { "ADX", "Adax Inc" }, - { "ADZ", "ADDER TECHNOLOGY LTD" }, - { "AEC", "Antex Electronics Corporation" }, - { "AED", "Advanced Electronic Designs, Inc." }, - { "AEI", "Actiontec Electric Inc" }, - { "AEJ", "Alpha Electronics Company" }, - { "AEM", "ASEM S.p.A." }, - { "AEN", "Avencall" }, - { "AEP", "Aetas Peripheral International" }, - { "AET", "Aethra Telecomunicazioni S.r.l." }, - { "AFA", "Alfa Inc" }, - { "AGC", "Beijing Aerospace Golden Card Electronic Engineering Co.,Ltd." }, - { "AGI", "Artish Graphics Inc" }, - { "AGL", "Argolis" }, - { "AGM", "Advan Int'l Corporation" }, - { "AGO", "AlgolTek, Inc." }, - { "AGT", "Agilent Technologies" }, - { "AHC", "Advantech Co., Ltd." }, - { "AHQ", "Astro HQ LLC" }, - { "AHS", "Beijing AnHeng SecoTech Information Technology Co., Ltd." }, - { "AIC", "Arnos Insturments & Computer Systems" }, - { "AIE", "Altmann Industrieelektronik" }, - { "AII", "Amptron International Inc." }, - { "AIK", "Dongguan Alllike Electronics Co., Ltd." }, - { "AIL", "Altos India Ltd" }, - { "AIM", "AIMS Lab Inc" }, - { "AIR", "Advanced Integ. Research Inc" }, - { "AIS", "Alien Internet Services" }, - { "AIW", "Aiwa Company Ltd" }, - { "AIX", "ALTINEX, INC." }, - { "AJA", "AJA Video Systems, Inc." }, - { "AKB", "Akebia Ltd" }, - { "AKE", "AKAMI Electric Co.,Ltd" }, - { "AKI", "AKIA Corporation" }, - { "AKL", "AMiT Ltd" }, - { "AKM", "Asahi Kasei Microsystems Company Ltd" }, - { "AKP", "Atom Komplex Prylad" }, - { "AKY", "Askey Computer Corporation" }, - { "ALA", "Alacron Inc" }, - { "ALC", "Altec Corporation" }, - { "ALD", "In4S Inc" }, - { "ALE", "Alenco BV" }, - { "ALG", "Realtek Semiconductor Corp." }, - { "ALH", "AL Systems" }, - { "ALI", "Acer Labs" }, - { "ALJ", "Altec Lansing" }, - { "ALK", "Acrolink Inc" }, - { "ALL", "Alliance Semiconductor Corporation" }, - { "ALM", "Acutec Ltd." }, - { "ALN", "Alana Technologies" }, - { "ALO", "Algolith Inc." }, - { "ALP", "ALPS ALPINE CO., LTD." }, - { "ALR", "Advanced Logic" }, - { "ALS", "Avance Logic Inc" }, - { "ALT", "Altra" }, - { "ALV", "AlphaView LCD" }, - { "ALX", "ALEXON Co.,Ltd." }, - { "AMA", "Asia Microelectronic Development Inc" }, - { "AMB", "Ambient Technologies, Inc." }, - { "AMC", "Attachmate Corporation" }, - { "AMD", "Amdek Corporation" }, - { "AMI", "American Megatrends Inc" }, - { "AML", "Anderson Multimedia Communications (HK) Limited" }, - { "AMN", "Amimon LTD." }, - { "AMO", "Amino Technologies PLC and Amino Communications Limited" }, - { "AMP", "AMP Inc" }, - { "AMR", "AmTRAN Technology Co., Ltd." }, - { "AMS", "ARMSTEL, Inc." }, - { "AMT", "AMT International Industry" }, - { "AMX", "AMX LLC" }, - { "ANA", "Anakron" }, - { "ANC", "Ancot" }, - { "AND", "Adtran Inc" }, - { "ANI", "Anigma Inc" }, - { "ANK", "Anko Electronic Company Ltd" }, - { "ANL", "Analogix Semiconductor, Inc" }, - { "ANO", "Anorad Corporation" }, - { "ANP", "Andrew Network Production" }, - { "ANR", "ANR Ltd" }, - { "ANS", "Ansel Communication Company" }, - { "ANT", "Ace CAD Enterprise Company Ltd" }, - { "ANV", "Beijing ANTVR Technology Co., Ltd." }, - { "ANW", "Analog Way SAS" }, - { "ANX", "Acer Netxus Inc" }, - { "AOA", "AOpen Inc." }, - { "AOE", "Advanced Optics Electronics, Inc." }, - { "AOL", "America OnLine" }, - { "AOT", "Alcatel" }, - { "APC", "American Power Conversion" }, - { "APD", "AppliAdata" }, - { "APE", "ALPS ALPINE CO., LTD." }, - { "APG", "Horner Electric Inc" }, - { "API", "A Plus Info Corporation" }, - { "APL", "Aplicom Oy" }, - { "APM", "Applied Memory Tech" }, - { "APN", "Appian Tech Inc" }, - { "APP", "Apple Computer Inc" }, - { "APR", "Aprilia s.p.a." }, - { "APS", "Autologic Inc" }, - { "APT", "Audio Processing Technology Ltd" }, - { "APV", "A+V Link" }, - { "APX", "AP Designs Ltd" }, - { "ARC", "Alta Research Corporation" }, - { "ARD", "AREC Inc." }, - { "ARE", "ICET S.p.A." }, - { "ARG", "Argus Electronics Co., LTD" }, - { "ARI", "Argosy Research Inc" }, - { "ARK", "Ark Logic Inc" }, - { "ARL", "Arlotto Comnet Inc" }, - { "ARM", "Arima" }, - { "ARO", "Poso International B.V." }, - { "ARR", "ARRIS Group, Inc." }, - { "ARS", "Arescom Inc" }, - { "ART", "Corion Industrial Corporation" }, - { "ASC", "Ascom Strategic Technology Unit" }, - { "ASD", "USC Information Sciences Institute" }, - { "ASE", "AseV Display Labs" }, - { "ASH", "Ashton Bentley Concepts" }, - { "ASI", "Ahead Systems" }, - { "ASK", "Ask A/S" }, - { "ASL", "AccuScene Corporation Ltd" }, - { "ASM", "ASEM S.p.A." }, - { "ASN", "Asante Tech Inc" }, - { "ASP", "ASP Microelectronics Ltd" }, - { "AST", "AST Research Inc" }, - { "ASU", "Asuscom Network Inc" }, - { "ASX", "AudioScience" }, - { "ASY", "Rockwell Collins / Airshow Systems" }, - { "ATA", "Allied Telesyn International (Asia) Pte Ltd" }, - { "ATC", "Ably-Tech Corporation" }, - { "ATD", "Alpha Telecom Inc" }, - { "ATE", "Innovate Ltd" }, - { "ATH", "Athena Informatica S.R.L." }, - { "ATI", "Allied Telesis KK" }, - { "ATJ", "ArchiTek Corporation" }, - { "ATK", "Allied Telesyn Int'l" }, - { "ATL", "Arcus Technology Ltd" }, - { "ATM", "ATM Ltd" }, - { "ATN", "Athena Smartcard Solutions Ltd." }, - { "ATO", "ASTRO DESIGN, INC." }, - { "ATP", "Alpha-Top Corporation" }, - { "ATT", "AT&T" }, - { "ATV", "Office Depot, Inc." }, - { "ATX", "Athenix Corporation" }, - { "AUG", "August Home, Inc." }, - { "AUI", "ALPS ALPINE CO., LTD." }, - { "AUO", "AU Optronics" }, - { "AUR", "Aureal Semiconductor" }, - { "AUS", "ASUSTek COMPUTER INC" }, - { "AUT", "Autotime Corporation" }, - { "AUV", "Auvidea GmbH" }, - { "AVA", "Avaya Communication" }, - { "AVC", "Auravision Corporation" }, - { "AVD", "Avid Electronics Corporation" }, - { "AVE", "Add Value Enterpises (Asia) Pte Ltd" }, - { "AVG", "Avegant Corporation" }, - { "AVI", "Nippon Avionics Co.,Ltd" }, - { "AVJ", "Atelier Vision Corporation" }, - { "AVL", "Avalue Technology Inc." }, - { "AVM", "AVM GmbH" }, - { "AVN", "Advance Computer Corporation" }, - { "AVO", "Avocent Corporation" }, - { "AVR", "AVer Information Inc." }, - { "AVS", "Avatron Software Inc." }, - { "AVT", "Avtek (Electronics) Pty Ltd" }, - { "AVV", "SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.)" }, - { "AVX", "A/Vaux Electronics" }, - { "AWC", "Access Works Comm Inc" }, - { "AWL", "Aironet Wireless Communications, Inc" }, - { "AWS", "Wave Systems" }, - { "AXB", "Adrienne Electronics Corporation" }, - { "AXC", "AXIOMTEK CO., LTD." }, - { "AXE", "Axell Corporation" }, - { "AXI", "American Magnetics" }, - { "AXL", "Axel" }, - { "AXO", "Axonic Labs LLC" }, - { "AXP", "American Express" }, - { "AXT", "Axtend Technologies Inc" }, - { "AXX", "Axxon Computer Corporation" }, - { "AXY", "AXYZ Automation Services, Inc" }, - { "AYD", "Aydin Displays" }, - { "AYR", "Airlib, Inc" }, - { "AZH", "Shenzhen three Connaught Information Technology Co., Ltd. (3nod Group)" }, - { "AZM", "AZ Middelheim - Radiotherapy" }, - { "AZT", "Aztech Systems Ltd" }, - { "BAC", "Biometric Access Corporation" }, - { "BAN", "Banyan" }, - { "BBB", "an-najah university" }, - { "BBH", "B&Bh" }, - { "BBL", "Brain Boxes Limited" }, - { "BBV", "BlueBox Video Limited" }, - { "BBX", "Black Box Corporation" }, - { "BCC", "Beaver Computer Corporaton" }, - { "BCD", "Barco GmbH" }, - { "BCI", "Broadata Communications Inc." }, - { "BCM", "Broadcom" }, - { "BCQ", "Deutsche Telekom Berkom GmbH" }, - { "BCS", "Booria CAD/CAM systems" }, - { "BDO", "Brahler ICS" }, - { "BDR", "Blonder Tongue Labs, Inc." }, - { "BDS", "Barco Display Systems" }, - { "BEC", "Beckhoff Automation" }, - { "BEI", "Beckworth Enterprises Inc" }, - { "BEK", "Beko Elektronik A.S." }, - { "BEL", "Beltronic Industrieelektronik GmbH" }, - { "BEO", "Baug & Olufsen" }, - { "BFE", "B.F. Engineering Corporation" }, - { "BGB", "Barco Graphics N.V" }, - { "BGT", "Budzetron Inc" }, - { "BHZ", "BitHeadz, Inc." }, - { "BIA", "Biamp Systems Corporation" }, - { "BIC", "Big Island Communications" }, - { "BII", "Boeckeler Instruments Inc" }, - { "BIL", "Billion Electric Company Ltd" }, - { "BIO", "BioLink Technologies International, Inc." }, - { "BIT", "Bit 3 Computer" }, - { "BLD", "BILD INNOVATIVE TECHNOLOGY LLC" }, - { "BLI", "Busicom" }, - { "BLN", "BioLink Technologies" }, - { "BLP", "Bloomberg L.P." }, - { "BMD", "Blackmagic Design" }, - { "BMI", "Benson Medical Instruments Company" }, - { "BML", "BIOMED Lab" }, - { "BMS", "BIOMEDISYS" }, - { "BNE", "Bull AB" }, - { "BNK", "Banksia Tech Pty Ltd" }, - { "BNO", "Bang & Olufsen" }, - { "BNS", "Boulder Nonlinear Systems" }, - { "BOB", "Rainy Orchard" }, - { "BOE", "BOE" }, - { "BOI", "NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD" }, - { "BOS", "BOS" }, - { "BPD", "Micro Solutions, Inc." }, - { "BPS", "Barco, N.V." }, - { "BPU", "Best Power" }, - { "BRA", "Braemac Pty Ltd" }, - { "BRC", "BARC" }, - { "BRG", "Bridge Information Co., Ltd" }, - { "BRI", "Boca Research Inc" }, - { "BRM", "Braemar Inc" }, - { "BRO", "BROTHER INDUSTRIES,LTD." }, - { "BSE", "Bose Corporation" }, - { "BSG", "Robert Bosch GmbH" }, - { "BSL", "Biomedical Systems Laboratory" }, - { "BSN", "BRIGHTSIGN, LLC" }, - { "BST", "BodySound Technologies, Inc." }, - { "BTC", "Bit 3 Computer" }, - { "BTE", "Brilliant Technology" }, - { "BTF", "Bitfield Oy" }, - { "BTI", "BusTech Inc" }, - { "BTO", "BioTao Ltd" }, - { "BUF", "Yasuhiko Shirai Melco Inc" }, - { "BUG", "B.U.G., Inc." }, - { "BUJ", "ATI Tech Inc" }, - { "BUL", "Bull" }, - { "BUR", "Bernecker & Rainer Ind-Eletronik GmbH" }, - { "BUS", "BusTek" }, - { "BUT", "21ST CENTURY ENTERTAINMENT" }, - { "BWK", "Bitworks Inc." }, - { "BXE", "Buxco Electronics" }, - { "BYD", "byd:sign corporation" }, - { "CAA", "Castles Automation Co., Ltd" }, - { "CAC", "CA & F Elettronica" }, - { "CAG", "CalComp" }, - { "CAI", "Canon Inc." }, - { "CAL", "Acon" }, - { "CAM", "Cambridge Audio" }, - { "CAN", "Canopus Company Ltd" }, - { "CAR", "Cardinal Company Ltd" }, - { "CAS", "CASIO COMPUTER CO.,LTD" }, - { "CAT", "Consultancy in Advanced Technology" }, - { "CAV", "Cavium Networks, Inc" }, - { "CBI", "ComputerBoards Inc" }, - { "CBR", "Cebra Tech A/S" }, - { "CBT", "Cabletime Ltd" }, - { "CBX", "Cybex Computer Products Corporation" }, - { "CCC", "C-Cube Microsystems" }, - { "CCI", "Cache" }, - { "CCJ", "CONTEC CO.,LTD." }, - { "CCL", "CCL/ITRI" }, - { "CCP", "Capetronic USA Inc" }, - { "CDC", "Core Dynamics Corporation" }, - { "CDD", "Convergent Data Devices" }, - { "CDE", "Colin.de" }, - { "CDG", "Christie Digital Systems Inc" }, - { "CDI", "Concept Development Inc" }, - { "CDK", "Cray Communications" }, - { "CDN", "Codenoll Technical Corporation" }, - { "CDP", "CalComp" }, - { "CDS", "Computer Diagnostic Systems" }, - { "CDT", "IBM Corporation" }, - { "CDV", "Convergent Design Inc." }, - { "CEA", "Consumer Electronics Association" }, - { "CEC", "Chicony Electronics Company Ltd" }, - { "CED", "Cambridge Electronic Design Ltd" }, - { "CEF", "Cefar Digital Vision" }, - { "CEI", "Crestron Electronics, Inc." }, - { "CEM", "MEC Electronics GmbH" }, - { "CEN", "Centurion Technologies P/L" }, - { "CEP", "C-DAC" }, - { "CER", "Ceronix" }, - { "CET", "TEC CORPORATION" }, - { "CFG", "Atlantis" }, - { "CFR", "Meta View, Inc." }, - { "CGA", "Chunghwa Picture Tubes, LTD" }, - { "CGS", "Chyron Corp" }, - { "CGT", "congatec AG" }, - { "CHA", "Chase Research PLC" }, - { "CHD", "ChangHong Electric Co.,Ltd" }, - { "CHE", "Acer Inc" }, - { "CHG", "Sichuan Changhong Electric CO, LTD." }, - { "CHI", "Chrontel Inc" }, - { "CHL", "Chloride-R&D" }, - { "CHM", "CHIC TECHNOLOGY CORP." }, - { "CHO", "Sichuang Changhong Corporation" }, - { "CHP", "CH Products" }, - { "CHR", "christmann informationstechnik + medien GmbH & Co. KG" }, - { "CHS", "Agentur Chairos" }, - { "CHT", "Chunghwa Picture Tubes,LTD." }, - { "CHY", "Cherry GmbH" }, - { "CIC", "Comm. Intelligence Corporation" }, - { "CIE", "Convergent Engineering, Inc." }, - { "CII", "Cromack Industries Inc" }, - { "CIL", "Citicom Infotech Private Limited" }, - { "CIN", "Citron GmbH" }, - { "CIP", "Ciprico Inc" }, - { "CIR", "Cirrus Logic Inc" }, - { "CIS", "Cisco Systems Inc" }, - { "CIT", "Citifax Limited" }, - { "CKC", "The Concept Keyboard Company Ltd" }, - { "CKJ", "Carina System Co., Ltd." }, - { "CLA", "Clarion Company Ltd" }, - { "CLD", "COMMAT L.t.d." }, - { "CLE", "Classe Audio" }, - { "CLG", "CoreLogic" }, - { "CLI", "Cirrus Logic Inc" }, - { "CLM", "CrystaLake Multimedia" }, - { "CLO", "Clone Computers" }, - { "CLR", "Clover Electronics" }, - { "CLT", "automated computer control systems" }, - { "CLV", "Clevo Company" }, - { "CLX", "CardLogix" }, - { "CMC", "CMC Ltd" }, - { "CMD", "Colorado MicroDisplay, Inc." }, - { "CMG", "Chenming Mold Ind. Corp." }, - { "CMI", "C-Media Electronics" }, - { "CMK", "Comark LLC" }, - { "CMM", "Comtime GmbH" }, - { "CMN", "Chimei Innolux Corporation" }, - { "CMO", "Chi Mei Optoelectronics corp." }, - { "CMR", "Cambridge Research Systems Ltd" }, - { "CMS", "CompuMaster Srl" }, - { "CMX", "Comex Electronics AB" }, - { "CNB", "American Power Conversion" }, - { "CNC", "Alvedon Computers Ltd" }, - { "CND", "Micro-Star Int'l Co., Ltd." }, - { "CNE", "Cine-tal" }, - { "CNI", "Connect Int'l A/S" }, - { "CNN", "Canon Inc" }, - { "CNT", "COINT Multimedia Systems" }, - { "COB", "COBY Electronics Co., Ltd" }, - { "COD", "CODAN Pty. Ltd." }, - { "COI", "Codec Inc." }, - { "COL", "Rockwell Collins, Inc." }, - { "COM", "Comtrol Corporation" }, - { "CON", "Contec Company Ltd" }, - { "COO", "coolux GmbH" }, - { "COR", "Corollary Inc" }, - { "COS", "CoStar Corporation" }, - { "COT", "Core Technology Inc" }, - { "COW", "Polycow Productions" }, - { "COX", "Comrex" }, - { "CPC", "Ciprico Inc" }, - { "CPD", "CompuAdd" }, - { "CPI", "Computer Peripherals Inc" }, - { "CPL", "Compal Electronics Inc" }, - { "CPM", "Capella Microsystems Inc." }, - { "CPP", "Compound Photonics" }, - { "CPQ", "Compaq Computer Company" }, - { "CPT", "cPATH" }, - { "CPX", "Powermatic Data Systems" }, - { "CRA", "CRALTECH ELECTRONICA, S.L." }, - { "CRC", "CONRAC GmbH" }, - { "CRD", "Cardinal Technical Inc" }, - { "CRE", "Creative Labs Inc" }, - { "CRH", "Contemporary Research Corp." }, - { "CRI", "Crio Inc." }, - { "CRL", "Creative Logic" }, - { "CRM", "CORSAIR MEMORY Inc." }, - { "CRN", "Cornerstone Imaging" }, - { "CRO", "Extraordinary Technologies PTY Limited" }, - { "CRQ", "Cirque Corporation" }, - { "CRS", "Crescendo Communication Inc" }, - { "CRV", "Cerevo Inc." }, - { "CRW", "Cammegh Limited" }, - { "CRX", "Cyrix Corporation" }, - { "CSB", "Transtex SA" }, - { "CSC", "Crystal Semiconductor" }, - { "CSD", "Cresta Systems Inc" }, - { "CSE", "Concept Solutions & Engineering" }, - { "CSI", "Cabletron System Inc" }, - { "CSL", "Cloudium Systems Ltd." }, - { "CSM", "Cosmic Engineering Inc." }, - { "CSO", "California Institute of Technology" }, - { "CSS", "CSS Laboratories" }, - { "CST", "CSTI Inc" }, - { "CTA", "CoSystems Inc" }, - { "CTC", "CTC Communication Development Company Ltd" }, - { "CTE", "Chunghwa Telecom Co., Ltd." }, - { "CTL", "Creative Technology Ltd" }, - { "CTM", "Computerm Corporation" }, - { "CTN", "Computone Products" }, - { "CTP", "Computer Technology Corporation" }, - { "CTR", "Control4 Corporation" }, - { "CTS", "Comtec Systems Co., Ltd." }, - { "CTX", "Creatix Polymedia GmbH" }, - { "CUB", "Cubix Corporation" }, - { "CUK", "Calibre UK Ltd" }, - { "CVA", "Covia Inc." }, - { "CVI", "Colorado Video, Inc." }, - { "CVP", "Chromatec Video Products Ltd" }, - { "CVS", "Clarity Visual Systems" }, - { "CWC", "Curtiss-Wright Controls, Inc." }, - { "CWR", "Connectware Inc" }, - { "CXT", "Conexant Systems" }, - { "CYB", "CyberVision" }, - { "CYC", "Cylink Corporation" }, - { "CYD", "Cyclades Corporation" }, - { "CYL", "Cyberlabs" }, - { "CYP", "CYPRESS SEMICONDUCTOR CORPORATION" }, - { "CYT", "Cytechinfo Inc" }, - { "CYV", "Cyviz AS" }, - { "CYW", "Cyberware" }, - { "CYX", "Cyrix Corporation" }, - { "CZC", "Shenzhen ChuangZhiCheng Technology Co., Ltd." }, - { "CZE", "Carl Zeiss AG" }, - { "DAC", "Digital Acoustics Corporation" }, - { "DAE", "Digatron Industrie Elektronik GmbH" }, - { "DAI", "DAIS SET Ltd." }, - { "DAK", "Daktronics" }, - { "DAL", "Digital Audio Labs Inc" }, - { "DAN", "Danelec Marine A/S" }, - { "DAS", "DAVIS AS" }, - { "DAT", "Datel Inc" }, - { "DAU", "Daou Tech Inc" }, - { "DAV", "Davicom Semiconductor Inc" }, - { "DAW", "DA2 Technologies Inc" }, - { "DAX", "Data Apex Ltd" }, - { "DBD", "Diebold Inc." }, - { "DBI", "DigiBoard Inc" }, - { "DBK", "Databook Inc" }, - { "DBL", "Doble Engineering Company" }, - { "DBN", "DB Networks Inc" }, - { "DCA", "Digital Communications Association" }, - { "DCC", "Dale Computer Corporation" }, - { "DCD", "Datacast LLC" }, - { "DCE", "dSPACE GmbH" }, - { "DCI", "Concepts Inc" }, - { "DCL", "Dynamic Controls Ltd" }, - { "DCM", "DCM Data Products" }, - { "DCO", "Dialogue Technology Corporation" }, - { "DCR", "Decros Ltd" }, - { "DCS", "Diamond Computer Systems Inc" }, - { "DCT", "Dancall Telecom A/S" }, - { "DCV", "Datatronics Technology Inc" }, - { "DDA", "DA2 Technologies Corporation" }, - { "DDD", "Danka Data Devices" }, - { "DDE", "Datasat Digital Entertainment" }, - { "DDI", "Data Display AG" }, - { "DDS", "Barco, N.V." }, - { "DDT", "Datadesk Technologies Inc" }, - { "DDV", "Delta Information Systems, Inc" }, - { "DEC", "Digital Equipment Corporation" }, - { "DEI", "Deico Electronics" }, - { "DEL", "Dell Inc." }, - { "DEN", "Densitron Computers Ltd" }, - { "DEX", "idex displays" }, - { "DFI", "DFI" }, - { "DFK", "SharkTec A/S" }, - { "DFT", "DEI Holdings dba Definitive Technology" }, - { "DGA", "Digiital Arts Inc" }, - { "DGC", "Data General Corporation" }, - { "DGI", "DIGI International" }, - { "DGK", "DugoTech Co., LTD" }, - { "DGP", "Digicorp European sales S.A." }, - { "DGS", "Diagsoft Inc" }, - { "DGT", "Dearborn Group Technology" }, - { "DHD", "Dension Audio Systems" }, - { "DHP", "DH Print" }, - { "DHQ", "Quadram" }, - { "DHT", "Projectavision Inc" }, - { "DIA", "Diadem" }, - { "DIG", "Digicom S.p.A." }, - { "DII", "Dataq Instruments Inc" }, - { "DIM", "dPict Imaging, Inc." }, - { "DIN", "Daintelecom Co., Ltd" }, - { "DIS", "Diseda S.A." }, - { "DIT", "Dragon Information Technology" }, - { "DJE", "Capstone Visual Product Development" }, - { "DJP", "Maygay Machines, Ltd" }, - { "DKY", "Datakey Inc" }, - { "DLB", "Dolby Laboratories Inc." }, - { "DLC", "Diamond Lane Comm. Corporation" }, - { "DLG", "Digital-Logic GmbH" }, - { "DLK", "D-Link Systems Inc" }, - { "DLL", "Dell Inc" }, - { "DLO", "Shenzhen Dlodlo Technologies Co., Ltd." }, - { "DLT", "Digitelec Informatique Park Cadera" }, - { "DMB", "Digicom Systems Inc" }, - { "DMC", "Dune Microsystems Corporation" }, - { "DMM", "Dimond Multimedia Systems Inc" }, - { "DMN", "Dimension Engineering LLC" }, - { "DMO", "Data Modul AG" }, - { "DMP", "D&M Holdings Inc, Professional Business Company" }, - { "DMS", "DOME imaging systems" }, - { "DMT", "Distributed Management Task Force, Inc. (DMTF)" }, - { "DMV", "NDS Ltd" }, - { "DNA", "DNA Enterprises, Inc." }, - { "DNG", "Apache Micro Peripherals Inc" }, - { "DNI", "Deterministic Networks Inc." }, - { "DNT", "Dr. Neuhous Telekommunikation GmbH" }, - { "DNV", "DiCon" }, - { "DOL", "Dolman Technologies Group Inc" }, - { "DOM", "Dome Imaging Systems" }, - { "DON", "DENON, Ltd." }, - { "DOT", "Dotronic Mikroelektronik GmbH" }, - { "DPA", "DigiTalk Pro AV" }, - { "DPC", "Delta Electronics Inc" }, - { "DPH", "Delphi Automotive LLP" }, - { "DPI", "DocuPoint" }, - { "DPL", "Digital Projection Limited" }, - { "DPM", "ADPM Synthesis sas" }, - { "DPN", "Shanghai Lexiang Technology Limited" }, - { "DPS", "Digital Processing Systems" }, - { "DPT", "DPT" }, - { "DPX", "DpiX, Inc." }, - { "DQB", "Datacube Inc" }, - { "DRB", "Dr. Bott KG" }, - { "DRC", "Data Ray Corp." }, - { "DRD", "DIGITAL REFLECTION INC." }, - { "DRI", "Data Race Inc" }, - { "DRS", "DRS Defense Solutions, LLC" }, - { "DSA", "Display Solution AG" }, - { "DSD", "DS Multimedia Pte Ltd" }, - { "DSG", "Disguise Technologies" }, - { "DSI", "Digitan Systems Inc" }, - { "DSJ", "VR Technology Holdings Limited" }, - { "DSM", "DSM Digital Services GmbH" }, - { "DSP", "Domain Technology Inc" }, - { "DTA", "DELTATEC" }, - { "DTC", "DTC Tech Corporation" }, - { "DTE", "Dimension Technologies, Inc." }, - { "DTI", "Diversified Technology, Inc." }, - { "DTK", "Dynax Electronics (HK) Ltd" }, - { "DTL", "e-Net Inc" }, - { "DTN", "Datang Telephone Co" }, - { "DTO", "Deutsche Thomson OHG" }, - { "DTT", "Design & Test Technology, Inc." }, - { "DTX", "Data Translation" }, - { "DUA", "Dosch & Amand GmbH & Company KG" }, - { "DUN", "NCR Corporation" }, - { "DVD", "Dictaphone Corporation" }, - { "DVL", "Devolo AG" }, - { "DVS", "Digital Video System" }, - { "DVT", "Data Video" }, - { "DWE", "Daewoo Electronics Company Ltd" }, - { "DXC", "Digipronix Control Systems" }, - { "DXD", "DECIMATOR DESIGN PTY LTD" }, - { "DXL", "Dextera Labs Inc" }, - { "DXP", "Data Expert Corporation" }, - { "DXS", "Signet" }, - { "DYC", "Dycam Inc" }, - { "DYM", "Dymo-CoStar Corporation" }, - { "DYN", "Askey Computer Corporation" }, - { "DYX", "Dynax Electronics (HK) Ltd" }, - { "EAG", "ELTEC Elektronik AG" }, - { "EAS", "Evans and Sutherland Computer" }, - { "EBH", "Data Price Informatica" }, - { "EBS", "EBS Euchner Büro- und Schulsysteme GmbH" }, - { "EBT", "HUALONG TECHNOLOGY CO., LTD" }, - { "ECA", "Electro Cam Corp." }, - { "ECC", "ESSential Comm. Corporation" }, - { "ECH", "EchoStar Corporation" }, - { "ECI", "Enciris Technologies" }, - { "ECK", "Eugene Chukhlomin Sole Proprietorship, d.b.a." }, - { "ECL", "Excel Company Ltd" }, - { "ECM", "E-Cmos Tech Corporation" }, - { "ECO", "Echo Speech Corporation" }, - { "ECP", "Elecom Company Ltd" }, - { "ECS", "Elitegroup Computer Systems Company Ltd" }, - { "ECT", "Enciris Technologies" }, - { "EDC", "e.Digital Corporation" }, - { "EDG", "Electronic-Design GmbH" }, - { "EDI", "Edimax Tech. Company Ltd" }, - { "EDM", "EDMI" }, - { "EDT", "Emerging Display Technologies Corp" }, - { "EEE", "ET&T Technology Company Ltd" }, - { "EEH", "EEH Datalink GmbH" }, - { "EEP", "E.E.P.D. GmbH" }, - { "EES", "EE Solutions, Inc." }, - { "EGA", "Elgato Systems LLC" }, - { "EGD", "EIZO GmbH Display Technologies" }, - { "EGL", "Eagle Technology" }, - { "EGN", "Egenera, Inc." }, - { "EGO", "Ergo Electronics" }, - { "EHJ", "Epson Research" }, - { "EHN", "Enhansoft" }, - { "EIC", "Eicon Technology Corporation" }, - { "EIN", "Elegant Invention" }, - { "EKA", "MagTek Inc." }, - { "EKC", "Eastman Kodak Company" }, - { "EKS", "EKSEN YAZILIM" }, - { "ELA", "ELAD srl" }, - { "ELC", "Electro Scientific Ind" }, - { "ELD", "Express Luck, Inc." }, - { "ELE", "Elecom Company Ltd" }, - { "ELG", "Elmeg GmbH Kommunikationstechnik" }, - { "ELI", "Edsun Laboratories" }, - { "ELL", "Electrosonic Ltd" }, - { "ELM", "Elmic Systems Inc" }, - { "ELO", "Elo TouchSystems Inc" }, - { "ELS", "ELSA GmbH" }, - { "ELT", "Element Labs, Inc." }, - { "ELU", "Express Industrial, Ltd." }, - { "ELX", "Elonex PLC" }, - { "EMB", "Embedded computing inc ltd" }, - { "EMC", "eMicro Corporation" }, - { "EMD", "Embrionix Design Inc." }, - { "EME", "EMiNE TECHNOLOGY COMPANY, LTD." }, - { "EMG", "EMG Consultants Inc" }, - { "EMI", "Ex Machina Inc" }, - { "EMK", "Emcore Corporation" }, - { "EMO", "ELMO COMPANY, LIMITED" }, - { "EMU", "Emulex Corporation" }, - { "ENC", "Eizo Nanao Corporation" }, - { "END", "ENIDAN Technologies Ltd" }, - { "ENE", "ENE Technology Inc." }, - { "ENI", "Efficient Networks" }, - { "ENS", "Ensoniq Corporation" }, - { "ENT", "Enterprise Comm. & Computing Inc" }, - { "EON", "Eon Instrumentation, Inc." }, - { "EPC", "Empac" }, - { "EPH", "Epiphan Systems Inc." }, - { "EPI", "Envision Peripherals, Inc" }, - { "EPN", "EPiCON Inc." }, - { "EPS", "KEPS" }, - { "EQP", "Equipe Electronics Ltd." }, - { "EQX", "Equinox Systems Inc" }, - { "ERG", "Ergo System" }, - { "ERI", "Ericsson Mobile Communications AB" }, - { "ERN", "Ericsson, Inc." }, - { "ERP", "Euraplan GmbH" }, - { "ERS", "Eizo Rugged Solutions" }, - { "ERT", "Escort Insturments Corporation" }, - { "ESA", "Elbit Systems of America" }, - { "ESB", "Esterline Belgium BVBA" }, - { "ESC", "Eden Sistemas de Computacao S/A" }, - { "ESD", "Ensemble Designs, Inc" }, - { "ESG", "ELCON Systemtechnik GmbH" }, - { "ESI", "Extended Systems, Inc." }, - { "ESK", "ES&S" }, - { "ESL", "Esterline Technologies" }, - { "ESN", "eSATURNUS" }, - { "ESS", "ESS Technology Inc" }, - { "EST", "Embedded Solution Technology" }, - { "ESY", "E-Systems Inc" }, - { "ETC", "Everton Technology Company Ltd" }, - { "ETD", "ELAN MICROELECTRONICS CORPORATION" }, - { "ETH", "Etherboot Project" }, - { "ETI", "Eclipse Tech Inc" }, - { "ETK", "eTEK Labs Inc." }, - { "ETL", "Evertz Microsystems Ltd." }, - { "ETS", "Electronic Trade Solutions Ltd" }, - { "ETT", "E-Tech Inc" }, - { "EUT", "Ericsson Mobile Networks B.V." }, - { "EVE", "Advanced Micro Peripherals Ltd" }, - { "EVI", "eviateg GmbH" }, - { "EVX", "Everex" }, - { "EXA", "Exabyte" }, - { "EXC", "Excession Audio" }, - { "EXI", "Exide Electronics" }, - { "EXN", "RGB Systems, Inc. dba Extron Electronics" }, - { "EXP", "Data Export Corporation" }, - { "EXR", "Explorer Inc." }, - { "EXT", "Exatech Computadores & Servicos Ltda" }, - { "EXX", "Exxact GmbH" }, - { "EXY", "Exterity Ltd" }, - { "EYE", "eyevis GmbH" }, - { "EYF", "eyefactive Gmbh" }, - { "EZE", "EzE Technologies" }, - { "EZP", "Storm Technology" }, - { "FAN", "Fantalooks Co., Ltd." }, - { "FAR", "Farallon Computing" }, - { "FBI", "Interface Corporation" }, - { "FCB", "Furukawa Electric Company Ltd" }, - { "FCG", "First International Computer Ltd" }, - { "FCS", "Focus Enhancements, Inc." }, - { "FDC", "Future Domain" }, - { "FDD", "Forth Dimension Displays Ltd" }, - { "FDI", "Future Designs, Inc." }, - { "FDT", "Fujitsu Display Technologies Corp." }, - { "FDX", "Findex, Inc." }, - { "FEC", "FURUNO ELECTRIC CO., LTD." }, - { "FEL", "Fellowes & Questec" }, - { "FEN", "Fen Systems Ltd." }, - { "FER", "Ferranti Int'L" }, - { "FFC", "FUJIFILM Corporation" }, - { "FFI", "Fairfield Industries" }, - { "FGD", "Lisa Draexlmaier GmbH" }, - { "FGL", "Fujitsu General Limited." }, - { "FHL", "FHLP" }, - { "FIC", "Formosa Industrial Computing Inc" }, - { "FIL", "Forefront Int'l Ltd" }, - { "FIN", "Finecom Co., Ltd." }, - { "FIR", "Chaplet Systems Inc" }, - { "FIS", "FLY-IT Simulators" }, - { "FIT", "Feature Integration Technology Inc." }, - { "FJC", "Fujitsu Takamisawa Component Limited" }, - { "FJS", "Fujitsu Spain" }, - { "FJT", "F.J. Tieman BV" }, - { "FLE", "ADTI Media, Inc" }, - { "FLI", "Faroudja Laboratories" }, - { "FLY", "Butterfly Communications" }, - { "FMA", "Fast Multimedia AG" }, - { "FMC", "Ford Microelectronics Inc" }, - { "FMI", "Fellowes, Inc." }, - { "FML", "Fujitsu Microelect Ltd" }, - { "FMZ", "Formoza-Altair" }, - { "FNC", "Fanuc LTD" }, - { "FNI", "Funai Electric Co., Ltd." }, - { "FOA", "FOR-A Company Limited" }, - { "FOK", "Fokus Technologies GmbH" }, - { "FOS", "Foss Tecator" }, - { "FOV", "FOVE INC" }, - { "FOX", "HON HAI PRECISON IND.CO.,LTD." }, - { "FPC", "Fingerprint Cards AB" }, - { "FPE", "Fujitsu Peripherals Ltd" }, - { "FPS", "Deltec Corporation" }, - { "FPX", "Cirel Systemes" }, - { "FRC", "Force Computers" }, - { "FRD", "Freedom Scientific BLV" }, - { "FRE", "Forvus Research Inc" }, - { "FRI", "Fibernet Research Inc" }, - { "FRO", "FARO Technologies" }, - { "FRS", "South Mountain Technologies, LTD" }, - { "FSC", "Future Systems Consulting KK" }, - { "FSI", "Fore Systems Inc" }, - { "FST", "Modesto PC Inc" }, - { "FTC", "Futuretouch Corporation" }, - { "FTE", "Frontline Test Equipment Inc." }, - { "FTG", "FTG Data Systems" }, - { "FTI", "FastPoint Technologies, Inc." }, - { "FTL", "FUJITSU TEN LIMITED" }, - { "FTN", "Fountain Technologies Inc" }, - { "FTR", "Mediasonic" }, - { "FTS", "FocalTech Systems Co., Ltd." }, - { "FTW", "MindTribe Product Engineering, Inc." }, - { "FUJ", "Fujitsu Ltd" }, - { "FUN", "sisel muhendislik" }, - { "FUS", "Fujitsu Siemens Computers GmbH" }, - { "FVC", "First Virtual Corporation" }, - { "FVX", "C-C-C Group Plc" }, - { "FWA", "Attero Tech, LLC" }, - { "FWR", "Flat Connections Inc" }, - { "FXX", "Fuji Xerox" }, - { "FZC", "Founder Group Shenzhen Co." }, - { "FZI", "FZI Forschungszentrum Informatik" }, - { "GAC", "GreenArrays, Inc." }, - { "GAG", "Gage Applied Sciences Inc" }, - { "GAL", "Galil Motion Control" }, - { "GAU", "Gaudi Co., Ltd." }, - { "GBT", "GIGA-BYTE TECHNOLOGY CO., LTD." }, - { "GCC", "GCC Technologies Inc" }, - { "GCI", "Gateway Comm. Inc" }, - { "GCS", "Grey Cell Systems Ltd" }, - { "GDC", "General Datacom" }, - { "GDI", "G. Diehl ISDN GmbH" }, - { "GDS", "GDS" }, - { "GDT", "Vortex Computersysteme GmbH" }, - { "GEC", "Gechic Corporation" }, - { "GED", "General Dynamics C4 Systems" }, - { "GEF", "GE Fanuc Embedded Systems" }, - { "GEH", "Abaco Systems, Inc." }, - { "GEM", "Gem Plus" }, - { "GEN", "Genesys ATE Inc" }, - { "GEO", "GEO Sense" }, - { "GER", "GERMANEERS GmbH" }, - { "GES", "GES Singapore Pte Ltd" }, - { "GET", "Getac Technology Corporation" }, - { "GFM", "GFMesstechnik GmbH" }, - { "GFN", "Gefen Inc." }, - { "GGL", "Google Inc." }, - { "GGT", "G2TOUCH KOREA" }, - { "GIC", "General Inst. Corporation" }, - { "GIM", "Guillemont International" }, - { "GIP", "GI Provision Ltd" }, - { "GIS", "AT&T Global Info Solutions" }, - { "GJN", "Grand Junction Networks" }, - { "GLD", "Goldmund - Digital Audio SA" }, - { "GLE", "AD electronics" }, - { "GLM", "Genesys Logic" }, - { "GLS", "Gadget Labs LLC" }, - { "GMK", "GMK Electronic Design GmbH" }, - { "GML", "General Information Systems" }, - { "GMM", "GMM Research Inc" }, - { "GMN", "GEMINI 2000 Ltd" }, - { "GMX", "GMX Inc" }, - { "GND", "Gennum Corporation" }, - { "GNN", "GN Nettest Inc" }, - { "GNZ", "Gunze Ltd" }, - { "GOE", "GOEPEL electronic GmbH" }, - { "GPR", "GoPro, Inc." }, - { "GRA", "Graphica Computer" }, - { "GRE", "GOLD RAIN ENTERPRISES CORP." }, - { "GRH", "Granch Ltd" }, - { "GRM", "Garmin International" }, - { "GRV", "Advanced Gravis" }, - { "GRY", "Robert Gray Company" }, - { "GSB", "NIPPONDENCHI CO,.LTD" }, - { "GSC", "General Standards Corporation" }, - { "GSM", "LG Electronics" }, - { "GSN", "Grandstream Networks, Inc." }, - { "GST", "Graphic SystemTechnology" }, - { "GSY", "Grossenbacher Systeme AG" }, - { "GTC", "Graphtec Corporation" }, - { "GTI", "Goldtouch" }, - { "GTK", "G-Tech Corporation" }, - { "GTM", "Garnet System Company Ltd" }, - { "GTS", "Geotest Marvin Test Systems Inc" }, - { "GTT", "General Touch Technology Co., Ltd." }, - { "GUD", "Guntermann & Drunck GmbH" }, - { "GUZ", "Guzik Technical Enterprises" }, - { "GVC", "GVC Corporation" }, - { "GVL", "Global Village Communication" }, - { "GWI", "GW Instruments" }, - { "GWK", "Gateworks Corporation" }, - { "GWY", "Gateway 2000" }, - { "GZE", "GUNZE Limited" }, - { "HAE", "Haider electronics" }, - { "HAI", "Haivision Systems Inc." }, - { "HAL", "Halberthal" }, - { "HAN", "Hanchang System Corporation" }, - { "HAR", "Harris Corporation" }, - { "HAY", "Hayes Microcomputer Products Inc" }, - { "HCA", "DAT" }, - { "HCE", "Hitachi Consumer Electronics Co., Ltd" }, - { "HCL", "HCL America Inc" }, - { "HCM", "HCL Peripherals" }, - { "HCP", "Hitachi Computer Products Inc" }, - { "HCW", "Hauppauge Computer Works Inc" }, - { "HDC", "HardCom Elektronik & Datateknik" }, - { "HDI", "HD-INFO d.o.o." }, - { "HDV", "Holografika kft." }, - { "HEC", "Hisense Electric Co., Ltd." }, - { "HEL", "Hitachi Micro Systems Europe Ltd" }, - { "HER", "Ascom Business Systems" }, - { "HET", "HETEC Datensysteme GmbH" }, - { "HHC", "HIRAKAWA HEWTECH CORP." }, - { "HHI", "Fraunhofer Heinrich-Hertz-Institute" }, - { "HIB", "Hibino Corporation" }, - { "HIC", "Hitachi Information Technology Co., Ltd." }, - { "HII", "Harman International Industries, Inc" }, - { "HIK", "Hikom Co., Ltd." }, - { "HIL", "Hilevel Technology" }, - { "HIQ", "Kaohsiung Opto Electronics Americas, Inc." }, - { "HIS", "Hope Industrial Systems, Inc." }, - { "HIT", "Hitachi America Ltd" }, - { "HJI", "Harris & Jeffries Inc" }, - { "HKA", "HONKO MFG. CO., LTD." }, - { "HKC", "HKC OVERSEAS LIMITED" }, - { "HKG", "Josef Heim KG" }, - { "HLG", "China Hualu Group Co., Ltd." }, - { "HMC", "Hualon Microelectric Corporation" }, - { "HMK", "hmk Daten-System-Technik BmbH" }, - { "HMX", "HUMAX Co., Ltd." }, - { "HNS", "Hughes Network Systems" }, - { "HOB", "HOB Electronic GmbH" }, - { "HOE", "Hosiden Corporation" }, - { "HOL", "Holoeye Photonics AG" }, - { "HON", "Sonitronix" }, - { "HPA", "Zytor Communications" }, - { "HPC", "Hewlett-Packard Co." }, - { "HPD", "Hewlett Packard" }, - { "HPE", "Hewlett Packard Enterprise" }, - { "HPI", "Headplay, Inc." }, - { "HPK", "HAMAMATSU PHOTONICS K.K." }, - { "HPN", "HP Inc." }, - { "HPQ", "Hewlett-Packard Co." }, - { "HPR", "H.P.R. Electronics GmbH" }, - { "HRC", "Hercules" }, - { "HRE", "Qingdao Haier Electronics Co., Ltd." }, - { "HRI", "Hall Research" }, - { "HRL", "Herolab GmbH" }, - { "HRS", "Harris Semiconductor" }, - { "HRT", "HERCULES" }, - { "HSC", "Hagiwara Sys-Com Company Ltd" }, - { "HSD", "HannStar Display Corp" }, - { "HSM", "AT&T Microelectronics" }, - { "HSP", "HannStar Display Corp" }, - { "HST", "Horsent Technology Co., Ltd." }, - { "HTC", "Hitachi Ltd" }, - { "HTI", "Hampshire Company, Inc." }, - { "HTK", "Holtek Microelectronics Inc" }, - { "HTL", "HTBLuVA Mödling" }, - { "HTR", "Shenzhen ZhuoYi HengTong Computer Technology Limited" }, - { "HTX", "Hitex Systementwicklung GmbH" }, - { "HUB", "GAI-Tronics, A Hubbell Company" }, - { "HUK", "Hoffmann + Krippner GmbH" }, - { "HUM", "IMP Electronics Ltd." }, - { "HVR", "HTC Corportation" }, - { "HWA", "Harris Canada Inc" }, - { "HWC", "DBA Hans Wedemeyer" }, - { "HWD", "Highwater Designs Ltd" }, - { "HWP", "Hewlett Packard" }, - { "HWV", "Huawei Technologies Co., Inc." }, - { "HXM", "Hexium Ltd." }, - { "HYC", "Hypercope Gmbh Aachen" }, - { "HYD", "Hydis Technologies.Co.,LTD" }, - { "HYL", "Shanghai Chai Ming Huang Info&Tech Co, Ltd" }, - { "HYO", "HYC CO., LTD." }, - { "HYP", "Hyphen Ltd" }, - { "HYR", "Hypertec Pty Ltd" }, - { "HYT", "Heng Yu Technology (HK) Limited" }, - { "HYV", "Hynix Semiconductor" }, - { "IAD", "IAdea Corporation" }, - { "IAF", "Institut f r angewandte Funksystemtechnik GmbH" }, - { "IAI", "Integration Associates, Inc." }, - { "IAT", "IAT Germany GmbH" }, - { "IBC", "Integrated Business Systems" }, - { "IBI", "INBINE.CO.LTD" }, - { "IBM", "IBM Brasil" }, - { "IBP", "IBP Instruments GmbH" }, - { "IBR", "IBR GmbH" }, - { "ICA", "ICA Inc" }, - { "ICC", "BICC Data Networks Ltd" }, - { "ICD", "ICD Inc" }, - { "ICE", "IC Ensemble" }, - { "ICI", "Infotek Communication Inc" }, - { "ICM", "Intracom SA" }, - { "ICN", "Sanyo Icon" }, - { "ICO", "Intel Corp" }, - { "ICP", "ICP Electronics, Inc./iEi Technology Corp." }, - { "ICR", "Icron" }, - { "ICS", "Integrated Circuit Systems" }, - { "ICV", "Inside Contactless" }, - { "ICX", "ICCC A/S" }, - { "IDC", "International Datacasting Corporation" }, - { "IDE", "IDE Associates" }, - { "IDK", "IDK Corporation" }, - { "IDN", "Idneo Technologies" }, - { "IDO", "IDEO Product Development" }, - { "IDP", "Integrated Device Technology, Inc." }, - { "IDS", "Interdigital Sistemas de Informacao" }, - { "IDT", "International Display Technology" }, - { "IDX", "IDEXX Labs" }, - { "IEC", "Interlace Engineering Corporation" }, - { "IEE", "IEE" }, - { "IEI", "Interlink Electronics" }, - { "IFS", "In Focus Systems Inc" }, - { "IFT", "Informtech" }, - { "IFX", "Infineon Technologies AG" }, - { "IFZ", "Infinite Z" }, - { "IGC", "Intergate Pty Ltd" }, - { "IGM", "IGM Communi" }, - { "IHE", "InHand Electronics" }, - { "IIC", "ISIC Innoscan Industrial Computers A/S" }, - { "III", "Intelligent Instrumentation" }, - { "IIN", "IINFRA Co., Ltd" }, - { "IIT", "Informatik Information Technologies" }, - { "IKE", "Ikegami Tsushinki Co. Ltd." }, - { "IKS", "Ikos Systems Inc" }, - { "ILC", "Image Logic Corporation" }, - { "ILS", "Innotech Corporation" }, - { "IMA", "Imagraph" }, - { "IMB", "ART s.r.l." }, - { "IMC", "IMC Networks" }, - { "IMD", "ImasDe Canarias S.A." }, - { "IME", "Imagraph" }, - { "IMF", "Immersive Audio Technologies France" }, - { "IMG", "IMAGENICS Co., Ltd." }, - { "IMI", "International Microsystems Inc" }, - { "IMM", "Immersion Corporation" }, - { "IMN", "Impossible Production" }, - { "IMP", "Impinj" }, - { "IMT", "Inmax Technology Corporation" }, - { "INA", "Inventec Corporation" }, - { "INC", "Home Row Inc" }, - { "IND", "ILC" }, - { "INE", "Inventec Electronics (M) Sdn. Bhd." }, - { "INF", "Inframetrics Inc" }, - { "ING", "Integraph Corporation" }, - { "INI", "Initio Corporation" }, - { "INK", "Indtek Co., Ltd." }, - { "INL", "InnoLux Display Corporation" }, - { "INM", "InnoMedia Inc" }, - { "INN", "Innovent Systems, Inc." }, - { "INO", "Innolab Pte Ltd" }, - { "INP", "Interphase Corporation" }, - { "INS", "Ines GmbH" }, - { "INT", "Interphase Corporation" }, - { "INU", "Inovatec S.p.A." }, - { "INV", "Inviso, Inc." }, - { "INX", "Communications Supply Corporation (A division of WESCO)" }, - { "INZ", "Best Buy" }, - { "IOA", "CRE Technology Corporation" }, - { "IOD", "I-O Data Device Inc" }, - { "IOM", "Iomega" }, - { "ION", "Inside Out Networks" }, - { "IOS", "i-O Display System" }, - { "IOT", "I/OTech Inc" }, - { "IPC", "IPC Corporation" }, - { "IPD", "Industrial Products Design, Inc." }, - { "IPI", "Intelligent Platform Management Interface (IPMI) forum (Intel, HP, NEC, Dell)" }, - { "IPM", "IPM Industria Politecnica Meridionale SpA" }, - { "IPN", "Performance Technologies" }, - { "IPP", "IP Power Technologies GmbH" }, - { "IPQ", "IP3 Technology Ltd." }, - { "IPR", "Ithaca Peripherals" }, - { "IPS", "IPS, Inc. (Intellectual Property Solutions, Inc.)" }, - { "IPT", "International Power Technologies" }, - { "IPW", "IPWireless, Inc" }, - { "IQI", "IneoQuest Technologies, Inc" }, - { "IQT", "IMAGEQUEST Co., Ltd" }, - { "IRD", "Irdata" }, - { "ISA", "Symbol Technologies" }, - { "ISC", "Id3 Semiconductors" }, - { "ISG", "Insignia Solutions Inc" }, - { "ISI", "Interface Solutions" }, - { "ISL", "Isolation Systems" }, - { "ISM", "Image Stream Medical" }, - { "ISP", "IntreSource Systems Pte Ltd" }, - { "ISR", "INSIS Co., LTD." }, - { "ISS", "ISS Inc" }, - { "IST", "Intersolve Technologies" }, - { "ISY", "International Integrated Systems,Inc.(IISI)" }, - { "ITA", "Itausa Export North America" }, - { "ITC", "Intercom Inc" }, - { "ITD", "Internet Technology Corporation" }, - { "ITE", "Integrated Tech Express Inc" }, - { "ITI", "VanErum Group" }, - { "ITK", "ITK Telekommunikation AG" }, - { "ITL", "Inter-Tel" }, - { "ITM", "ITM inc." }, - { "ITN", "The NTI Group" }, - { "ITP", "IT-PRO Consulting und Systemhaus GmbH" }, - { "ITR", "Infotronic America, Inc." }, - { "ITS", "IDTECH" }, - { "ITT", "I&T Telecom." }, - { "ITX", "integrated Technology Express Inc" }, - { "IUC", "ICSL" }, - { "IVI", "Intervoice Inc" }, - { "IVM", "Iiyama North America" }, - { "IVR", "Inlife-Handnet Co., Ltd." }, - { "IVS", "Intevac Photonics Inc." }, - { "IWR", "Icuiti Corporation" }, - { "IWX", "Intelliworxx, Inc." }, - { "IXD", "Intertex Data AB" }, - { "IXN", "Shenzhen Inet Mobile Internet Technology Co., LTD" }, - { "JAC", "Astec Inc" }, - { "JAE", "Japan Aviation Electronics Industry, Limited" }, - { "JAS", "Janz Automationssysteme AG" }, - { "JAT", "Jaton Corporation" }, - { "JAZ", "Carrera Computer Inc" }, - { "JCE", "Jace Tech Inc" }, - { "JDI", "Japan Display Inc." }, - { "JDL", "Japan Digital Laboratory Co.,Ltd." }, - { "JEM", "Japan E.M.Solutions Co., Ltd." }, - { "JEN", "N-Vision" }, - { "JET", "JET POWER TECHNOLOGY CO., LTD." }, - { "JFX", "Jones Futurex Inc" }, - { "JGD", "University College" }, - { "JIC", "Jaeik Information & Communication Co., Ltd." }, - { "JKC", "JVC KENWOOD Corporation" }, - { "JMT", "Micro Technical Company Ltd" }, - { "JPC", "JPC Technology Limited" }, - { "JPW", "Wallis Hamilton Industries" }, - { "JQE", "CNet Technical Inc" }, - { "JSD", "JS DigiTech, Inc" }, - { "JSI", "Jupiter Systems, Inc." }, - { "JSK", "SANKEN ELECTRIC CO., LTD" }, - { "JTS", "JS Motorsports" }, - { "JTY", "jetway security micro,inc" }, - { "JUK", "Janich & Klass Computertechnik GmbH" }, - { "JUP", "Jupiter Systems" }, - { "JVC", "JVC" }, - { "JWD", "Video International Inc." }, - { "JWL", "Jewell Instruments, LLC" }, - { "JWS", "JWSpencer & Co." }, - { "JWY", "Jetway Information Co., Ltd" }, - { "KAR", "Karna" }, - { "KBI", "Kidboard Inc" }, - { "KBL", "Kobil Systems GmbH" }, - { "KCD", "Chunichi Denshi Co.,LTD." }, - { "KCL", "Keycorp Ltd" }, - { "KDE", "KDE" }, - { "KDK", "Kodiak Tech" }, - { "KDM", "Korea Data Systems Co., Ltd." }, - { "KDS", "KDS USA" }, - { "KDT", "KDDI Technology Corporation" }, - { "KEC", "Kyushu Electronics Systems Inc" }, - { "KEM", "Kontron Embedded Modules GmbH" }, - { "KES", "Kesa Corporation" }, - { "KEU", "Kontron Europe GmbH" }, - { "KEY", "Key Tech Inc" }, - { "KFC", "SCD Tech" }, - { "KFE", "Komatsu Forest" }, - { "KFX", "Kofax Image Products" }, - { "KGI", "Klipsch Group, Inc" }, - { "KGL", "KEISOKU GIKEN Co.,Ltd." }, - { "KIO", "Kionix, Inc." }, - { "KIS", "KiSS Technology A/S" }, - { "KMC", "Mitsumi Company Ltd" }, - { "KME", "KIMIN Electronics Co., Ltd." }, - { "KML", "Kensington Microware Ltd" }, - { "KMR", "Kramer Electronics Ltd. International" }, - { "KNC", "Konica corporation" }, - { "KNX", "Nutech Marketing PTL" }, - { "KOB", "Kobil Systems GmbH" }, - { "KOD", "Eastman Kodak Company" }, - { "KOE", "KOLTER ELECTRONIC" }, - { "KOL", "Kollmorgen Motion Technologies Group" }, - { "KOM", "Kontron GmbH" }, - { "KOU", "KOUZIRO Co.,Ltd." }, - { "KOW", "KOWA Company,LTD." }, - { "KPC", "King Phoenix Company" }, - { "KPT", "TPK Holding Co., Ltd" }, - { "KRL", "Krell Industries Inc." }, - { "KRM", "Kroma Telecom" }, - { "KRY", "Kroy LLC" }, - { "KSC", "Kinetic Systems Corporation" }, - { "KSG", "KUPA China Shenzhen Micro Technology Co., Ltd. Gold Institute" }, - { "KSL", "Karn Solutions Ltd." }, - { "KSX", "King Tester Corporation" }, - { "KTC", "Kingston Tech Corporation" }, - { "KTD", "Takahata Electronics Co.,Ltd." }, - { "KTE", "K-Tech" }, - { "KTG", "Kayser-Threde GmbH" }, - { "KTI", "Konica Technical Inc" }, - { "KTK", "Key Tronic Corporation" }, - { "KTN", "Katron Tech Inc" }, - { "KTS", "Kyokko Communication System Co., Ltd." }, - { "KUR", "Kurta Corporation" }, - { "KVA", "Kvaser AB" }, - { "KVX", "KeyView" }, - { "KWD", "Kenwood Corporation" }, - { "KYC", "Kyocera Corporation" }, - { "KYE", "KYE Syst Corporation" }, - { "KYK", "Samsung Electronics America Inc" }, - { "KYN", "KEYENCE CORPORATION" }, - { "KZI", "K-Zone International co. Ltd." }, - { "KZN", "K-Zone International" }, - { "LAB", "ACT Labs Ltd" }, - { "LAC", "LaCie" }, - { "LAF", "Microline" }, - { "LAG", "Laguna Systems" }, - { "LAN", "Sodeman Lancom Inc" }, - { "LAS", "LASAT Comm. A/S" }, - { "LAV", "Lava Computer MFG Inc" }, - { "LBO", "Lubosoft" }, - { "LCC", "LCI" }, - { "LCD", "Toshiba Matsushita Display Technology Co., Ltd" }, - { "LCE", "La Commande Electronique" }, - { "LCI", "Lite-On Communication Inc" }, - { "LCM", "Latitude Comm." }, - { "LCN", "LEXICON" }, - { "LCS", "Longshine Electronics Company" }, - { "LCT", "Labcal Technologies" }, - { "LDN", "Laserdyne Technologies" }, - { "LDT", "LogiDataTech Electronic GmbH" }, - { "LEC", "Lectron Company Ltd" }, - { "LED", "Long Engineering Design Inc" }, - { "LEG", "Legerity, Inc" }, - { "LEN", "Lenovo Group Limited" }, - { "LEO", "First International Computer Inc" }, - { "LEX", "Lexical Ltd" }, - { "LGC", "Logic Ltd" }, - { "LGI", "Logitech Inc" }, - { "LGS", "LG Semicom Company Ltd" }, - { "LGX", "Lasergraphics, Inc." }, - { "LHA", "Lars Haagh ApS" }, - { "LHC", "Beihai Century Joint Innovation Technology Co.,Ltd" }, - { "LHE", "Lung Hwa Electronics Company Ltd" }, - { "LHT", "Lighthouse Technologies Limited" }, - { "LIN", "Lenovo Beijing Co. Ltd." }, - { "LIP", "Linked IP GmbH" }, - { "LIT", "Lithics Silicon Technology" }, - { "LJX", "Datalogic Corporation" }, - { "LKM", "Likom Technology Sdn. Bhd." }, - { "LLL", "L-3 Communications" }, - { "LMG", "Lucent Technologies" }, - { "LMI", "Lexmark Int'l Inc" }, - { "LMP", "Leda Media Products" }, - { "LMT", "Laser Master" }, - { "LND", "Land Computer Company Ltd" }, - { "LNK", "Link Tech Inc" }, - { "LNR", "Linear Systems Ltd." }, - { "LNT", "LANETCO International" }, - { "LNV", "Lenovo" }, - { "LNX", "The Linux Foundation" }, - { "LOC", "Locamation B.V." }, - { "LOE", "Loewe Opta GmbH" }, - { "LOG", "Logicode Technology Inc" }, - { "LOL", "Litelogic Operations Ltd" }, - { "LPE", "El-PUSK Co., Ltd." }, - { "LPI", "Design Technology" }, - { "LPL", "LG Philips" }, - { "LSC", "LifeSize Communications" }, - { "LSD", "Intersil Corporation" }, - { "LSI", "Loughborough Sound Images" }, - { "LSJ", "LSI Japan Company Ltd" }, - { "LSL", "Logical Solutions" }, - { "LSP", "Lightspace Technologies" }, - { "LSY", "LSI Systems Inc" }, - { "LTC", "Labtec Inc" }, - { "LTI", "Jongshine Tech Inc" }, - { "LTK", "Lucidity Technology Company Ltd" }, - { "LTN", "Litronic Inc" }, - { "LTS", "LTS Scale LLC" }, - { "LTV", "Leitch Technology International Inc." }, - { "LTW", "Lightware, Inc" }, - { "LUC", "Lucent Technologies" }, - { "LUM", "Lumagen, Inc." }, - { "LUX", "Luxxell Research Inc" }, - { "LVI", "LVI Low Vision International AB" }, - { "LWC", "Labway Corporation" }, - { "LWR", "Lightware Visual Engineering" }, - { "LWW", "Lanier Worldwide" }, - { "LXC", "LXCO Technologies AG" }, - { "LXN", "Luxeon" }, - { "LXS", "ELEA CardWare" }, - { "LZX", "Lightwell Company Ltd" }, - { "MAC", "MAC System Company Ltd" }, - { "MAD", "Xedia Corporation" }, - { "MAE", "Maestro Pty Ltd" }, - { "MAG", "MAG InnoVision" }, - { "MAI", "Mutoh America Inc" }, - { "MAL", "Meridian Audio Ltd" }, - { "MAN", "LGIC" }, - { "MAS", "Mass Inc." }, - { "MAT", "Matsushita Electric Ind. Company Ltd" }, - { "MAX", "Rogen Tech Distribution Inc" }, - { "MAY", "Maynard Electronics" }, - { "MAZ", "MAZeT GmbH" }, - { "MBC", "MBC" }, - { "MBD", "Microbus PLC" }, - { "MBM", "Marshall Electronics" }, - { "MBV", "Moreton Bay" }, - { "MCA", "American Nuclear Systems Inc" }, - { "MCC", "Micro Industries" }, - { "MCD", "McDATA Corporation" }, - { "MCE", "Metz-Werke GmbH & Co KG" }, - { "MCG", "Motorola Computer Group" }, - { "MCI", "Micronics Computers" }, - { "MCJ", "Medicaroid Corporation" }, - { "MCL", "Motorola Communications Israel" }, - { "MCM", "Metricom Inc" }, - { "MCN", "Micron Electronics Inc" }, - { "MCO", "Motion Computing Inc." }, - { "MCP", "Magni Systems Inc" }, - { "MCQ", "Mat's Computers" }, - { "MCR", "Marina Communicaitons" }, - { "MCS", "Micro Computer Systems" }, - { "MCT", "Microtec" }, - { "MCX", "Millson Custom Solutions Inc." }, - { "MDA", "Media4 Inc" }, - { "MDC", "Midori Electronics" }, - { "MDD", "MODIS" }, - { "MDF", "MILDEF AB" }, - { "MDG", "Madge Networks" }, - { "MDI", "Micro Design Inc" }, - { "MDK", "Mediatek Corporation" }, - { "MDO", "Panasonic" }, - { "MDR", "Medar Inc" }, - { "MDS", "Micro Display Systems Inc" }, - { "MDT", "Magus Data Tech" }, - { "MDV", "MET Development Inc" }, - { "MDX", "MicroDatec GmbH" }, - { "MDY", "Microdyne Inc" }, - { "MEC", "Mega System Technologies Inc" }, - { "MED", "Messeltronik Dresden GmbH" }, - { "MEE", "Mitsubishi Electric Engineering Co., Ltd." }, - { "MEG", "Abeam Tech Ltd." }, - { "MEI", "Panasonic Industry Company" }, - { "MEJ", "Mac-Eight Co., LTD." }, - { "MEK", "Mediaedge Corporation" }, - { "MEL", "Mitsubishi Electric Corporation" }, - { "MEN", "MEN Mikroelectronik Nueruberg GmbH" }, - { "MEP", "Meld Technology" }, - { "MEQ", "Matelect Ltd." }, - { "MET", "Metheus Corporation" }, - { "MEU", "MPL AG, Elektronik-Unternehmen" }, - { "MEX", "MSC Vertriebs GmbH" }, - { "MFG", "MicroField Graphics Inc" }, - { "MFI", "Micro Firmware" }, - { "MFR", "MediaFire Corp." }, - { "MGA", "Mega System Technologies, Inc." }, - { "MGC", "Mentor Graphics Corporation" }, - { "MGE", "Schneider Electric S.A." }, - { "MGL", "M-G Technology Ltd" }, - { "MGT", "Megatech R & D Company" }, - { "MHQ", "Moxa Inc." }, - { "MIC", "Micom Communications Inc" }, - { "MID", "miro Displays" }, - { "MII", "Mitec Inc" }, - { "MIL", "Marconi Instruments Ltd" }, - { "MIM", "Mimio – A Newell Rubbermaid Company" }, - { "MIN", "Minicom Digital Signage" }, - { "MIP", "micronpc.com" }, - { "MIR", "Miro Computer Prod." }, - { "MIS", "Modular Industrial Solutions Inc" }, - { "MIT", "MCM Industrial Technology GmbH" }, - { "MIV", "MicroImage Video Systems" }, - { "MJI", "MARANTZ JAPAN, INC." }, - { "MJS", "MJS Designs" }, - { "MKC", "Media Tek Inc." }, - { "MKS", "MK Seiko Co., Ltd." }, - { "MKT", "MICROTEK Inc." }, - { "MKV", "Trtheim Technology" }, - { "MLC", "MILCOTS" }, - { "MLD", "Deep Video Imaging Ltd" }, - { "MLG", "Micrologica AG" }, - { "MLI", "McIntosh Laboratory Inc." }, - { "MLL", "Millogic Ltd." }, - { "MLM", "Millennium Engineering Inc" }, - { "MLN", "Mark Levinson" }, - { "MLP", "Magic Leap" }, - { "MLS", "Milestone EPE" }, - { "MLT", "Wanlida Group Co., Ltd." }, - { "MLX", "Mylex Corporation" }, - { "MMA", "Micromedia AG" }, - { "MMD", "Micromed Biotecnologia Ltd" }, - { "MMF", "Minnesota Mining and Manufacturing" }, - { "MMI", "Multimax" }, - { "MMM", "Electronic Measurements" }, - { "MMN", "MiniMan Inc" }, - { "MMS", "MMS Electronics" }, - { "MMT", "MIMO Monitors" }, - { "MNC", "Mini Micro Methods Ltd" }, - { "MNI", "Marseille, Inc." }, - { "MNL", "Monorail Inc" }, - { "MNP", "Microcom" }, - { "MOC", "Matrix Orbital Corporation" }, - { "MOD", "Modular Technology" }, - { "MOM", "Momentum Data Systems" }, - { "MOS", "Moses Corporation" }, - { "MOT", "Motorola UDS" }, - { "MPC", "M-Pact Inc" }, - { "MPI", "Mediatrix Peripherals Inc" }, - { "MPJ", "Microlab" }, - { "MPL", "Maple Research Inst. Company Ltd" }, - { "MPN", "Mainpine Limited" }, - { "MPS", "mps Software GmbH" }, - { "MPV", "Megapixel Visual Realty" }, - { "MPX", "Micropix Technologies, Ltd." }, - { "MQP", "MultiQ Products AB" }, - { "MRA", "Miranda Technologies Inc" }, - { "MRC", "Marconi Simulation & Ty-Coch Way Training" }, - { "MRD", "MicroDisplay Corporation" }, - { "MRK", "Maruko & Company Ltd" }, - { "MRL", "Miratel" }, - { "MRO", "Medikro Oy" }, - { "MRT", "Merging Technologies" }, - { "MSA", "Micro Systemation AB" }, - { "MSC", "Mouse Systems Corporation" }, - { "MSD", "Datenerfassungs- und Informationssysteme" }, - { "MSF", "M-Systems Flash Disk Pioneers" }, - { "MSG", "MSI GmbH" }, - { "MSH", "Microsoft" }, - { "MSI", "Microstep" }, - { "MSK", "Megasoft Inc" }, - { "MSL", "MicroSlate Inc." }, - { "MSM", "Advanced Digital Systems" }, - { "MSP", "Mistral Solutions [P] Ltd." }, - { "MSR", "MASPRO DENKOH Corp." }, - { "MST", "MS Telematica" }, - { "MSU", "motorola" }, - { "MSV", "Mosgi Corporation" }, - { "MSX", "Micomsoft Co., Ltd." }, - { "MSY", "MicroTouch Systems Inc" }, - { "MTA", "Meta Watch Ltd" }, - { "MTB", "Media Technologies Ltd." }, - { "MTC", "Mars-Tech Corporation" }, - { "MTD", "MindTech Display Co. Ltd" }, - { "MTE", "MediaTec GmbH" }, - { "MTH", "Micro-Tech Hearing Instruments" }, - { "MTI", "MaxCom Technical Inc" }, - { "MTJ", "MicroTechnica Co.,Ltd." }, - { "MTK", "Microtek International Inc." }, - { "MTL", "Mitel Corporation" }, - { "MTM", "Motium" }, - { "MTN", "Mtron Storage Technology Co., Ltd." }, - { "MTR", "Mitron computer Inc" }, - { "MTS", "Multi-Tech Systems" }, - { "MTU", "Mark of the Unicorn Inc" }, - { "MTX", "Matrox" }, - { "MUD", "Multi-Dimension Institute" }, - { "MUK", "Mainpine Limited" }, - { "MVD", "Microvitec PLC" }, - { "MVI", "Media Vision Inc" }, - { "MVM", "SOBO VISION" }, - { "MVN", "Meta Company" }, - { "MVR", "MediCapture, Inc." }, - { "MVS", "Microvision" }, - { "MVX", "COM 1" }, - { "MWI", "Multiwave Innovation Pte Ltd" }, - { "MWR", "mware" }, - { "MWY", "Microway Inc" }, - { "MXD", "MaxData Computer GmbH & Co.KG" }, - { "MXI", "Macronix Inc" }, - { "MXL", "Hitachi Maxell, Ltd." }, - { "MXP", "Maxpeed Corporation" }, - { "MXT", "Maxtech Corporation" }, - { "MXV", "MaxVision Corporation" }, - { "MYA", "Monydata" }, - { "MYR", "Myriad Solutions Ltd" }, - { "MYX", "Micronyx Inc" }, - { "NAC", "Ncast Corporation" }, - { "NAD", "NAD Electronics" }, - { "NAK", "Nakano Engineering Co.,Ltd." }, - { "NAL", "Network Alchemy" }, - { "NAT", "NaturalPoint Inc." }, - { "NAV", "Navigation Corporation" }, - { "NAX", "Naxos Tecnologia" }, - { "NBL", "N*Able Technologies Inc" }, - { "NBS", "National Key Lab. on ISN" }, - { "NBT", "NingBo Bestwinning Technology CO., Ltd" }, - { "NCA", "Nixdorf Company" }, - { "NCC", "NCR Corporation" }, - { "NCE", "Norcent Technology, Inc." }, - { "NCI", "NewCom Inc" }, - { "NCL", "NetComm Ltd" }, - { "NCP", "Najing CEC Panda FPD Technology CO. ltd" }, - { "NCR", "NCR Electronics" }, - { "NCS", "Northgate Computer Systems" }, - { "NCT", "NEC CustomTechnica, Ltd." }, - { "NDC", "National DataComm Corporaiton" }, - { "NDF", "NDF Special Light Products B.V." }, - { "NDI", "National Display Systems" }, - { "NDK", "Naitoh Densei CO., LTD." }, - { "NDL", "Network Designers" }, - { "NDS", "Nokia Data" }, - { "NEC", "NEC Corporation" }, - { "NEO", "NEO TELECOM CO.,LTD." }, - { "NES", "INNES" }, - { "NET", "Mettler Toledo" }, - { "NEU", "NEUROTEC - EMPRESA DE PESQUISA E DESENVOLVIMENTO EM BIOMEDICINA" }, - { "NEX", "Nexgen Mediatech Inc.," }, - { "NFC", "BTC Korea Co., Ltd" }, - { "NFS", "Number Five Software" }, - { "NGC", "Network General" }, - { "NGS", "A D S Exports" }, - { "NHT", "Vinci Labs" }, - { "NIC", "National Instruments Corporation" }, - { "NIS", "Nissei Electric Company" }, - { "NIT", "Network Info Technology" }, - { "NIX", "Seanix Technology Inc" }, - { "NLC", "Next Level Communications" }, - { "NME", "Navico, Inc." }, - { "NMP", "Nokia Mobile Phones" }, - { "NMS", "Natural Micro System" }, - { "NMV", "NEC-Mitsubishi Electric Visual Systems Corporation" }, - { "NMX", "Neomagic" }, - { "NNC", "NNC" }, - { "NOD", "3NOD Digital Technology Co. Ltd." }, - { "NOE", "NordicEye AB" }, - { "NOI", "North Invent A/S" }, - { "NOK", "Nokia Display Products" }, - { "NOR", "Norand Corporation" }, - { "NOT", "Not Limited Inc" }, - { "NPA", "Arvanics" }, - { "NPI", "Network Peripherals Inc" }, - { "NRI", "Noritake Itron Corporation" }, - { "NRL", "U.S. Naval Research Lab" }, - { "NRT", "Beijing Northern Radiantelecom Co." }, - { "NRV", "Taugagreining hf" }, - { "NSA", "NeuroSky, Inc." }, - { "NSC", "National Semiconductor Corporation" }, - { "NSI", "NISSEI ELECTRIC CO.,LTD" }, - { "NSP", "Nspire System Inc." }, - { "NSS", "Newport Systems Solutions" }, - { "NST", "Network Security Technology Co" }, - { "NTC", "NeoTech S.R.L" }, - { "NTI", "New Tech Int'l Company" }, - { "NTK", "NewTek" }, - { "NTL", "National Transcomm. Ltd" }, - { "NTN", "Nuvoton Technology Corporation" }, - { "NTR", "N-trig Innovative Technologies, Inc." }, - { "NTS", "Nits Technology Inc." }, - { "NTT", "NTT Advanced Technology Corporation" }, - { "NTW", "Networth Inc" }, - { "NTX", "Netaccess Inc" }, - { "NUG", "NU Technology, Inc." }, - { "NUI", "NU Inc." }, - { "NVC", "NetVision Corporation" }, - { "NVD", "Nvidia" }, - { "NVI", "NuVision US, Inc." }, - { "NVL", "Novell Inc" }, - { "NVT", "Navatek Engineering Corporation" }, - { "NWC", "NW Computer Engineering" }, - { "NWL", "Newline Interactive Inc." }, - { "NWP", "NovaWeb Technologies Inc" }, - { "NWS", "Newisys, Inc." }, - { "NXC", "NextCom K.K." }, - { "NXG", "Nexgen" }, - { "NXP", "NXP Semiconductors bv." }, - { "NXQ", "Nexiq Technologies, Inc." }, - { "NXS", "Technology Nexus Secure Open Systems AB" }, - { "NXT", "NZXT (PNP same EDID)_" }, - { "NYC", "Nakayo Relecommunications, Inc." }, - { "OAK", "Oak Tech Inc" }, - { "OAS", "Oasys Technology Company" }, - { "OBS", "Optibase Technologies" }, - { "OCD", "Macraigor Systems Inc" }, - { "OCN", "Olfan" }, - { "OCS", "Open Connect Solutions" }, - { "ODM", "ODME Inc." }, - { "ODR", "Odrac" }, - { "OEC", "ORION ELECTRIC CO.,LTD" }, - { "OEI", "Optum Engineering Inc." }, - { "OHW", "M-Labs Limited" }, - { "OIC", "Option Industrial Computers" }, - { "OIM", "Option International" }, - { "OIN", "Option International" }, - { "OKI", "OKI Electric Industrial Company Ltd" }, - { "OLC", "Olicom A/S" }, - { "OLD", "Olidata S.p.A." }, - { "OLI", "Olivetti" }, - { "OLT", "Olitec S.A." }, - { "OLV", "Olitec S.A." }, - { "OLY", "OLYMPUS CORPORATION" }, - { "OMC", "OBJIX Multimedia Corporation" }, - { "OMN", "Omnitel" }, - { "OMR", "Omron Corporation" }, - { "ONE", "Oneac Corporation" }, - { "ONK", "ONKYO Corporation" }, - { "ONL", "OnLive, Inc" }, - { "ONS", "On Systems Inc" }, - { "ONW", "OPEN Networks Ltd" }, - { "ONX", "SOMELEC Z.I. Du Vert Galanta" }, - { "OOS", "OSRAM" }, - { "OPC", "Opcode Inc" }, - { "OPI", "D.N.S. Corporation" }, - { "OPP", "OPPO Digital, Inc." }, - { "OPT", "OPTi Inc" }, - { "OPV", "Optivision Inc" }, - { "OQI", "Oksori Company Ltd" }, - { "ORG", "ORGA Kartensysteme GmbH" }, - { "ORI", "OSR Open Systems Resources, Inc." }, - { "ORN", "ORION ELECTRIC CO., LTD." }, - { "OSA", "OSAKA Micro Computer, Inc." }, - { "OSD", "Optical Systems Design Pty Ltd" }, - { "OSI", "Open Stack, Inc." }, - { "OSP", "OPTI-UPS Corporation" }, - { "OSR", "Oksori Company Ltd" }, - { "OTB", "outsidetheboxstuff.com" }, - { "OTI", "Orchid Technology" }, - { "OTK", "OmniTek" }, - { "OTM", "Optoma Corporation" }, - { "OTT", "OPTO22, Inc." }, - { "OUK", "OUK Company Ltd" }, - { "OVR", "Oculus VR, Inc." }, - { "OWL", "Mediacom Technologies Pte Ltd" }, - { "OXU", "Oxus Research S.A." }, - { "OYO", "Shadow Systems" }, - { "OZC", "OZ Corporation" }, - { "OZO", "Tribe Computer Works Inc" }, - { "PAC", "Pacific Avionics Corporation" }, - { "PAD", "Promotion and Display Technology Ltd." }, - { "PAK", "Many CNC System Co., Ltd." }, - { "PAM", "Peter Antesberger Messtechnik" }, - { "PAN", "The Panda Project" }, - { "PAR", "Parallan Comp Inc" }, - { "PBI", "Pitney Bowes" }, - { "PBL", "Packard Bell Electronics" }, - { "PBN", "Packard Bell NEC" }, - { "PBV", "Pitney Bowes" }, - { "PCA", "Philips BU Add On Card" }, - { "PCB", "OCTAL S.A." }, - { "PCC", "PowerCom Technology Company Ltd" }, - { "PCG", "First Industrial Computer Inc" }, - { "PCI", "Pioneer Computer Inc" }, - { "PCK", "PCBANK21" }, - { "PCL", "pentel.co.,ltd" }, - { "PCM", "PCM Systems Corporation" }, - { "PCO", "Performance Concepts Inc.," }, - { "PCP", "Procomp USA Inc" }, - { "PCS", "TOSHIBA PERSONAL COMPUTER SYSTEM CORPRATION" }, - { "PCT", "PC-Tel Inc" }, - { "PCW", "Pacific CommWare Inc" }, - { "PCX", "PC Xperten" }, - { "PDM", "Psion Dacom Plc." }, - { "PDN", "AT&T Paradyne" }, - { "PDR", "Pure Data Inc" }, - { "PDS", "PD Systems International Ltd" }, - { "PDT", "PDTS - Prozessdatentechnik und Systeme" }, - { "PDV", "Prodrive B.V." }, - { "PEC", "POTRANS Electrical Corp." }, - { "PEG", "Pegatron Corporation" }, - { "PEI", "PEI Electronics Inc" }, - { "PEL", "Primax Electric Ltd" }, - { "PEN", "Interactive Computer Products Inc" }, - { "PEP", "Peppercon AG" }, - { "PER", "Perceptive Signal Technologies" }, - { "PET", "Practical Electronic Tools" }, - { "PFT", "Telia ProSoft AB" }, - { "PGI", "PACSGEAR, Inc." }, - { "PGM", "Paradigm Advanced Research Centre" }, - { "PGP", "propagamma kommunikation" }, - { "PGS", "Princeton Graphic Systems" }, - { "PHC", "Pijnenburg Beheer N.V." }, - { "PHE", "Philips Medical Systems Boeblingen GmbH" }, - { "PHI", "DO NOT USE - PHI" }, - { "PHL", "Philips Consumer Electronics Company" }, - { "PHO", "Photonics Systems Inc." }, - { "PHS", "Philips Communication Systems" }, - { "PHY", "Phylon Communications" }, - { "PIC", "Picturall Ltd." }, - { "PIE", "Pacific Image Electronics Company Ltd" }, - { "PIM", "Prism, LLC" }, - { "PIO", "Pioneer Electronic Corporation" }, - { "PIS", "TECNART CO.,LTD." }, - { "PIX", "Pixie Tech Inc" }, - { "PJA", "Projecta" }, - { "PJD", "Projectiondesign AS" }, - { "PJT", "Pan Jit International Inc." }, - { "PKA", "Acco UK Ltd." }, - { "PLC", "Pro-Log Corporation" }, - { "PLF", "Panasonic Avionics Corporation" }, - { "PLM", "PROLINK Microsystems Corp." }, - { "PLT", "PT Hartono Istana Teknologi" }, - { "PLV", "PLUS Vision Corp." }, - { "PLX", "Parallax Graphics" }, - { "PLY", "Polycom Inc." }, - { "PMC", "PMC Consumer Electronics Ltd" }, - { "PMD", "TDK USA Corporation" }, - { "PMM", "Point Multimedia System" }, - { "PMS", "Pabian Embedded Systems" }, - { "PMT", "Promate Electronic Co., Ltd." }, - { "PMX", "Photomatrix" }, - { "PNG", "Microsoft" }, - { "PNL", "Panelview, Inc." }, - { "PNP", "Microsoft" }, - { "PNR", "Planar Systems, Inc." }, - { "PNS", "PanaScope" }, - { "PNT", "HOYA Corporation PENTAX Lifecare Division" }, - { "PNX", "Phoenix Technologies, Ltd." }, - { "POL", "PolyComp (PTY) Ltd." }, - { "PON", "Perpetual Technologies, LLC" }, - { "POR", "Portalis LC" }, - { "POS", "Positivo Tecnologia S.A." }, - { "POT", "Parrot" }, - { "PPC", "Phoenixtec Power Company Ltd" }, - { "PPD", "MEPhI" }, - { "PPI", "Practical Peripherals" }, - { "PPM", "Clinton Electronics Corp." }, - { "PPP", "Purup Prepress AS" }, - { "PPR", "PicPro" }, - { "PPX", "Perceptive Pixel Inc." }, - { "PQI", "Pixel Qi" }, - { "PRA", "PRO/AUTOMATION" }, - { "PRC", "PerComm" }, - { "PRD", "Praim S.R.L." }, - { "PRF", "Schneider Electric Japan Holdings, Ltd." }, - { "PRG", "The Phoenix Research Group Inc" }, - { "PRI", "Priva Hortimation BV" }, - { "PRM", "Prometheus" }, - { "PRO", "Proteon" }, - { "PRP", "UEFI Forum" }, - { "PRS", "Leutron Vision" }, - { "PRT", "Parade Technologies, Ltd." }, - { "PRX", "Proxima Corporation" }, - { "PSA", "Advanced Signal Processing Technologies" }, - { "PSC", "Philips Semiconductors" }, - { "PSD", "Peus-Systems GmbH" }, - { "PSE", "Practical Solutions Pte., Ltd." }, - { "PSI", "PSI-Perceptive Solutions Inc" }, - { "PSL", "Perle Systems Limited" }, - { "PSM", "Prosum" }, - { "PST", "Global Data SA" }, - { "PSY", "Prodea Systems Inc." }, - { "PTA", "PAR Tech Inc." }, - { "PTC", "PS Technology Corporation" }, - { "PTG", "Cipher Systems Inc" }, - { "PTH", "Pathlight Technology Inc" }, - { "PTI", "Promise Technology Inc" }, - { "PTL", "Pantel Inc" }, - { "PTS", "Plain Tree Systems Inc" }, - { "PTW", "DO NOT USE - PTW" }, - { "PUL", "Pulse-Eight Ltd" }, - { "PVC", "DO NOT USE - PVC" }, - { "PVG", "Proview Global Co., Ltd" }, - { "PVI", "Prime view international Co., Ltd" }, - { "PVM", "Penta Studiotechnik GmbH" }, - { "PVN", "Pixel Vision" }, - { "PVP", "Klos Technologies, Inc." }, - { "PVR", "Pimax Tech. CO., LTD" }, - { "PXC", "Phoenix Contact" }, - { "PXE", "PIXELA CORPORATION" }, - { "PXL", "The Moving Pixel Company" }, - { "PXM", "Proxim Inc" }, - { "PXN", "PixelNext Inc" }, - { "QCC", "QuakeCom Company Ltd" }, - { "QCH", "Metronics Inc" }, - { "QCI", "Quanta Computer Inc" }, - { "QCK", "Quick Corporation" }, - { "QCL", "Quadrant Components Inc" }, - { "QCP", "Qualcomm Inc" }, - { "QDI", "Quantum Data Incorporated" }, - { "QDL", "QD Laser, Inc." }, - { "QDM", "Quadram" }, - { "QDS", "Quanta Display Inc." }, - { "QFF", "Padix Co., Inc." }, - { "QFI", "Quickflex, Inc" }, - { "QLC", "Q-Logic" }, - { "QQQ", "Chuomusen Co., Ltd." }, - { "QSC", "QSC, LLC" }, - { "QSI", "Quantum Solutions, Inc." }, - { "QTD", "Quantum 3D Inc" }, - { "QTH", "Questech Ltd" }, - { "QTI", "Quicknet Technologies Inc" }, - { "QTM", "Quantum" }, - { "QTR", "Qtronix Corporation" }, - { "QUA", "Quatographic AG" }, - { "QUE", "Questra Consulting" }, - { "QVU", "Quartics" }, - { "RAC", "Racore Computer Products Inc" }, - { "RAD", "Radisys Corporation" }, - { "RAI", "Rockwell Automation/Intecolor" }, - { "RAN", "Rancho Tech Inc" }, - { "RAR", "Raritan, Inc." }, - { "RAS", "RAScom Inc" }, - { "RAT", "Rent-A-Tech" }, - { "RAY", "Raylar Design, Inc." }, - { "RCE", "Parc d'Activite des Bellevues" }, - { "RCH", "Reach Technology Inc" }, - { "RCI", "RC International" }, - { "RCN", "Radio Consult SRL" }, - { "RCO", "Rockwell Collins" }, - { "RDI", "Rainbow Displays, Inc." }, - { "RDM", "Tremon Enterprises Company Ltd" }, - { "RDN", "RADIODATA GmbH" }, - { "RDS", "Radius Inc" }, - { "REA", "Real D" }, - { "REC", "ReCom" }, - { "RED", "Research Electronics Development Inc" }, - { "REF", "Reflectivity, Inc." }, - { "REH", "Rehan Electronics Ltd." }, - { "REL", "Reliance Electric Ind Corporation" }, - { "REM", "SCI Systems Inc." }, - { "REN", "Renesas Technology Corp." }, - { "RES", "ResMed Pty Ltd" }, - { "RET", "Resonance Technology, Inc." }, - { "REV", "Revolution Display, Inc." }, - { "REX", "RATOC Systems, Inc." }, - { "RFI", "RAFI GmbH & Co. KG" }, - { "RFX", "Redfox Technologies Inc." }, - { "RGB", "RGB Spectrum" }, - { "RGL", "Robertson Geologging Ltd" }, - { "RHD", "RightHand Technologies" }, - { "RHM", "Rohm Company Ltd" }, - { "RHT", "Red Hat, Inc." }, - { "RIC", "RICOH COMPANY, LTD." }, - { "RII", "Racal Interlan Inc" }, - { "RIO", "Rios Systems Company Ltd" }, - { "RIT", "Ritech Inc" }, - { "RIV", "Rivulet Communications" }, - { "RJA", "Roland Corporation" }, - { "RJS", "Advanced Engineering" }, - { "RKC", "Reakin Technolohy Corporation" }, - { "RLD", "MEPCO" }, - { "RLN", "RadioLAN Inc" }, - { "RMC", "Raritan Computer, Inc" }, - { "RMP", "Research Machines" }, - { "RMS", "Shenzhen Ramos Digital Technology Co., Ltd" }, - { "RMT", "Roper Mobile" }, - { "RNB", "Rainbow Technologies" }, - { "ROB", "Robust Electronics GmbH" }, - { "ROH", "Rohm Co., Ltd." }, - { "ROK", "Rockwell International" }, - { "ROP", "Roper International Ltd" }, - { "ROS", "Rohde & Schwarz" }, - { "RPI", "RoomPro Technologies" }, - { "RPT", "R.P.T.Intergroups" }, - { "RRI", "Radicom Research Inc" }, - { "RSC", "PhotoTelesis" }, - { "RSH", "ADC-Centre" }, - { "RSI", "Rampage Systems Inc" }, - { "RSN", "Radiospire Networks, Inc." }, - { "RSQ", "R Squared" }, - { "RSR", "Zhong Shan City Richsound Electronic Industrial Ltd." }, - { "RSS", "Rockwell Semiconductor Systems" }, - { "RSV", "Ross Video Ltd" }, - { "RSX", "Rapid Tech Corporation" }, - { "RTC", "Relia Technologies" }, - { "RTI", "Rancho Tech Inc" }, - { "RTK", "DO NOT USE - RTK" }, - { "RTL", "Realtek Semiconductor Company Ltd" }, - { "RTS", "Raintree Systems" }, - { "RUN", "RUNCO International" }, - { "RUP", "Ups Manufactoring s.r.l." }, - { "RVC", "RSI Systems Inc" }, - { "RVI", "Realvision Inc" }, - { "RVL", "Reveal Computer Prod" }, - { "RWC", "Red Wing Corporation" }, - { "RXT", "Tectona SoftSolutions (P) Ltd.," }, - { "RZR", "Razer Taiwan Co. Ltd." }, - { "RZS", "Rozsnyó, s.r.o." }, - { "SAA", "Sanritz Automation Co.,Ltd." }, - { "SAE", "Saab Aerotech" }, - { "SAG", "Sedlbauer" }, - { "SAI", "Sage Inc" }, - { "SAK", "Saitek Ltd" }, - { "SAM", "Samsung Electric Company" }, - { "SAN", "Sanyo Electric Co.,Ltd." }, - { "SAS", "Stores Automated Systems Inc" }, - { "SAT", "Shuttle Tech" }, - { "SBC", "Shanghai Bell Telephone Equip Mfg Co" }, - { "SBD", "Softbed - Consulting & Development Ltd" }, - { "SBI", "SMART Technologies Inc." }, - { "SBS", "SBS-or Industrial Computers GmbH" }, - { "SBT", "Senseboard Technologies AB" }, - { "SCB", "SeeCubic B.V." }, - { "SCC", "SORD Computer Corporation" }, - { "SCD", "Sanyo Electric Company Ltd" }, - { "SCE", "Sun Corporation" }, - { "SCH", "Schlumberger Cards" }, - { "SCI", "System Craft" }, - { "SCL", "Sigmacom Co., Ltd." }, - { "SCM", "SCM Microsystems Inc" }, - { "SCN", "Scanport, Inc." }, - { "SCO", "SORCUS Computer GmbH" }, - { "SCP", "Scriptel Corporation" }, - { "SCR", "Systran Corporation" }, - { "SCS", "Nanomach Anstalt" }, - { "SCT", "Smart Card Technology" }, - { "SCX", "Socionext Inc." }, - { "SDA", "SAT (Societe Anonyme)" }, - { "SDD", "Intrada-SDD Ltd" }, - { "SDE", "Sherwood Digital Electronics Corporation" }, - { "SDF", "SODIFF E&T CO., Ltd." }, - { "SDH", "Communications Specialies, Inc." }, - { "SDI", "Samtron Displays Inc" }, - { "SDK", "SAIT-Devlonics" }, - { "SDR", "SDR Systems" }, - { "SDS", "SunRiver Data System" }, - { "SDT", "Siemens AG" }, - { "SDX", "SDX Business Systems Ltd" }, - { "SEA", "Seanix Technology Inc." }, - { "SEB", "system elektronik GmbH" }, - { "SEC", "Seiko Epson Corporation" }, - { "SEE", "SeeColor Corporation" }, - { "SEG", "DO NOT USE - SEG" }, - { "SEI", "Seitz & Associates Inc" }, - { "SEL", "Way2Call Communications" }, - { "SEM", "Samsung Electronics Company Ltd" }, - { "SEN", "Sencore" }, - { "SEO", "SEOS Ltd" }, - { "SEP", "SEP Eletronica Ltda." }, - { "SER", "Sony Ericsson Mobile Communications Inc." }, - { "SES", "Session Control LLC" }, - { "SET", "SendTek Corporation" }, - { "SFM", "TORNADO Company" }, - { "SFT", "Mikroforum Ring 3" }, - { "SGC", "Spectragraphics Corporation" }, - { "SGD", "Sigma Designs, Inc." }, - { "SGE", "Kansai Electric Company Ltd" }, - { "SGI", "Scan Group Ltd" }, - { "SGL", "Super Gate Technology Company Ltd" }, - { "SGM", "SAGEM" }, - { "SGO", "Logos Design A/S" }, - { "SGT", "Stargate Technology" }, - { "SGW", "Shanghai Guowei Science and Technology Co., Ltd." }, - { "SGX", "Silicon Graphics Inc" }, - { "SGZ", "Systec Computer GmbH" }, - { "SHC", "ShibaSoku Co., Ltd." }, - { "SHG", "Soft & Hardware development Goldammer GmbH" }, - { "SHI", "Jiangsu Shinco Electronic Group Co., Ltd" }, - { "SHP", "Sharp Corporation" }, - { "SHR", "Digital Discovery" }, - { "SHT", "Shin Ho Tech" }, - { "SIA", "SIEMENS AG" }, - { "SIB", "Sanyo Electric Company Ltd" }, - { "SIC", "Sysmate Corporation" }, - { "SID", "Seiko Instruments Information Devices Inc" }, - { "SIE", "Siemens" }, - { "SIG", "Sigma Designs Inc" }, - { "SII", "Silicon Image, Inc." }, - { "SIL", "Silicon Laboratories, Inc" }, - { "SIM", "S3 Inc" }, - { "SIN", "Singular Technology Co., Ltd." }, - { "SIR", "Sirius Technologies Pty Ltd" }, - { "SIS", "Silicon Integrated Systems Corporation" }, - { "SIT", "Sitintel" }, - { "SIU", "Seiko Instruments USA Inc" }, - { "SIX", "Zuniq Data Corporation" }, - { "SJE", "Sejin Electron Inc" }, - { "SKD", "Schneider & Koch" }, - { "SKI", "LLC SKTB “SKIT”" }, - { "SKM", "Guangzhou Teclast Information Technology Limited" }, - { "SKT", "Samsung Electro-Mechanics Company Ltd" }, - { "SKW", "Skyworth" }, - { "SKY", "SKYDATA S.P.A." }, - { "SLA", "Systeme Lauer GmbH&Co KG" }, - { "SLB", "Shlumberger Ltd" }, - { "SLC", "Syslogic Datentechnik AG" }, - { "SLF", "StarLeaf" }, - { "SLH", "Silicon Library Inc." }, - { "SLI", "Symbios Logic Inc" }, - { "SLK", "Silitek Corporation" }, - { "SLM", "Solomon Technology Corporation" }, - { "SLR", "Schlumberger Technology Corporate" }, - { "SLS", "Schnick-Schnack-Systems GmbH" }, - { "SLT", "Salt Internatioinal Corp." }, - { "SLX", "Specialix" }, - { "SMA", "SMART Modular Technologies" }, - { "SMB", "Schlumberger" }, - { "SMC", "Standard Microsystems Corporation" }, - { "SME", "Sysmate Company" }, - { "SMI", "SpaceLabs Medical Inc" }, - { "SMK", "SMK CORPORATION" }, - { "SML", "Sumitomo Metal Industries, Ltd." }, - { "SMM", "Shark Multimedia Inc" }, - { "SMO", "STMicroelectronics" }, - { "SMP", "Simple Computing" }, - { "SMR", "B.& V. s.r.l." }, - { "SMS", "Silicom Multimedia Systems Inc" }, - { "SMT", "Silcom Manufacturing Tech Inc" }, - { "SNC", "Sentronic International Corp." }, - { "SNI", "Siemens Microdesign GmbH" }, - { "SNK", "S&K Electronics" }, - { "SNN", "SUNNY ELEKTRONIK" }, - { "SNO", "SINOSUN TECHNOLOGY CO., LTD" }, - { "SNP", "Siemens Nixdorf Info Systems" }, - { "SNS", "Cirtech (UK) Ltd" }, - { "SNT", "SuperNet Inc" }, - { "SNV", "SONOVE GmbH" }, - { "SNW", "Snell & Wilcox" }, - { "SNX", "Sonix Comm. Ltd" }, - { "SNY", "Sony" }, - { "SOC", "Santec Corporation" }, - { "SOI", "Silicon Optix Corporation" }, - { "SOL", "Solitron Technologies Inc" }, - { "SON", "Sony" }, - { "SOR", "Sorcus Computer GmbH" }, - { "SOT", "Sotec Company Ltd" }, - { "SOY", "SOYO Group, Inc" }, - { "SPC", "SpinCore Technologies, Inc" }, - { "SPE", "SPEA Software AG" }, - { "SPH", "G&W Instruments GmbH" }, - { "SPI", "SPACE-I Co., Ltd." }, - { "SPK", "SpeakerCraft" }, - { "SPL", "Smart Silicon Systems Pty Ltd" }, - { "SPN", "Sapience Corporation" }, - { "SPR", "pmns GmbH" }, - { "SPS", "Synopsys Inc" }, - { "SPT", "Sceptre Tech Inc" }, - { "SPU", "SIM2 Multimedia S.P.A." }, - { "SPX", "Simplex Time Recorder Co." }, - { "SQT", "Sequent Computer Systems Inc" }, - { "SRC", "Integrated Tech Express Inc" }, - { "SRD", "Setred" }, - { "SRF", "Surf Communication Solutions Ltd" }, - { "SRG", "Intuitive Surgical, Inc." }, - { "SRS", "SR-Systems e.K." }, - { "SRT", "SeeReal Technologies GmbH" }, - { "SSC", "Sierra Semiconductor Inc" }, - { "SSD", "FlightSafety International" }, - { "SSE", "Samsung Electronic Co." }, - { "SSI", "S-S Technology Inc" }, - { "SSJ", "Sankyo Seiki Mfg.co., Ltd" }, - { "SSL", "Shenzhen South-Top Computer Co., Ltd." }, - { "SSP", "Spectrum Signal Proecessing Inc" }, - { "SSS", "S3 Inc" }, - { "SST", "SystemSoft Corporation" }, - { "STA", "ST Electronics Systems Assembly Pte Ltd" }, - { "STB", "STB Systems Inc" }, - { "STC", "STAC Electronics" }, - { "STD", "STD Computer Inc" }, - { "STE", "SII Ido-Tsushin Inc" }, - { "STF", "Starflight Electronics" }, - { "STG", "StereoGraphics Corp." }, - { "STH", "Semtech Corporation" }, - { "STI", "Smart Tech Inc" }, - { "STK", "SANTAK CORP." }, - { "STL", "SigmaTel Inc" }, - { "STM", "SGS Thomson Microelectronics" }, - { "STN", "Samsung Electronics America" }, - { "STO", "Stollmann E+V GmbH" }, - { "STP", "StreamPlay Ltd" }, - { "STQ", "Synthetel Corporation" }, - { "STR", "Starlight Networks Inc" }, - { "STS", "SITECSYSTEM CO., LTD." }, - { "STT", "Star Paging Telecom Tech (Shenzhen) Co. Ltd." }, - { "STU", "Sentelic Corporation" }, - { "STW", "Starwin Inc." }, - { "STX", "ST-Ericsson" }, - { "STY", "SDS Technologies" }, - { "SUB", "Subspace Comm. Inc" }, - { "SUM", "Summagraphics Corporation" }, - { "SUN", "Sun Electronics Corporation" }, - { "SUP", "Supra Corporation" }, - { "SUR", "Surenam Computer Corporation" }, - { "SVA", "SGEG" }, - { "SVC", "Intellix Corp." }, - { "SVD", "SVD Computer" }, - { "SVI", "Sun Microsystems" }, - { "SVR", "Sensics, Inc." }, - { "SVS", "SVSI" }, - { "SVT", "SEVIT Co., Ltd." }, - { "SWC", "Software Café" }, - { "SWI", "Sierra Wireless Inc." }, - { "SWL", "Sharedware Ltd" }, - { "SWO", "Guangzhou Shirui Electronics Co., Ltd." }, - { "SWS", "Static" }, - { "SWT", "Software Technologies Group,Inc." }, - { "SXB", "Syntax-Brillian" }, - { "SXD", "Silex technology, Inc." }, - { "SXG", "SELEX GALILEO" }, - { "SXI", "Silex Inside" }, - { "SXL", "SolutionInside" }, - { "SXT", "SHARP TAKAYA ELECTRONIC INDUSTRY CO.,LTD." }, - { "SYC", "Sysmic" }, - { "SYE", "SY Electronics Ltd" }, - { "SYK", "Stryker Communications" }, - { "SYL", "Sylvania Computer Products" }, - { "SYM", "Symicron Computer Communications Ltd." }, - { "SYN", "Synaptics Inc" }, - { "SYP", "SYPRO Co Ltd" }, - { "SYS", "Sysgration Ltd" }, - { "SYT", "Seyeon Tech Company Ltd" }, - { "SYV", "SYVAX Inc" }, - { "SYX", "Prime Systems, Inc." }, - { "SZM", "Shenzhen MTC Co., Ltd" }, - { "TAA", "Tandberg" }, - { "TAB", "Todos Data System AB" }, - { "TAG", "Teles AG" }, - { "TAI", "Toshiba America Info Systems Inc" }, - { "TAM", "Tamura Seisakusyo Ltd" }, - { "TAS", "Taskit Rechnertechnik GmbH" }, - { "TAT", "Teleliaison Inc" }, - { "TAV", "Thales Avionics" }, - { "TAX", "Taxan (Europe) Ltd" }, - { "TBB", "Triple S Engineering Inc" }, - { "TBC", "Turbo Communication, Inc" }, - { "TBS", "Turtle Beach System" }, - { "TCC", "Tandon Corporation" }, - { "TCD", "Taicom Data Systems Co., Ltd." }, - { "TCE", "Century Corporation" }, - { "TCF", "Televic Conference" }, - { "TCH", "Interaction Systems, Inc" }, - { "TCI", "Tulip Computers Int'l B.V." }, - { "TCJ", "TEAC America Inc" }, - { "TCL", "Technical Concepts Ltd" }, - { "TCM", "3Com Corporation" }, - { "TCN", "Tecnetics (PTY) Ltd" }, - { "TCO", "Thomas-Conrad Corporation" }, - { "TCR", "Thomson Consumer Electronics" }, - { "TCS", "Tatung Company of America Inc" }, - { "TCT", "Telecom Technology Centre Co. Ltd." }, - { "TCX", "FREEMARS Heavy Industries" }, - { "TDC", "Teradici" }, - { "TDD", "Tandberg Data Display AS" }, - { "TDG", "Six15 Technologies" }, - { "TDM", "Tandem Computer Europe Inc" }, - { "TDP", "3D Perception" }, - { "TDS", "Tri-Data Systems Inc" }, - { "TDT", "TDT" }, - { "TDV", "TDVision Systems, Inc." }, - { "TDY", "Tandy Electronics" }, - { "TEA", "TEAC System Corporation" }, - { "TEC", "Tecmar Inc" }, - { "TEK", "Tektronix Inc" }, - { "TEL", "Promotion and Display Technology Ltd." }, - { "TEN", "Tencent" }, - { "TER", "TerraTec Electronic GmbH" }, - { "TET", "TETRADYNE CO., LTD." }, - { "TEV", "Televés, S.A." }, - { "TEZ", "Tech Source Inc." }, - { "TGC", "Toshiba Global Commerce Solutions, Inc." }, - { "TGI", "TriGem Computer Inc" }, - { "TGM", "TriGem Computer,Inc." }, - { "TGS", "Torus Systems Ltd" }, - { "TGV", "Grass Valley Germany GmbH" }, - { "TGW", "TECHNOGYM S.p.A." }, - { "THN", "Thundercom Holdings Sdn. Bhd." }, - { "TIC", "Trigem KinfoComm" }, - { "TIL", "Technical Illusions Inc." }, - { "TIP", "TIPTEL AG" }, - { "TIV", "OOO Technoinvest" }, - { "TIX", "Tixi.Com GmbH" }, - { "TKC", "Taiko Electric Works.LTD" }, - { "TKG", "Tek Gear" }, - { "TKN", "Teknor Microsystem Inc" }, - { "TKO", "TouchKo, Inc." }, - { "TKS", "TimeKeeping Systems, Inc." }, - { "TLA", "Ferrari Electronic GmbH" }, - { "TLD", "Telindus" }, - { "TLE", "Zhejiang Tianle Digital Electric Co., Ltd." }, - { "TLF", "Teleforce.,co,ltd" }, - { "TLI", "TOSHIBA TELI CORPORATION" }, - { "TLK", "Telelink AG" }, - { "TLL", "Thinklogical" }, - { "TLN", "Techlogix Networx" }, - { "TLS", "Teleste Educational OY" }, - { "TLT", "Dai Telecom S.p.A." }, - { "TLV", "S3 Inc" }, - { "TLX", "Telxon Corporation" }, - { "TMC", "Techmedia Computer Systems Corporation" }, - { "TME", "AT&T Microelectronics" }, - { "TMI", "Texas Microsystem" }, - { "TMM", "Time Management, Inc." }, - { "TMO", "Terumo Corporation" }, - { "TMR", "Taicom International Inc" }, - { "TMS", "Trident Microsystems Ltd" }, - { "TMT", "T-Metrics Inc." }, - { "TMX", "Thermotrex Corporation" }, - { "TNC", "TNC Industrial Company Ltd" }, - { "TNJ", "DO NOT USE - TNJ" }, - { "TNM", "TECNIMAGEN SA" }, - { "TNY", "Tennyson Tech Pty Ltd" }, - { "TOE", "TOEI Electronics Co., Ltd." }, - { "TOG", "The OPEN Group" }, - { "TOL", "TCL Corporation" }, - { "TOM", "Ceton Corporation" }, - { "TON", "TONNA" }, - { "TOP", "Orion Communications Co., Ltd." }, - { "TOS", "Dynabook Inc." }, - { "TOU", "Touchstone Technology" }, - { "TPC", "Touch Panel Systems Corporation" }, - { "TPD", "Times (Shanghai) Computer Co., Ltd." }, - { "TPE", "Technology Power Enterprises Inc" }, - { "TPJ", "Junnila" }, - { "TPK", "TOPRE CORPORATION" }, - { "TPR", "Topro Technology Inc" }, - { "TPS", "Teleprocessing Systeme GmbH" }, - { "TPT", "Thruput Ltd" }, - { "TPV", "Top Victory Electronics ( Fujian ) Company Ltd" }, - { "TPZ", "Ypoaz Systems Inc" }, - { "TRA", "TriTech Microelectronics International" }, - { "TRB", "Triumph Board a.s." }, - { "TRC", "Trioc AB" }, - { "TRD", "Trident Microsystem Inc" }, - { "TRE", "Tremetrics" }, - { "TRI", "Tricord Systems" }, - { "TRL", "Royal Information" }, - { "TRM", "Tekram Technology Company Ltd" }, - { "TRN", "Datacommunicatie Tron B.V." }, - { "TRP", "TRAPEZE GROUP" }, - { "TRS", "Torus Systems Ltd" }, - { "TRT", "Tritec Electronic AG" }, - { "TRU", "Aashima Technology B.V." }, - { "TRV", "Trivisio Prototyping GmbH" }, - { "TRX", "Trex Enterprises" }, - { "TSB", "Toshiba America Info Systems Inc" }, - { "TSC", "Sanyo Electric Company Ltd" }, - { "TSD", "TechniSat Digital GmbH" }, - { "TSE", "Tottori Sanyo Electric" }, - { "TSF", "Racal-Airtech Software Forge Ltd" }, - { "TSG", "The Software Group Ltd" }, - { "TSH", "ELAN MICROELECTRONICS CORPORATION" }, - { "TSI", "TeleVideo Systems" }, - { "TSL", "Tottori SANYO Electric Co., Ltd." }, - { "TSP", "U.S. Navy" }, - { "TST", "Transtream Inc" }, - { "TSV", "TRANSVIDEO" }, - { "TSW", "VRSHOW Technology Limited" }, - { "TSY", "TouchSystems" }, - { "TTA", "Topson Technology Co., Ltd." }, - { "TTB", "National Semiconductor Japan Ltd" }, - { "TTC", "Telecommunications Techniques Corporation" }, - { "TTE", "TTE, Inc." }, - { "TTI", "Trenton Terminals Inc" }, - { "TTK", "Totoku Electric Company Ltd" }, - { "TTL", "2-Tel B.V" }, - { "TTP", "Toshiba Corporation" }, - { "TTS", "TechnoTrend Systemtechnik GmbH" }, - { "TTX", "Taitex Corporation" }, - { "TTY", "TRIDELITY Display Solutions GmbH" }, - { "TUA", "T+A elektroakustik GmbH" }, - { "TUT", "Tut Systems" }, - { "TVD", "Tecnovision" }, - { "TVI", "Truevision" }, - { "TVL", "Total Vision LTD" }, - { "TVM", "Taiwan Video & Monitor Corporation" }, - { "TVO", "TV One Ltd" }, - { "TVR", "TV Interactive Corporation" }, - { "TVS", "TVS Electronics Limited" }, - { "TVV", "TV1 GmbH" }, - { "TWA", "Tidewater Association" }, - { "TWE", "Kontron Electronik" }, - { "TWH", "Twinhead International Corporation" }, - { "TWI", "Easytel oy" }, - { "TWK", "TOWITOKO electronics GmbH" }, - { "TWX", "TEKWorx Limited" }, - { "TXL", "Trixel Ltd" }, - { "TXN", "Texas Insturments" }, - { "TXT", "Textron Defense System" }, - { "TYN", "Tyan Computer Corporation" }, - { "UAS", "Ultima Associates Pte Ltd" }, - { "UBI", "Ungermann-Bass Inc" }, - { "UBL", "Ubinetics Ltd." }, - { "UBU", "Canonical Ltd." }, - { "UDN", "Uniden Corporation" }, - { "UEC", "Ultima Electronics Corporation" }, - { "UEG", "Elitegroup Computer Systems Company Ltd" }, - { "UEI", "Universal Electronics Inc" }, - { "UET", "Universal Empowering Technologies" }, - { "UFG", "UNIGRAF-USA" }, - { "UFO", "UFO Systems Inc" }, - { "UHB", "XOCECO" }, - { "UIC", "Uniform Industrial Corporation" }, - { "UJR", "Ueda Japan Radio Co., Ltd." }, - { "ULT", "Ultra Network Tech" }, - { "UMC", "United Microelectr Corporation" }, - { "UMG", "Umezawa Giken Co.,Ltd" }, - { "UMM", "Universal Multimedia" }, - { "UMT", "UltiMachine" }, - { "UNA", "Unisys DSD" }, - { "UNB", "Unisys Corporation" }, - { "UNC", "Unisys Corporation" }, - { "UND", "Unisys Corporation" }, - { "UNE", "Unisys Corporation" }, - { "UNF", "Unisys Corporation" }, - { "UNI", "Uniform Industry Corp." }, - { "UNM", "Unisys Corporation" }, - { "UNO", "Unisys Corporation" }, - { "UNP", "Unitop" }, - { "UNS", "Unisys Corporation" }, - { "UNT", "Unisys Corporation" }, - { "UNY", "Unicate" }, - { "UPP", "UPPI" }, - { "UPS", "Systems Enhancement" }, - { "URD", "Video Computer S.p.A." }, - { "USA", "Utimaco Safeware AG" }, - { "USD", "U.S. Digital Corporation" }, - { "USE", "U. S. Electronics Inc." }, - { "USI", "Universal Scientific Industrial Co., Ltd." }, - { "USR", "U.S. Robotics Inc" }, - { "UTC", "Unicompute Technology Co., Ltd." }, - { "UTD", "Up to Date Tech" }, - { "UWC", "Uniwill Computer Corp." }, - { "VAD", "Vaddio, LLC" }, - { "VAI", "VAIO Corporation" }, - { "VAL", "Valence Computing Corporation" }, - { "VAR", "Varian Australia Pty Ltd" }, - { "VAT", "VADATECH INC" }, - { "VBR", "VBrick Systems Inc." }, - { "VBT", "Valley Board Ltda" }, - { "VCC", "Virtual Computer Corporation" }, - { "VCI", "VistaCom Inc" }, - { "VCJ", "Victor Company of Japan, Limited" }, - { "VCM", "Vector Magnetics, LLC" }, - { "VCX", "VCONEX" }, - { "VDA", "Victor Data Systems" }, - { "VDC", "VDC Display Systems" }, - { "VDM", "Vadem" }, - { "VDO", "Video & Display Oriented Corporation" }, - { "VDS", "Vidisys GmbH & Company" }, - { "VDT", "Viditec, Inc." }, - { "VEC", "Vector Informatik GmbH" }, - { "VEK", "Vektrex" }, - { "VES", "Vestel Elektronik Sanayi ve Ticaret A. S." }, - { "VFI", "VeriFone Inc" }, - { "VHI", "Macrocad Development Inc." }, - { "VIA", "VIA Tech Inc" }, - { "VIB", "Tatung UK Ltd" }, - { "VIC", "Victron B.V." }, - { "VID", "Ingram Macrotron Germany" }, - { "VIK", "Viking Connectors" }, - { "VIM", "Via Mons Ltd." }, - { "VIN", "Vine Micros Ltd" }, - { "VIR", "Visual Interface, Inc" }, - { "VIS", "Visioneer" }, - { "VIT", "Visitech AS" }, - { "VIZ", "VIZIO, Inc" }, - { "VLB", "ValleyBoard Ltda." }, - { "VLC", "VersaLogic Corporation" }, - { "VLK", "Vislink International Ltd" }, - { "VLM", "LENOVO BEIJING CO. LTD." }, - { "VLT", "VideoLan Technologies" }, - { "VLV", "Valve Corporation" }, - { "VMI", "Vermont Microsystems" }, - { "VML", "Vine Micros Limited" }, - { "VMW", "VMware Inc.," }, - { "VNC", "Vinca Corporation" }, - { "VOB", "MaxData Computer AG" }, - { "VPI", "Video Products Inc" }, - { "VPR", "Best Buy" }, - { "VPX", "VPixx Technologies Inc." }, - { "VQ@", "Vision Quest" }, - { "VRC", "Virtual Resources Corporation" }, - { "VRG", "VRgineers, Inc." }, - { "VRM", "VRmagic Holding AG" }, - { "VRS", "VRstudios, Inc." }, - { "VRT", "Varjo Technologies" }, - { "VSC", "ViewSonic Corporation" }, - { "VSD", "3M" }, - { "VSI", "VideoServer" }, - { "VSN", "Ingram Macrotron" }, - { "VSP", "Vision Systems GmbH" }, - { "VSR", "V-Star Electronics Inc." }, - { "VTB", "Videotechnik Breithaupt" }, - { "VTC", "VTel Corporation" }, - { "VTG", "Voice Technologies Group Inc" }, - { "VTI", "VLSI Tech Inc" }, - { "VTK", "Viewteck Co., Ltd." }, - { "VTL", "Vivid Technology Pte Ltd" }, - { "VTM", "Miltope Corporation" }, - { "VTN", "VIDEOTRON CORP." }, - { "VTS", "VTech Computers Ltd" }, - { "VTV", "VATIV Technologies" }, - { "VTX", "Vestax Corporation" }, - { "VUT", "Vutrix (UK) Ltd" }, - { "VWB", "Vweb Corp." }, - { "WAC", "Wacom Tech" }, - { "WAL", "Wave Access" }, - { "WAN", "DO NOT USE - WAN" }, - { "WAV", "Wavephore" }, - { "WBN", "MicroSoftWare" }, - { "WBS", "WB Systemtechnik GmbH" }, - { "WCI", "Wisecom Inc" }, - { "WCS", "Woodwind Communications Systems Inc" }, - { "WDC", "Western Digital" }, - { "WDE", "Westinghouse Digital Electronics" }, - { "WEB", "WebGear Inc" }, - { "WEC", "Winbond Electronics Corporation" }, - { "WEL", "W-DEV" }, - { "WEY", "WEY Design AG" }, - { "WHI", "Whistle Communications" }, - { "WII", "Innoware Inc" }, - { "WIL", "WIPRO Information Technology Ltd" }, - { "WIN", "Wintop Technology Inc" }, - { "WIP", "Wipro Infotech" }, - { "WKH", "Uni-Take Int'l Inc." }, - { "WLD", "Wildfire Communications Inc" }, - { "WLF", "WOLF Advanced Technology" }, - { "WML", "Wolfson Microelectronics Ltd" }, - { "WMO", "Westermo Teleindustri AB" }, - { "WMT", "Winmate Communication Inc" }, - { "WNI", "WillNet Inc." }, - { "WNV", "Winnov L.P." }, - { "WNX", "Diebold Nixdorf Systems GmbH" }, - { "WPA", "Matsushita Communication Industrial Co., Ltd." }, - { "WPI", "Wearnes Peripherals International (Pte) Ltd" }, - { "WRC", "WiNRADiO Communications" }, - { "WSC", "CIS Technology Inc" }, - { "WSP", "Wireless And Smart Products Inc." }, - { "WST", "Wistron Corporation" }, - { "WTC", "ACC Microelectronics" }, - { "WTI", "WorkStation Tech" }, - { "WTK", "Wearnes Thakral Pte" }, - { "WTS", "Restek Electric Company Ltd" }, - { "WVM", "Wave Systems Corporation" }, - { "WVV", "WolfVision GmbH" }, - { "WWP", "Wipotec Wiege- und Positioniersysteme GmbH" }, - { "WWV", "World Wide Video, Inc." }, - { "WXT", "Woxter Technology Co. Ltd" }, - { "WYR", "WyreStorm Technologies LLC" }, - { "WYS", "Wyse Technology" }, - { "WYT", "Wooyoung Image & Information Co.,Ltd." }, - { "XAC", "XAC Automation Corp" }, - { "XAD", "Alpha Data" }, - { "XDM", "XDM Ltd." }, - { "XER", "DO NOT USE - XER" }, - { "XES", "Extreme Engineering Solutions, Inc." }, - { "XFG", "Jan Strapko - FOTO" }, - { "XFO", "EXFO Electro Optical Engineering" }, - { "XIN", "Xinex Networks Inc" }, - { "XIO", "Xiotech Corporation" }, - { "XIR", "Xirocm Inc" }, - { "XIT", "Xitel Pty ltd" }, - { "XLX", "Xilinx, Inc." }, - { "XMM", "C3PO S.L." }, - { "XNT", "XN Technologies, Inc." }, - { "XOC", "DO NOT USE - XOC" }, - { "XQU", "SHANGHAI SVA-DAV ELECTRONICS CO., LTD" }, - { "XRC", "Xircom Inc" }, - { "XRO", "XORO ELECTRONICS (CHENGDU) LIMITED" }, - { "XSN", "Xscreen AS" }, - { "XST", "XS Technologies Inc" }, - { "XSY", "XSYS" }, - { "XTD", "Icuiti Corporation" }, - { "XTE", "X2E GmbH" }, - { "XTL", "Crystal Computer" }, - { "XTN", "X-10 (USA) Inc" }, - { "XYC", "Xycotec Computer GmbH" }, - { "XYE", "Shenzhen Zhuona Technology Co., Ltd." }, - { "YED", "Y-E Data Inc" }, - { "YHQ", "Yokogawa Electric Corporation" }, - { "YHW", "Exacom SA" }, - { "YMH", "Yamaha Corporation" }, - { "YOW", "American Biometric Company" }, - { "ZAN", "Zandar Technologies plc" }, - { "ZAX", "Zefiro Acoustics" }, - { "ZAZ", "ZeeVee, Inc." }, - { "ZBR", "Zebra Technologies International, LLC" }, - { "ZBX", "Zebax Technologies" }, - { "ZCT", "ZeitControl cardsystems GmbH" }, - { "ZDS", "Zenith Data Systems" }, - { "ZEN", "ZENIC Inc." }, - { "ZGT", "Zenith Data Systems" }, - { "ZIC", "Nationz Technologies Inc." }, - { "ZMC", "HangZhou ZMCHIVIN" }, - { "ZMT", "Zalman Tech Co., Ltd." }, - { "ZMZ", "Z Microsystems" }, - { "ZNI", "Zetinet Inc" }, - { "ZNX", "Znyx Adv. Systems" }, - { "ZOW", "Zowie Intertainment, Inc" }, - { "ZRN", "Zoran Corporation" }, - { "ZSE", "Zenith Data Systems" }, - { "ZTC", "ZyDAS Technology Corporation" }, - { "ZTE", "ZTE Corporation" }, - { "ZTI", "Zoom Telephonics Inc" }, - { "ZTM", "ZT Group Int'l Inc." }, - { "ZTT", "Z3 Technology" }, - { "ZWE", "Shenzhen Zowee Technology Co., LTD" }, - { "ZYD", "Zydacron Inc" }, - { "ZYP", "Zypcom Inc" }, - { "ZYT", "Zytex Computers" }, - { "ZYX", "Zyxel" }, - { "ZZZ", "Boca Research Inc" }, -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/edid/qedidvendortable.py b/src/platformsupport/edid/qedidvendortable.py deleted file mode 100755 index e1c57506..00000000 --- a/src/platformsupport/edid/qedidvendortable.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2017 Pier Luigi Fiorini -# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import urllib.request - -# The original source for this data used to be -# 'https://git.fedorahosted.org/cgit/hwdata.git/plain/pnp.ids' -# which is discontinued. For now there seems to be a fork at: -url = 'https://github.com/vcrhonek/hwdata/raw/master/pnp.ids' - -copyright = """ -// Copyright (C) 2017 Pier Luigi Fiorini -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -""" - -notice = """/* - * This lookup table was generated from {} - * - * Do not change this file directly, instead edit the - * qtbase/util/edid/qedidvendortable.py script and regenerate this file. - */""".format(url) - -header = """ -#ifndef QEDIDVENDORTABLE_P_H -#define QEDIDVENDORTABLE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -struct VendorTable { - const char id[4]; - const char name[%d]; -}; - -static const VendorTable q_edidVendorTable[] = {""" - -footer = """}; - -QT_END_NAMESPACE - -#endif // QEDIDVENDORTABLE_P_H""" - -vendors = {} - -max_vendor_length = 0 - -response = urllib.request.urlopen(url) -data = response.read().decode('utf-8') -for line in data.split('\n'): - l = line.split() - if line.startswith('#'): - continue - elif len(l) == 0: - continue - else: - pnp_id = l[0].upper() - vendors[pnp_id] = ' '.join(l[1:]) - if len(vendors[pnp_id]) > max_vendor_length: - max_vendor_length = len(vendors[pnp_id]) - -print(copyright) -print(notice) -print(header % (max_vendor_length + 1)) -for pnp_id in sorted(vendors.keys()): - print(' { "%s", "%s" },' % (pnp_id, vendors[pnp_id])) -print(footer) diff --git a/src/platformsupport/kmsconvenience/CMakeLists.txt b/src/platformsupport/kmsconvenience/CMakeLists.txt deleted file mode 100644 index 5883cdd7..00000000 --- a/src/platformsupport/kmsconvenience/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_module(AuroraKmsSupport - DESCRIPTION - "KMS shared code" - SOURCES - aurorakmsdevice.cpp aurorakmsdevice_p.h - PRIVATE_HEADERS - aurorakmsdevice_p.h - DEFINES - QT_NO_CAST_FROM_ASCII - QT_NO_FOREACH - LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::GuiPrivate - PkgConfig::Libdrm - NO_CMAKE - NO_PKGCONFIG - STATIC -) - -liri_extend_target(AuroraKmsSupport CONDITION FEATURE_aurora_drm_atomic - DEFINES - EGLFS_ENABLE_DRM_ATOMIC -) - -liri_finalize_module(AuroraKmsSupport) diff --git a/src/platformsupport/kmsconvenience/aurorakmsdevice.cpp b/src/platformsupport/kmsconvenience/aurorakmsdevice.cpp deleted file mode 100644 index 487eaf6d..00000000 --- a/src/platformsupport/kmsconvenience/aurorakmsdevice.cpp +++ /dev/null @@ -1,1209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Copyright (C) 2015 Pier Luigi Fiorini -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include - -#include - -#include "aurorakmsdevice_p.h" - -#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) - -Q_LOGGING_CATEGORY(qLcKmsDebug, "aurora.eglfs.kms") - -namespace Aurora { - -namespace PlatformSupport { - -enum OutputConfiguration { - OutputConfigOff, - OutputConfigPreferred, - OutputConfigCurrent, - OutputConfigSkip, - OutputConfigMode, - OutputConfigModeline -}; - -int KmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector) -{ - int candidate = -1; - - for (int i = 0; i < connector->count_encoders; i++) { - drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoders[i]); - if (!encoder) { - qWarning("Failed to get encoder"); - continue; - } - - quint32 encoderId = encoder->encoder_id; - quint32 crtcId = encoder->crtc_id; - quint32 possibleCrtcs = encoder->possible_crtcs; - drmModeFreeEncoder(encoder); - - for (int j = 0; j < resources->count_crtcs; j++) { - bool isPossible = possibleCrtcs & (1 << j); - bool isAvailable = !(m_crtc_allocator & (1 << j)); - // Preserve the existing CRTC -> encoder -> connector routing if - // any. It makes the initialization faster, and may be better - // since we have a very dumb picking algorithm. - bool isBestChoice = (!connector->encoder_id || - (connector->encoder_id == encoderId && - resources->crtcs[j] == crtcId)); - - if (isPossible && isAvailable && isBestChoice) { - return j; - } else if (isPossible && isAvailable) { - candidate = j; - } - } - } - - return candidate; -} - -static const char * const connector_type_names[] = { // must match DRM_MODE_CONNECTOR_* - "None", - "VGA", - "DVI", - "DVI", - "DVI", - "Composite", - "TV", - "LVDS", - "CTV", - "DIN", - "DP", - "HDMI", - "HDMI", - "TV", - "eDP", - "Virtual", - "DSI" -}; - -static QByteArray nameForConnector(const drmModeConnectorPtr connector) -{ - QByteArray connectorName("UNKNOWN"); - - if (connector->connector_type < ARRAY_LENGTH(connector_type_names)) - connectorName = connector_type_names[connector->connector_type]; - - connectorName += QByteArray::number(connector->connector_type_id); - - return connectorName; -} - -static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode) -{ - char hsync[16]; - char vsync[16]; - float fclock; - - mode->type = DRM_MODE_TYPE_USERDEF; - mode->hskew = 0; - mode->vscan = 0; - mode->vrefresh = 0; - mode->flags = 0; - - if (sscanf(text.constData(), "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s", - &fclock, - &mode->hdisplay, - &mode->hsync_start, - &mode->hsync_end, - &mode->htotal, - &mode->vdisplay, - &mode->vsync_start, - &mode->vsync_end, - &mode->vtotal, hsync, vsync) != 11) - return false; - - mode->clock = fclock * 1000; - - if (strcmp(hsync, "+hsync") == 0) - mode->flags |= DRM_MODE_FLAG_PHSYNC; - else if (strcmp(hsync, "-hsync") == 0) - mode->flags |= DRM_MODE_FLAG_NHSYNC; - else - return false; - - if (strcmp(vsync, "+vsync") == 0) - mode->flags |= DRM_MODE_FLAG_PVSYNC; - else if (strcmp(vsync, "-vsync") == 0) - mode->flags |= DRM_MODE_FLAG_NVSYNC; - else - return false; - - return true; -} - -static inline void assignPlane(KmsOutput *output, KmsPlane *plane) -{ - if (output->eglfs_plane) - output->eglfs_plane->activeCrtcId = 0; - - plane->activeCrtcId = output->crtc_id; - output->eglfs_plane = plane; -} - -QPlatformScreen *KmsDevice::createScreenForConnector(drmModeResPtr resources, - drmModeConnectorPtr connector, - ScreenInfo *vinfo) -{ - Q_ASSERT(vinfo); - const QByteArray connectorName = nameForConnector(connector); - - const int crtc = crtcForConnector(resources, connector); - if (crtc < 0) { - qWarning() << "No usable crtc/encoder pair for connector" << connectorName; - return nullptr; - } - - OutputConfiguration configuration; - QSize configurationSize; - int configurationRefresh = 0; - drmModeModeInfo configurationModeline; - - auto userConfig = m_screenConfig->outputSettings(); - QVariantMap userConnectorConfig = userConfig.value(QString::fromUtf8(connectorName)); - // default to the preferred mode unless overridden in the config - const QByteArray mode = userConnectorConfig.value(QStringLiteral("mode"), QStringLiteral("preferred")) - .toByteArray().toLower(); - if (mode == "off") { - configuration = OutputConfigOff; - } else if (mode == "preferred") { - configuration = OutputConfigPreferred; - } else if (mode == "current") { - configuration = OutputConfigCurrent; - } else if (mode == "skip") { - configuration = OutputConfigSkip; - } else if (sscanf(mode.constData(), "%dx%d@%d", &configurationSize.rwidth(), &configurationSize.rheight(), - &configurationRefresh) == 3) - { - configuration = OutputConfigMode; - } else if (sscanf(mode.constData(), "%dx%d", &configurationSize.rwidth(), &configurationSize.rheight()) == 2) { - configuration = OutputConfigMode; - } else if (parseModeline(mode, &configurationModeline)) { - configuration = OutputConfigModeline; - } else { - qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData()); - configuration = OutputConfigPreferred; - } - - *vinfo = ScreenInfo(); - vinfo->virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); - if (userConnectorConfig.contains(QStringLiteral("virtualPos"))) { - const QByteArray vpos = userConnectorConfig.value(QStringLiteral("virtualPos")).toByteArray(); - const QByteArrayList vposComp = vpos.split(','); - if (vposComp.count() == 2) - vinfo->virtualPos = QPoint(vposComp[0].trimmed().toInt(), vposComp[1].trimmed().toInt()); - } - if (userConnectorConfig.value(QStringLiteral("primary")).toBool()) - vinfo->isPrimary = true; - - const uint32_t crtc_id = resources->crtcs[crtc]; - - if (configuration == OutputConfigOff) { - qCDebug(qLcKmsDebug) << "Turning off output" << connectorName; - drmModeSetCrtc(m_dri_fd, crtc_id, 0, 0, 0, 0, 0, nullptr); - return nullptr; - } - - // Skip disconnected output - if (configuration == OutputConfigPreferred && connector->connection == DRM_MODE_DISCONNECTED) { - qCDebug(qLcKmsDebug) << "Skipping disconnected output" << connectorName; - return nullptr; - } - - if (configuration == OutputConfigSkip) { - qCDebug(qLcKmsDebug) << "Skipping output" << connectorName; - return nullptr; - } - - // Get the current mode on the current crtc - drmModeModeInfo crtc_mode; - memset(&crtc_mode, 0, sizeof crtc_mode); - if (drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoder_id)) { - drmModeCrtcPtr crtc = drmModeGetCrtc(m_dri_fd, encoder->crtc_id); - drmModeFreeEncoder(encoder); - - if (!crtc) - return nullptr; - - if (crtc->mode_valid) - crtc_mode = crtc->mode; - - drmModeFreeCrtc(crtc); - } - - QList modes; - modes.reserve(connector->count_modes); - qCDebug(qLcKmsDebug) << connectorName << "mode count:" << connector->count_modes - << "crtc index:" << crtc << "crtc id:" << crtc_id; - for (int i = 0; i < connector->count_modes; i++) { - const drmModeModeInfo &mode = connector->modes[i]; - qCDebug(qLcKmsDebug) << "mode" << i << mode.hdisplay << "x" << mode.vdisplay - << '@' << mode.vrefresh << "hz"; - modes << connector->modes[i]; - } - - int preferred = -1; - int current = -1; - int configured = -1; - int best = -1; - int autoSelected = -1; - - for (int i = modes.size() - 1; i >= 0; i--) { - const drmModeModeInfo &m = modes.at(i); - - if (configuration == OutputConfigMode - && m.hdisplay == configurationSize.width() - && m.vdisplay == configurationSize.height() - && (!configurationRefresh || m.vrefresh == uint32_t(configurationRefresh))) - { - configured = i; - } - - if (!memcmp(&crtc_mode, &m, sizeof m)) - current = i; - - if (m.type & DRM_MODE_TYPE_PREFERRED) - preferred = i; - - best = i; - } - - if (configuration == OutputConfigModeline) { - modes << configurationModeline; - configured = modes.size() - 1; - } - - if (current < 0 && crtc_mode.clock != 0) { - modes << crtc_mode; - current = mode.size() - 1; - } - - if (configuration == OutputConfigCurrent) - configured = current; - - int selected_mode = -1; - - if (configured >= 0) - selected_mode = configured; - else if (preferred >= 0) - selected_mode = preferred; - else if (current >= 0) - selected_mode = current; - else if (best >= 0) - selected_mode = best; - - // Pick a mode that is at least 1920x1080 - { - const int minimalArea = 1920 * 1080; - - for (int i = modes.size() - 1; i >= 0; i--) { - int width = modes[i].hdisplay; - int height = modes[i].vdisplay; - - if (width * height >= minimalArea) { - autoSelected = i; - break; - } - } - } - - // Make sure we select a mode that is at least 1920x1080 - if (autoSelected >= 0) { - int width = modes[selected_mode].hdisplay; - int height = modes[selected_mode].vdisplay; - int refresh = modes[selected_mode].vrefresh; - - int autoWidth = modes[autoSelected].hdisplay; - int autoHeight = modes[autoSelected].vdisplay; - - if (autoWidth * autoHeight > width * height) { - qCDebug(qLcKmsDebug) << "Selected mode was" << selected_mode << ":" << width << "x" << height - << '@' << refresh << "hz for output" << connectorName; - selected_mode = autoSelected; - } - } - - if (Q_UNLIKELY(selected_mode < 0)) { - qCWarning(qLcKmsDebug) << "No modes available for output" << connectorName; - return nullptr; - } else { - int width = modes[selected_mode].hdisplay; - int height = modes[selected_mode].vdisplay; - int refresh = modes[selected_mode].vrefresh; - qCDebug(qLcKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height - << '@' << refresh << "hz for output" << connectorName; - } - - // physical size from connector < config values < env vars - int pwidth = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH"); - if (!pwidth) - pwidth = qEnvironmentVariableIntValue("QT_QPA_PHYSICAL_WIDTH"); - int pheight = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT"); - if (!pheight) - pheight = qEnvironmentVariableIntValue("QT_QPA_PHYSICAL_HEIGHT"); - QSizeF physSize(pwidth, pheight); - if (physSize.isEmpty()) { - physSize = QSize(userConnectorConfig.value(QStringLiteral("physicalWidth")).toInt(), - userConnectorConfig.value(QStringLiteral("physicalHeight")).toInt()); - if (physSize.isEmpty()) { - physSize.setWidth(connector->mmWidth); - physSize.setHeight(connector->mmHeight); - } - } - qCDebug(qLcKmsDebug) << "Physical size is" << physSize << "mm" << "for output" << connectorName; - - const QByteArray formatStr = userConnectorConfig.value(QStringLiteral("format"), QString()) - .toByteArray().toLower(); - uint32_t drmFormat; - bool drmFormatExplicit = true; - if (formatStr.isEmpty()) { - drmFormat = DRM_FORMAT_XRGB8888; - drmFormatExplicit = false; - } else if (formatStr == "xrgb8888") { - drmFormat = DRM_FORMAT_XRGB8888; - } else if (formatStr == "xbgr8888") { - drmFormat = DRM_FORMAT_XBGR8888; - } else if (formatStr == "argb8888") { - drmFormat = DRM_FORMAT_ARGB8888; - } else if (formatStr == "abgr8888") { - drmFormat = DRM_FORMAT_ABGR8888; - } else if (formatStr == "rgb565") { - drmFormat = DRM_FORMAT_RGB565; - } else if (formatStr == "bgr565") { - drmFormat = DRM_FORMAT_BGR565; - } else if (formatStr == "xrgb2101010") { - drmFormat = DRM_FORMAT_XRGB2101010; - } else if (formatStr == "xbgr2101010") { - drmFormat = DRM_FORMAT_XBGR2101010; - } else if (formatStr == "argb2101010") { - drmFormat = DRM_FORMAT_ARGB2101010; - } else if (formatStr == "abgr2101010") { - drmFormat = DRM_FORMAT_ABGR2101010; - } else { - qWarning("Invalid pixel format \"%s\" for output %s", formatStr.constData(), connectorName.constData()); - drmFormat = DRM_FORMAT_XRGB8888; - drmFormatExplicit = false; - } - qCDebug(qLcKmsDebug) << "Format is" << Qt::hex << drmFormat << Qt::dec << "requested_by_user =" << drmFormatExplicit - << "for output" << connectorName; - - const QString cloneSource = userConnectorConfig.value(QStringLiteral("clones")).toString(); - if (!cloneSource.isEmpty()) - qCDebug(qLcKmsDebug) << "Output" << connectorName << " clones output " << cloneSource; - - QSize framebufferSize; - bool framebufferSizeSet = false; - const QByteArray fbsize = userConnectorConfig.value(QStringLiteral("size")).toByteArray().toLower(); - if (!fbsize.isEmpty()) { - if (sscanf(fbsize.constData(), "%dx%d", &framebufferSize.rwidth(), &framebufferSize.rheight()) == 2) { -#ifdef EGLFS_ENABLE_DRM_ATOMIC - if (hasAtomicSupport()) - framebufferSizeSet = true; -#endif - if (!framebufferSizeSet) - qWarning("Setting framebuffer size is only available with DRM atomic API"); - } else { - qWarning("Invalid framebuffer size '%s'", fbsize.constData()); - } - } - if (!framebufferSizeSet) { - framebufferSize.setWidth(modes[selected_mode].hdisplay); - framebufferSize.setHeight(modes[selected_mode].vdisplay); - } - - qCDebug(qLcKmsDebug) << "Output" << connectorName << "framebuffer size is " << framebufferSize; - - KmsOutput output; - output.name = QString::fromUtf8(connectorName); - output.connector_id = connector->connector_id; - output.crtc_index = crtc; - output.crtc_id = crtc_id; - output.physical_size = physSize; - output.preferred_mode = preferred >= 0 ? preferred : selected_mode; - output.mode = selected_mode; - output.mode_set = false; - output.saved_crtc = drmModeGetCrtc(m_dri_fd, crtc_id); - output.modes = modes; - output.subpixel = connector->subpixel; - output.dpms_prop = connectorProperty(connector, QByteArrayLiteral("DPMS")); - output.edid_blob = connectorPropertyBlob(connector, QByteArrayLiteral("EDID")); - output.wants_forced_plane = false; - output.forced_plane_id = 0; - output.forced_plane_set = false; - output.drm_format = drmFormat; - output.drm_format_requested_by_user = drmFormatExplicit; - output.clone_source = cloneSource; - output.size = framebufferSize; - -#ifdef EGLFS_ENABLE_DRM_ATOMIC - if (drmModeCreatePropertyBlob(m_dri_fd, &modes[selected_mode], sizeof(drmModeModeInfo), - &output.mode_blob_id) != 0) { - qCDebug(qLcKmsDebug) << "Failed to create mode blob for mode" << selected_mode; - } - - parseConnectorProperties(output.connector_id, &output); - parseCrtcProperties(output.crtc_id, &output); -#endif - - QString planeListStr; - for (KmsPlane &plane : m_planes) { - if (plane.possibleCrtcs & (1 << output.crtc_index)) { - output.available_planes.append(plane); - planeListStr.append(QString::number(plane.id)); - planeListStr.append(QLatin1Char(' ')); - - // Choose the first primary plane that is not already assigned to - // another screen's associated crtc. - if (!output.eglfs_plane && plane.type == KmsPlane::PrimaryPlane && !plane.activeCrtcId) - assignPlane(&output, &plane); - } - } - qCDebug(qLcKmsDebug, "Output %s can use %d planes: %s", - connectorName.constData(), output.available_planes.count(), qPrintable(planeListStr)); - - // This is for the EGLDevice/EGLStream backend. On some of those devices one - // may want to target a pre-configured plane. It is probably useless for - // eglfs_kms and others. Do not confuse with generic plane support (available_planes). - bool ok; - int idx = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_PLANE_INDEX", &ok); - if (ok) { - drmModePlaneRes *planeResources = drmModeGetPlaneResources(m_dri_fd); - if (planeResources) { - if (idx >= 0 && idx < int(planeResources->count_planes)) { - drmModePlane *plane = drmModeGetPlane(m_dri_fd, planeResources->planes[idx]); - if (plane) { - output.wants_forced_plane = true; - output.forced_plane_id = plane->plane_id; - qCDebug(qLcKmsDebug, "Forcing plane index %d, plane id %u (belongs to crtc id %u)", - idx, plane->plane_id, plane->crtc_id); - - for (KmsPlane &kmsplane : m_planes) { - if (kmsplane.id == output.forced_plane_id) { - assignPlane(&output, &kmsplane); - break; - } - } - - drmModeFreePlane(plane); - } - } else { - qWarning("Invalid plane index %d, must be between 0 and %u", idx, planeResources->count_planes - 1); - } - } - } - - // A more useful version: allows specifying "crtc_id,plane_id:crtc_id,plane_id:..." - // in order to allow overriding the plane used for a given crtc. - if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_KMS_PLANES_FOR_CRTCS")) { - const QString val = qEnvironmentVariable("QT_QPA_EGLFS_KMS_PLANES_FOR_CRTCS"); - qCDebug(qLcKmsDebug, "crtc_id:plane_id override list: %s", qPrintable(val)); - const QStringList crtcPlanePairs = val.split(QLatin1Char(':')); - for (const QString &crtcPlanePair : crtcPlanePairs) { - const QStringList values = crtcPlanePair.split(QLatin1Char(',')); - if (values.count() == 2 && uint(values[0].toInt()) == output.crtc_id) { - uint planeId = values[1].toInt(); - for (KmsPlane &kmsplane : m_planes) { - if (kmsplane.id == planeId) { - assignPlane(&output, &kmsplane); - break; - } - } - } - } - } - - if (output.eglfs_plane) { - qCDebug(qLcKmsDebug, "Chose plane %u for output %s (crtc id %u) (may not be applicable)", - output.eglfs_plane->id, connectorName.constData(), output.crtc_id); - } - -#ifdef EGLFS_ENABLE_DRM_ATOMIC - if (hasAtomicSupport() && !output.eglfs_plane) { - qCDebug(qLcKmsDebug, "No plane associated with output %s (crtc id %u) and atomic modesetting is enabled. This is bad.", - connectorName.constData(), output.crtc_id); - } -#endif - - m_crtc_allocator |= (1 << output.crtc_index); - - vinfo->output = output; - - return createScreen(output); -} - -drmModePropertyPtr KmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) -{ - drmModePropertyPtr prop; - - for (int i = 0; i < connector->count_props; i++) { - prop = drmModeGetProperty(m_dri_fd, connector->props[i]); - if (!prop) - continue; - if (strcmp(prop->name, name.constData()) == 0) - return prop; - drmModeFreeProperty(prop); - } - - return nullptr; -} - -drmModePropertyBlobPtr KmsDevice::connectorPropertyBlob(drmModeConnectorPtr connector, const QByteArray &name) -{ - drmModePropertyPtr prop; - drmModePropertyBlobPtr blob = nullptr; - - for (int i = 0; i < connector->count_props && !blob; i++) { - prop = drmModeGetProperty(m_dri_fd, connector->props[i]); - if (!prop) - continue; - if ((prop->flags & DRM_MODE_PROP_BLOB) && (strcmp(prop->name, name.constData()) == 0)) - blob = drmModeGetPropertyBlob(m_dri_fd, connector->prop_values[i]); - drmModeFreeProperty(prop); - } - - return blob; -} - -KmsDevice::KmsDevice(KmsScreenConfig *screenConfig, const QString &path) - : m_screenConfig(screenConfig) - , m_path(path) - , m_dri_fd(-1) - , m_has_atomic_support(false) - , m_crtc_allocator(0) -{ - if (m_path.isEmpty()) { - m_path = m_screenConfig->devicePath(); - qCDebug(qLcKmsDebug, "Using DRM device %s specified in config file", qPrintable(m_path)); - if (m_path.isEmpty()) - qFatal("No DRM device given"); - } else { - qCDebug(qLcKmsDebug, "Using backend-provided DRM device %s", qPrintable(m_path)); - } -} - -KmsDevice::~KmsDevice() -{ -#ifdef EGLFS_ENABLE_DRM_ATOMIC - threadLocalAtomicReset(); -#endif -} - -struct OrderedScreen -{ - OrderedScreen() : screen(nullptr) { } - OrderedScreen(QPlatformScreen *screen, const KmsDevice::ScreenInfo &vinfo) - : screen(screen), vinfo(vinfo) { } - QPlatformScreen *screen; - KmsDevice::ScreenInfo vinfo; -}; - -QDebug operator<<(QDebug dbg, const OrderedScreen &s) -{ - QDebugStateSaver saver(dbg); - dbg.nospace() << "OrderedScreen(QPlatformScreen=" << s.screen << " (" << s.screen->name() << ") : " - << s.vinfo.virtualIndex - << " / " << s.vinfo.virtualPos - << " / primary: " << s.vinfo.isPrimary - << ")"; - return dbg; -} - -static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b) -{ - return a.vinfo.virtualIndex < b.vinfo.virtualIndex; -} - -void KmsDevice::createScreens() -{ - // Headless mode using a render node: cannot do any output related DRM - // stuff. Skip it all and register a dummy screen. - if (m_screenConfig->headless()) { - QPlatformScreen *screen = createHeadlessScreen(); - if (screen) { - qCDebug(qLcKmsDebug, "Headless mode enabled"); - registerScreen(screen, true, QPoint(0, 0), QList()); - return; - } else { - qWarning("QKmsDevice: Requested headless mode without support in the backend. Request is ignored."); - } - } - - drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - -#ifdef EGLFS_ENABLE_DRM_ATOMIC - // check atomic support - m_has_atomic_support = !drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_ATOMIC, 1); - if (m_has_atomic_support) { - qCDebug(qLcKmsDebug, "Atomic reported as supported"); - if (qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ATOMIC")) { - qCDebug(qLcKmsDebug, "Atomic enabled"); - } else { - qCDebug(qLcKmsDebug, "Atomic disabled"); - m_has_atomic_support = false; - } - } -#endif - - drmModeResPtr resources = drmModeGetResources(m_dri_fd); - if (!resources) { - qErrnoWarning(errno, "drmModeGetResources failed"); - return; - } - - discoverPlanes(); - - QVector screens; - - int wantedConnectorIndex = -1; - bool ok; - int idx = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_CONNECTOR_INDEX", &ok); - if (ok) { - if (idx >= 0 && idx < resources->count_connectors) - wantedConnectorIndex = idx; - else - qWarning("Invalid connector index %d, must be between 0 and %u", idx, resources->count_connectors - 1); - } - - for (int i = 0; i < resources->count_connectors; i++) { - if (wantedConnectorIndex >= 0 && i != wantedConnectorIndex) - continue; - - drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); - if (!connector) - continue; - - ScreenInfo vinfo; - QPlatformScreen *screen = createScreenForConnector(resources, connector, &vinfo); - if (screen) - screens.append(OrderedScreen(screen, vinfo)); - - drmModeFreeConnector(connector); - } - - drmModeFreeResources(resources); - - // Use stable sort to preserve the original (DRM connector) order - // for outputs with unspecified indices. - std::stable_sort(screens.begin(), screens.end(), orderedScreenLessThan); - qCDebug(qLcKmsDebug) << "Sorted screen list:" << screens; - - // The final list of screens is available, so do the second phase setup. - // Hook up clone sources and targets. - for (const OrderedScreen &orderedScreen : screens) { - QVector screensCloningThisScreen; - for (const OrderedScreen &s : screens) { - if (s.vinfo.output.clone_source == orderedScreen.vinfo.output.name) - screensCloningThisScreen.append(s.screen); - } - QPlatformScreen *screenThisScreenClones = nullptr; - if (!orderedScreen.vinfo.output.clone_source.isEmpty()) { - for (const OrderedScreen &s : screens) { - if (s.vinfo.output.name == orderedScreen.vinfo.output.clone_source) { - screenThisScreenClones = s.screen; - break; - } - } - } - if (screenThisScreenClones) - qCDebug(qLcKmsDebug) << orderedScreen.screen->name() << "clones" << screenThisScreenClones; - if (!screensCloningThisScreen.isEmpty()) - qCDebug(qLcKmsDebug) << orderedScreen.screen->name() << "is cloned by" << screensCloningThisScreen; - - registerScreenCloning(orderedScreen.screen, screenThisScreenClones, screensCloningThisScreen); - } - - // Figure out the virtual desktop and register the screens to QPA/QGuiApplication. - QPoint pos(0, 0); - QList siblings; - QVector virtualPositions; - int primarySiblingIdx = -1; - - for (const OrderedScreen &orderedScreen : screens) { - QPlatformScreen *s = orderedScreen.screen; - QPoint virtualPos(0, 0); - // set up a horizontal or vertical virtual desktop - if (orderedScreen.vinfo.virtualPos.isNull()) { - virtualPos = pos; - if (m_screenConfig->virtualDesktopLayout() == KmsScreenConfig::VirtualDesktopLayoutVertical) - pos.ry() += s->geometry().height(); - else - pos.rx() += s->geometry().width(); - } else { - virtualPos = orderedScreen.vinfo.virtualPos; - } - qCDebug(qLcKmsDebug) << "Adding QPlatformScreen" << s << "(" << s->name() << ")" - << "to QPA with geometry" << s->geometry() - << "and isPrimary=" << orderedScreen.vinfo.isPrimary; - // The order in qguiapp's screens list will match the order set by - // virtualIndex. This is not only handy but also required since for instance - // evdevtouch relies on it when performing touch device - screen mapping. - if (!m_screenConfig->separateScreens()) { - siblings.append(s); - virtualPositions.append(virtualPos); - if (orderedScreen.vinfo.isPrimary) - primarySiblingIdx = siblings.count() - 1; - } else { - registerScreen(s, orderedScreen.vinfo.isPrimary, virtualPos, QList() << s); - } - } - - if (!m_screenConfig->separateScreens()) { - // enable the virtual desktop - for (int i = 0; i < siblings.count(); ++i) - registerScreen(siblings[i], i == primarySiblingIdx, virtualPositions[i], siblings); - } -} - -QPlatformScreen *KmsDevice::createHeadlessScreen() -{ - // headless mode not supported by default - return nullptr; -} - -// not all subclasses support screen cloning -void KmsDevice::registerScreenCloning(QPlatformScreen *screen, - QPlatformScreen *screenThisScreenClones, - const QVector &screensCloningThisScreen) -{ - Q_UNUSED(screen); - Q_UNUSED(screenThisScreenClones); - Q_UNUSED(screensCloningThisScreen); -} - -// drm_property_type_is is not available in old headers -static inline bool propTypeIs(drmModePropertyPtr prop, uint32_t type) -{ - if (prop->flags & DRM_MODE_PROP_EXTENDED_TYPE) - return (prop->flags & DRM_MODE_PROP_EXTENDED_TYPE) == type; - return prop->flags & type; -} - -void KmsDevice::enumerateProperties(drmModeObjectPropertiesPtr objProps, PropCallback callback) -{ - for (uint32_t propIdx = 0; propIdx < objProps->count_props; ++propIdx) { - drmModePropertyPtr prop = drmModeGetProperty(m_dri_fd, objProps->props[propIdx]); - if (!prop) - continue; - - const quint64 value = objProps->prop_values[propIdx]; - qCDebug(qLcKmsDebug, " property %d: id = %u name = '%s'", propIdx, prop->prop_id, prop->name); - - if (propTypeIs(prop, DRM_MODE_PROP_SIGNED_RANGE)) { - qCDebug(qLcKmsDebug, " type is SIGNED_RANGE, value is %lld, possible values are:", qint64(value)); - for (int i = 0; i < prop->count_values; ++i) - qCDebug(qLcKmsDebug, " %lld", qint64(prop->values[i])); - } else if (propTypeIs(prop, DRM_MODE_PROP_RANGE)) { - qCDebug(qLcKmsDebug, " type is RANGE, value is %llu, possible values are:", value); - for (int i = 0; i < prop->count_values; ++i) - qCDebug(qLcKmsDebug, " %llu", quint64(prop->values[i])); - } else if (propTypeIs(prop, DRM_MODE_PROP_ENUM)) { - qCDebug(qLcKmsDebug, " type is ENUM, value is %llu, possible values are:", value); - for (int i = 0; i < prop->count_enums; ++i) - qCDebug(qLcKmsDebug, " enum %d: %s - %llu", i, prop->enums[i].name, quint64(prop->enums[i].value)); - } else if (propTypeIs(prop, DRM_MODE_PROP_BITMASK)) { - qCDebug(qLcKmsDebug, " type is BITMASK, value is %llu, possible bits are:", value); - for (int i = 0; i < prop->count_enums; ++i) - qCDebug(qLcKmsDebug, " bitmask %d: %s - %u", i, prop->enums[i].name, 1 << prop->enums[i].value); - } else if (propTypeIs(prop, DRM_MODE_PROP_BLOB)) { - qCDebug(qLcKmsDebug, " type is BLOB"); - } else if (propTypeIs(prop, DRM_MODE_PROP_OBJECT)) { - qCDebug(qLcKmsDebug, " type is OBJECT"); - } - - callback(prop, value); - - drmModeFreeProperty(prop); - } -} - -void KmsDevice::discoverPlanes() -{ - m_planes.clear(); - - drmModePlaneResPtr planeResources = drmModeGetPlaneResources(m_dri_fd); - if (!planeResources) - return; - - const int countPlanes = planeResources->count_planes; - qCDebug(qLcKmsDebug, "Found %d planes", countPlanes); - for (int planeIdx = 0; planeIdx < countPlanes; ++planeIdx) { - drmModePlanePtr drmplane = drmModeGetPlane(m_dri_fd, planeResources->planes[planeIdx]); - if (!drmplane) { - qCDebug(qLcKmsDebug, "Failed to query plane %d, ignoring", planeIdx); - continue; - } - - KmsPlane plane; - plane.id = drmplane->plane_id; - plane.possibleCrtcs = drmplane->possible_crtcs; - - const int countFormats = drmplane->count_formats; - QString formatStr; - for (int i = 0; i < countFormats; ++i) { - uint32_t f = drmplane->formats[i]; - plane.supportedFormats.append(f); - formatStr += QString::asprintf("%c%c%c%c ", f, f >> 8, f >> 16, f >> 24); - } - - qCDebug(qLcKmsDebug, "plane %d: id = %u countFormats = %d possibleCrtcs = 0x%x supported formats = %s", - planeIdx, plane.id, countFormats, plane.possibleCrtcs, qPrintable(formatStr)); - - drmModeFreePlane(drmplane); - - drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(m_dri_fd, plane.id, DRM_MODE_OBJECT_PLANE); - if (!objProps) { - qCDebug(qLcKmsDebug, "Failed to query plane %d object properties, ignoring", planeIdx); - continue; - } - - enumerateProperties(objProps, [&plane](drmModePropertyPtr prop, quint64 value) { - if (!strcmp(prop->name, "type")) { - plane.type = KmsPlane::Type(value); - } else if (!strcmp(prop->name, "rotation")) { - plane.initialRotation = KmsPlane::Rotations(int(value)); - plane.availableRotations = { }; - if (propTypeIs(prop, DRM_MODE_PROP_BITMASK)) { - for (int i = 0; i < prop->count_enums; ++i) - plane.availableRotations |= KmsPlane::Rotation(1 << prop->enums[i].value); - } - plane.rotationPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "crtc_id")) { - plane.crtcPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "fb_id")) { - plane.framebufferPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "src_w")) { - plane.srcwidthPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "src_h")) { - plane.srcheightPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "crtc_w")) { - plane.crtcwidthPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "crtc_h")) { - plane.crtcheightPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "src_x")) { - plane.srcXPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "src_y")) { - plane.srcYPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "crtc_x")) { - plane.crtcXPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "crtc_y")) { - plane.crtcYPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "zpos")) { - plane.zposPropertyId = prop->prop_id; - } else if (!strcasecmp(prop->name, "blend_op")) { - plane.blendOpPropertyId = prop->prop_id; - } - }); - - m_planes.append(plane); - - drmModeFreeObjectProperties(objProps); - } - - drmModeFreePlaneResources(planeResources); -} - -int KmsDevice::fd() const -{ - return m_dri_fd; -} - -QString KmsDevice::devicePath() const -{ - return m_path; -} - -void KmsDevice::setFd(int fd) -{ - m_dri_fd = fd; -} - - -bool KmsDevice::hasAtomicSupport() -{ - return m_has_atomic_support; -} - -#ifdef EGLFS_ENABLE_DRM_ATOMIC -drmModeAtomicReq *KmsDevice::threadLocalAtomicRequest() -{ - if (!m_has_atomic_support) - return nullptr; - - AtomicReqs &a(m_atomicReqs.localData()); - if (!a.request) - a.request = drmModeAtomicAlloc(); - - return a.request; -} - -bool KmsDevice::threadLocalAtomicCommit(void *user_data) -{ - if (!m_has_atomic_support) - return false; - - AtomicReqs &a(m_atomicReqs.localData()); - if (!a.request) - return false; - - int ret = drmModeAtomicCommit(m_dri_fd, a.request, - DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_ALLOW_MODESET, - user_data); - - if (ret) { - qWarning("Failed to commit atomic request (code=%d)", ret); - return false; - } - - a.previous_request = a.request; - a.request = nullptr; - - return true; -} - -void KmsDevice::threadLocalAtomicReset() -{ - if (!m_has_atomic_support) - return; - - AtomicReqs &a(m_atomicReqs.localData()); - if (a.previous_request) { - drmModeAtomicFree(a.previous_request); - a.previous_request = nullptr; - } -} -#endif - -void KmsDevice::parseConnectorProperties(uint32_t connectorId, KmsOutput *output) -{ - drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(m_dri_fd, connectorId, DRM_MODE_OBJECT_CONNECTOR); - if (!objProps) { - qCDebug(qLcKmsDebug, "Failed to query connector %d object properties", connectorId); - return; - } - - enumerateProperties(objProps, [output](drmModePropertyPtr prop, quint64 value) { - Q_UNUSED(value); - if (!strcasecmp(prop->name, "crtc_id")) - output->crtcIdPropertyId = prop->prop_id; - }); - - drmModeFreeObjectProperties(objProps); -} - -void KmsDevice::parseCrtcProperties(uint32_t crtcId, KmsOutput *output) -{ - drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(m_dri_fd, crtcId, DRM_MODE_OBJECT_CRTC); - if (!objProps) { - qCDebug(qLcKmsDebug, "Failed to query crtc %d object properties", crtcId); - return; - } - - enumerateProperties(objProps, [output](drmModePropertyPtr prop, quint64 value) { - Q_UNUSED(value) - if (!strcasecmp(prop->name, "mode_id")) - output->modeIdPropertyId = prop->prop_id; - else if (!strcasecmp(prop->name, "active")) - output->activePropertyId = prop->prop_id; - }); - - drmModeFreeObjectProperties(objProps); -} - -KmsScreenConfig *KmsDevice::screenConfig() const -{ - return m_screenConfig; -} - -KmsScreenConfig::KmsScreenConfig() - : m_headless(false) - , m_hwCursor(true) - , m_separateScreens(false) - , m_pbuffers(false) - , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal) -{ - loadConfig(); -} - -void KmsScreenConfig::loadConfig() -{ - QByteArray json = qgetenv("QT_QPA_EGLFS_KMS_CONFIG"); - if (json.isEmpty()) { - json = qgetenv("QT_QPA_KMS_CONFIG"); - if (json.isEmpty()) - return; - } - - qCDebug(qLcKmsDebug) << "Loading KMS setup from" << json; - - QFile file(QString::fromUtf8(json)); - if (!file.open(QFile::ReadOnly)) { - qCWarning(qLcKmsDebug) << "Could not open config file" - << json << "for reading"; - return; - } - - const QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); - if (!doc.isObject()) { - qCWarning(qLcKmsDebug) << "Invalid config file" << json - << "- no top-level JSON object"; - return; - } - - const QJsonObject object = doc.object(); - - const QString headlessStr = object.value(QLatin1String("headless")).toString(); - const QByteArray headless = headlessStr.toUtf8(); - QSize headlessSize; - if (sscanf(headless.constData(), "%dx%d", &headlessSize.rwidth(), &headlessSize.rheight()) == 2) { - m_headless = true; - m_headlessSize = headlessSize; - } else { - m_headless = false; - } - - m_hwCursor = object.value(QLatin1String("hwcursor")).toBool(m_hwCursor); - m_pbuffers = object.value(QLatin1String("pbuffers")).toBool(m_pbuffers); - m_devicePath = object.value(QLatin1String("device")).toString(); - m_separateScreens = object.value(QLatin1String("separateScreens")).toBool(m_separateScreens); - - const QString vdOriString = object.value(QLatin1String("virtualDesktopLayout")).toString(); - if (!vdOriString.isEmpty()) { - if (vdOriString == QLatin1String("horizontal")) - m_virtualDesktopLayout = VirtualDesktopLayoutHorizontal; - else if (vdOriString == QLatin1String("vertical")) - m_virtualDesktopLayout = VirtualDesktopLayoutVertical; - else - qCWarning(qLcKmsDebug) << "Unknown virtualDesktopOrientation value" << vdOriString; - } - - const QJsonArray outputs = object.value(QLatin1String("outputs")).toArray(); - for (int i = 0; i < outputs.size(); i++) { - const QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap(); - - if (outputSettings.contains(QStringLiteral("name"))) { - const QString name = outputSettings.value(QStringLiteral("name")).toString(); - - if (m_outputSettings.contains(name)) { - qCDebug(qLcKmsDebug) << "Output" << name << "configured multiple times!"; - } - - m_outputSettings.insert(name, outputSettings); - } - } - - qCDebug(qLcKmsDebug) << "Requested configuration (some settings may be ignored):\n" - << "\theadless:" << m_headless << "\n" - << "\thwcursor:" << m_hwCursor << "\n" - << "\tpbuffers:" << m_pbuffers << "\n" - << "\tseparateScreens:" << m_separateScreens << "\n" - << "\tvirtualDesktopLayout:" << m_virtualDesktopLayout << "\n" - << "\toutputs:" << m_outputSettings; -} - -void KmsOutput::restoreMode(KmsDevice *device) -{ - if (mode_set && saved_crtc) { - drmModeSetCrtc(device->fd(), - saved_crtc->crtc_id, - saved_crtc->buffer_id, - 0, 0, - &connector_id, 1, - &saved_crtc->mode); - mode_set = false; - } -} - -void KmsOutput::cleanup(KmsDevice *device) -{ - if (dpms_prop) { - drmModeFreeProperty(dpms_prop); - dpms_prop = nullptr; - } - - if (edid_blob) { - drmModeFreePropertyBlob(edid_blob); - edid_blob = nullptr; - } - - restoreMode(device); - - if (saved_crtc) { - drmModeFreeCrtc(saved_crtc); - saved_crtc = nullptr; - } -} - -QPlatformScreen::SubpixelAntialiasingType KmsOutput::subpixelAntialiasingTypeHint() const -{ - switch (subpixel) { - default: - case DRM_MODE_SUBPIXEL_UNKNOWN: - case DRM_MODE_SUBPIXEL_NONE: - return QPlatformScreen::Subpixel_None; - case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB: - return QPlatformScreen::Subpixel_RGB; - case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR: - return QPlatformScreen::Subpixel_BGR; - case DRM_MODE_SUBPIXEL_VERTICAL_RGB: - return QPlatformScreen::Subpixel_VRGB; - case DRM_MODE_SUBPIXEL_VERTICAL_BGR: - return QPlatformScreen::Subpixel_VBGR; - } -} - -void KmsOutput::setPowerState(KmsDevice *device, QPlatformScreen::PowerState state) -{ - if (dpms_prop) - drmModeConnectorSetProperty(device->fd(), connector_id, - dpms_prop->prop_id, (int) state); -} - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/kmsconvenience/aurorakmsdevice_p.h b/src/platformsupport/kmsconvenience/aurorakmsdevice_p.h deleted file mode 100644 index dc3cc15a..00000000 --- a/src/platformsupport/kmsconvenience/aurorakmsdevice_p.h +++ /dev/null @@ -1,305 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Copyright (C) 2015 Pier Luigi Fiorini -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -// In less fortunate cases one may need to build on a system with dev headers -// from the dark ages. Let's pull a GL and define the missing stuff outselves. - -#ifndef DRM_PLANE_TYPE_OVERLAY -#define DRM_PLANE_TYPE_OVERLAY 0 -#endif -#ifndef DRM_PLANE_TYPE_PRIMARY -#define DRM_PLANE_TYPE_PRIMARY 1 -#endif -#ifndef DRM_PLANE_TYPE_CURSOR -#define DRM_PLANE_TYPE_CURSOR 2 -#endif - -#ifndef DRM_CLIENT_CAP_UNIVERSAL_PLANES -#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 -#endif -#ifndef DRM_CLIENT_CAP_ATOMIC -#define DRM_CLIENT_CAP_ATOMIC 3 -#endif - -#ifndef DRM_MODE_PROP_EXTENDED_TYPE -#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0 -#endif -#ifndef DRM_MODE_PROP_TYPE -#define DRM_MODE_PROP_TYPE(n) ((n) << 6) -#endif -#ifndef DRM_MODE_PROP_OBJECT -#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1) -#endif -#ifndef DRM_MODE_PROP_SIGNED_RANGE -#define DRM_MODE_PROP_SIGNED_RANGE DRM_MODE_PROP_TYPE(2) -#endif - -namespace Aurora { - -namespace PlatformSupport { - -class KmsDevice; - -class KmsScreenConfig -{ -public: - enum VirtualDesktopLayout { - VirtualDesktopLayoutHorizontal, - VirtualDesktopLayoutVertical - }; - - KmsScreenConfig(); - - QString devicePath() const { return m_devicePath; } - - bool headless() const { return m_headless; } - QSize headlessSize() const { return m_headlessSize; } - bool hwCursor() const { return m_hwCursor; } - bool separateScreens() const { return m_separateScreens; } - bool supportsPBuffers() const { return m_pbuffers; } - VirtualDesktopLayout virtualDesktopLayout() const { return m_virtualDesktopLayout; } - - QMap outputSettings() const { return m_outputSettings; } - -private: - void loadConfig(); - - QString m_devicePath; - bool m_headless; - QSize m_headlessSize; - bool m_hwCursor; - bool m_separateScreens; - bool m_pbuffers; - VirtualDesktopLayout m_virtualDesktopLayout; - QMap m_outputSettings; -}; - -// NB! QKmsPlane does not store the current state and offers no functions to -// change object properties. Any such functionality belongs to subclasses since -// in some cases atomic operations will be desired where a mere -// drmModeObjectSetProperty would not be acceptable. -struct KmsPlane -{ - enum Type { - OverlayPlane = DRM_PLANE_TYPE_OVERLAY, - PrimaryPlane = DRM_PLANE_TYPE_PRIMARY, - CursorPlane = DRM_PLANE_TYPE_CURSOR - }; - - enum Rotation { - Rotation0 = 1 << 0, - Rotation90 = 1 << 1, - Rotation180 = 1 << 2, - Rotation270 = 1 << 3, - RotationReflectX = 1 << 4, - RotationReflectY = 1 << 5 - }; - Q_DECLARE_FLAGS(Rotations, Rotation) - - uint32_t id = 0; - Type type = OverlayPlane; - - int possibleCrtcs = 0; - - QVector supportedFormats; - - Rotations initialRotation = Rotation0; - Rotations availableRotations = Rotation0; - uint32_t rotationPropertyId = 0; - uint32_t crtcPropertyId = 0; - uint32_t framebufferPropertyId = 0; - uint32_t srcXPropertyId = 0; - uint32_t srcYPropertyId = 0; - uint32_t crtcXPropertyId = 0; - uint32_t crtcYPropertyId = 0; - uint32_t srcwidthPropertyId = 0; - uint32_t srcheightPropertyId = 0; - uint32_t crtcwidthPropertyId = 0; - uint32_t crtcheightPropertyId = 0; - uint32_t zposPropertyId = 0; - uint32_t blendOpPropertyId = 0; - - uint32_t activeCrtcId = 0; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(KmsPlane::Rotations) - -struct KmsOutput -{ - QString name; - uint32_t connector_id = 0; - uint32_t crtc_index = 0; - uint32_t crtc_id = 0; - QSizeF physical_size; - int preferred_mode = -1; // index of preferred mode in list below - int mode = -1; // index of selected mode in list below - bool mode_set = false; - drmModeCrtcPtr saved_crtc = nullptr; - QList modes; - int subpixel = DRM_MODE_SUBPIXEL_UNKNOWN; - drmModePropertyPtr dpms_prop = nullptr; - drmModePropertyBlobPtr edid_blob = nullptr; - bool wants_forced_plane = false; - uint32_t forced_plane_id = 0; - bool forced_plane_set = false; - uint32_t drm_format = DRM_FORMAT_XRGB8888; - bool drm_format_requested_by_user = false; - QString clone_source; - QVector available_planes; - struct KmsPlane *eglfs_plane = nullptr; - QSize size; - uint32_t crtcIdPropertyId = 0; - uint32_t modeIdPropertyId = 0; - uint32_t activePropertyId = 0; - - uint32_t mode_blob_id = 0; - - void restoreMode(KmsDevice *device); - void cleanup(KmsDevice *device); - QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const; - void setPowerState(KmsDevice *device, QPlatformScreen::PowerState state); -}; - -class KmsDevice -{ -public: - struct ScreenInfo { - int virtualIndex = 0; - QPoint virtualPos; - bool isPrimary = false; - KmsOutput output; - }; - - KmsDevice(KmsScreenConfig *screenConfig, const QString &path = QString()); - virtual ~KmsDevice(); - - virtual bool open() = 0; - virtual void close() = 0; - virtual void *nativeDisplay() const = 0; - - bool hasAtomicSupport(); - -#ifdef EGLFS_ENABLE_DRM_ATOMIC - drmModeAtomicReq *threadLocalAtomicRequest(); - bool threadLocalAtomicCommit(void *user_data); - void threadLocalAtomicReset(); -#endif - void createScreens(); - - int fd() const; - QString devicePath() const; - - KmsScreenConfig *screenConfig() const; - -protected: - virtual QPlatformScreen *createScreen(const KmsOutput &output) = 0; - virtual QPlatformScreen *createHeadlessScreen(); - virtual void registerScreenCloning(QPlatformScreen *screen, - QPlatformScreen *screenThisScreenClones, - const QVector &screensCloningThisScreen); - virtual void registerScreen(QPlatformScreen *screen, - bool isPrimary, - const QPoint &virtualPos, - const QList &virtualSiblings) = 0; - - void setFd(int fd); - int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); - QPlatformScreen *createScreenForConnector(drmModeResPtr resources, - drmModeConnectorPtr connector, - ScreenInfo *vinfo); - drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); - drmModePropertyBlobPtr connectorPropertyBlob(drmModeConnectorPtr connector, const QByteArray &name); - typedef std::function PropCallback; - void enumerateProperties(drmModeObjectPropertiesPtr objProps, PropCallback callback); - void discoverPlanes(); - void parseConnectorProperties(uint32_t connectorId, KmsOutput *output); - void parseCrtcProperties(uint32_t crtcId, KmsOutput *output); - - KmsScreenConfig *m_screenConfig; - QString m_path; - int m_dri_fd; - - bool m_has_atomic_support; - -#ifdef EGLFS_ENABLE_DRM_ATOMIC - struct AtomicReqs { - drmModeAtomicReq *request = nullptr; - drmModeAtomicReq *previous_request = nullptr; - }; - QThreadStorage m_atomicReqs; -#endif - quint32 m_crtc_allocator; - - QVector m_planes; - -private: - Q_DISABLE_COPY(KmsDevice) -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/logind/CMakeLists.txt b/src/platformsupport/logind/CMakeLists.txt deleted file mode 100644 index 9831d5a1..00000000 --- a/src/platformsupport/logind/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_module(AuroraLogind - DESCRIPTION - "Qt API for logind" - SOURCES - defaultlogind_p_p.h - logind.cpp logind.h logind_p.h - logindtypes.cpp logindtypes_p.h - DEFINES - #QT_NO_CAST_FROM_ASCII - QT_NO_FOREACH - QT_NO_KEYWORDS - PUBLIC_LIBRARIES - Qt::Core - Qt::DBus - PKGCONFIG_DEPENDENCIES - Qt${QT_DEFAULT_MAJOR_VERSION}Core - Qt${QT_DEFAULT_MAJOR_VERSION}DBus -) - -liri_finalize_module(AuroraLogind) diff --git a/src/platformsupport/logind/Liri1AuroraLogindDependencies.cmake.in b/src/platformsupport/logind/Liri1AuroraLogindDependencies.cmake.in deleted file mode 100644 index cf0f316e..00000000 --- a/src/platformsupport/logind/Liri1AuroraLogindDependencies.cmake.in +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -include(CMakeFindDependencyMacro) - -find_dependency(Qt@QT_MAJOR_VERSION@Core "@QT_MIN_VERSION@" REQUIRED) -find_dependency(Qt@QT_MAJOR_VERSION@DBus "@QT_MIN_VERSION@" REQUIRED) diff --git a/src/platformsupport/logind/defaultlogind_p_p.h b/src/platformsupport/logind/defaultlogind_p_p.h deleted file mode 100644 index 825eaf18..00000000 --- a/src/platformsupport/logind/defaultlogind_p_p.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Liri API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -namespace Aurora { - -namespace PlatformSupport { - -class DefaultLogind : public Logind -{ - Q_OBJECT -public: - explicit DefaultLogind(QObject *parent = nullptr); -}; - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/logind/lirilogindglobal.h b/src/platformsupport/logind/lirilogindglobal.h deleted file mode 100644 index 4e1c27ca..00000000 --- a/src/platformsupport/logind/lirilogindglobal.h +++ /dev/null @@ -1,33 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -#if defined(QT_BUILD_LIRILOGIND_LIB) -# define LIRILOGIND_EXPORT Q_DECL_EXPORT -#else -# define LIRILOGIND_EXPORT Q_DECL_IMPORT -#endif -#define LIRILOGIND_NO_EXPORT Q_DECL_HIDDEN diff --git a/src/platformsupport/logind/logind.cpp b/src/platformsupport/logind/logind.cpp deleted file mode 100644 index f1732072..00000000 --- a/src/platformsupport/logind/logind.cpp +++ /dev/null @@ -1,974 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "defaultlogind_p_p.h" -#include "logind.h" -#include "logind_p.h" - -#include - -#include - -Q_LOGGING_CATEGORY(gLcLogind, "aurora.logind") - -#define LOGIN1_SERVICE QStringLiteral("org.freedesktop.login1") - -#define LOGIN1_OBJECT QLatin1String("/org/freedesktop/login1") -#define LOGIN1_MANAGER_INTERFACE QLatin1String("org.freedesktop.login1.Manager") -#define LOGIN1_SEAT_INTERFACE QLatin1String("org.freedesktop.login1.Seat") -#define LOGIN1_SESSION_INTERFACE QLatin1String("org.freedesktop.login1.Session") - -#define DBUS_SERVICE QLatin1String("org.freedesktop.DBus") -#define DBUS_PROPERTIES_INTERFACE QLatin1String("org.freedesktop.DBus.Properties") - -namespace Aurora { - -namespace PlatformSupport { - -/* - * DefaultLogind - */ - -DefaultLogind::DefaultLogind(QObject *parent) - : Logind(QDBusConnection::systemBus(), parent) -{ -} - -Q_GLOBAL_STATIC(DefaultLogind, s_logind) - -/* - * LogindPrivate - */ - -LogindPrivate::LogindPrivate(Logind *qq) - : bus(QDBusConnection::systemBus()) - , q_ptr(qq) -{ -} - -void LogindPrivate::_q_serviceRegistered() -{ - Q_Q(Logind); - - // Skip if we're already connected - if (isConnected) - return; - - // Find the active session otherwise try with XDG_SESSION_ID or the PID, - // when spawned by systemd --user only the first method is expected to work - DBusUserSession session; - if (getUserSession(session)) { - sessionPath = session.objectPath.path(); - qCInfo(gLcLogind, "Using session %s", qPrintable(session.id)); - } else { - QDBusObjectPath sessionObjectPath; - - if (qEnvironmentVariableIsSet("XDG_SESSION_ID")) { - if (getSessionById(QString::fromLocal8Bit(qgetenv("XDG_SESSION_ID")), sessionObjectPath)) - sessionPath = sessionObjectPath.path(); - } - - if (sessionObjectPath.path().isEmpty()) { - if (getSessionByPid(sessionObjectPath)) - sessionPath = sessionObjectPath.path(); - } - - if (!sessionPath.isEmpty()) { - QString sessionId = getSessionId(sessionPath); - qCInfo(gLcLogind, "Using session %s", qPrintable(sessionId)); - } - } - if (sessionPath.isEmpty()) { - qCWarning(gLcLogind) << "Unable to find session!"; - return; - } - qCDebug(gLcLogind) << "Session path:" << sessionPath; - - // We are connected now - isConnected = true; - - // Listen for lock and unlock signals - bus.connect(LOGIN1_SERVICE, sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("Lock"), - q, SIGNAL(lockSessionRequested())); - bus.connect(LOGIN1_SERVICE, sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("Unlock"), - q, SIGNAL(unlockSessionRequested())); - - // Listen for properties changed - bus.connect(LOGIN1_SERVICE, sessionPath, DBUS_PROPERTIES_INTERFACE, - QLatin1String("PropertiesChanged"), - q, SLOT(_q_sessionPropertiesChanged())); - - // Listen for prepare signals - bus.connect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForSleep"), - q, SIGNAL(prepareForSleep(bool))); - bus.connect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForShutdown"), - q, SIGNAL(prepareForShutdown(bool))); - - // Activate the session in case we are on another vt, the - // call blocks on purpose because we need to get properties - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - LOGIN1_MANAGER_INTERFACE, - QLatin1String("Activate")); - bus.call(message); - - // Get properties - _q_sessionPropertiesChanged(); - - Q_EMIT q->connectedChanged(isConnected); -} - -void LogindPrivate::_q_serviceUnregistered() -{ - Q_Q(Logind); - - // Disconnect prepare signals - bus.disconnect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForSleep"), - q, SIGNAL(prepareForSleep(bool))); - bus.disconnect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForShutdown"), - q, SIGNAL(prepareForShutdown(bool))); - - // Connection lost - isConnected = false; - Q_EMIT q->connectedChanged(isConnected); - - // Reset properties - if (sessionActive) { - sessionActive = false; - Q_EMIT q->sessionActiveChanged(false); - } - if (vt != -1) { - vt = -1; - Q_EMIT q->vtNumberChanged(-1); - } - if (!seat.isEmpty()) { - seat = QString(); - Q_EMIT q->seatChanged(seat); - } -} - -void LogindPrivate::_q_sessionPropertiesChanged() -{ - if (!isConnected || sessionPath.isEmpty()) - return; - - getSessionActive(); - getVirtualTerminal(); - getSeat(); -} - -void LogindPrivate::checkServiceRegistration() -{ - Q_Q(Logind); - - // Get the current session if the logind service is register - QDBusMessage message = - QDBusMessage::createMethodCall(DBUS_SERVICE, - QLatin1String("/"), - DBUS_SERVICE, - QLatin1String("ListNames")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, q); - q->connect(watcher, &QDBusPendingCallWatcher::finished, q, - [this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) - return; - - if (reply.value().contains(LOGIN1_SERVICE)) - _q_serviceRegistered(); - }); -} - -bool LogindPrivate::getSessionById(const QString &sessionId, QDBusObjectPath &path) const -{ - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QStringLiteral("GetSession")); - message.setArguments(QVariantList() << sessionId); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get session path for session %s: %s", - qPrintable(sessionId), - qPrintable(reply.error().message())); - return false; - } - - path = reply.value(); - return true; -} - -bool LogindPrivate::getSessionByPid(QDBusObjectPath &path) const -{ - QVariantList args; - args << static_cast(QCoreApplication::applicationPid()); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QStringLiteral("GetSessionByPID")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get session path by PID: %s", - qPrintable(reply.error().message())); - return false; - } - - path = reply.value(); - return true; -} - -bool LogindPrivate::getUserSession(DBusUserSession &session) const -{ - QDBusObjectPath userPath; - - { - QVariantList args; - args << ::getuid(); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QStringLiteral("GetUser")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get user path: %s", - qPrintable(reply.error().message())); - return false; - } - - userPath = reply.value(); - } - - { - QVariantList args; - args << QStringLiteral("org.freedesktop.login1.User") - << QStringLiteral("Sessions"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - userPath.path(), - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to list user sessions: %s", - qPrintable(reply.error().message())); - return false; - } - - // Find which session meets our critera - QStringList validTypes = { - QStringLiteral("tty"), - QStringLiteral("wayland"), - QStringLiteral("x11") - }; - - // We expect to have only one session for each user, and the session for the current - // user is supposed to be active because the user logged in with a login manager (either - // text based such as getty, or graphical like SDDM). - // Graphical login managers usually don't spawn a second session, but activate an already - // existing session for the user. - bool found = false; - DBusUserSessionVector sessions = qdbus_cast(reply.value().value()); - for (const auto &curSession : qAsConst(sessions)) { - const QString type = getSessionType(curSession.id, curSession.objectPath.path()); - const QString state = getSessionState(curSession.id, curSession.objectPath.path()); - - if (!validTypes.contains(type)) - continue; - if (state != QStringLiteral("active")) - continue; - - // We get the sessions from newest to oldest, pick the last - // one that meets the criteria - session = curSession; - found = true; - } - - return found; - } - - return false; -} - -QString LogindPrivate::getSessionId(const QString &sessionPath) const -{ - QVariantList args; - args << LOGIN1_SESSION_INTERFACE - << QStringLiteral("Id"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get session id: %s", - qPrintable(reply.error().message())); - return QString(); - } - - return reply.value().toString(); -} - -QString LogindPrivate::getSessionType(const QString &sessionId, const QString &sessionPath) const -{ - QVariantList args; - args << LOGIN1_SESSION_INTERFACE - << QStringLiteral("Type"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get type for session %s: %s", - qPrintable(sessionId), qPrintable(reply.error().message())); - return QString(); - } - - return reply.value().toString(); -} - -QString LogindPrivate::getSessionState(const QString &sessionId, const QString &sessionPath) const -{ - QVariantList args; - args << LOGIN1_SESSION_INTERFACE - << QStringLiteral("State"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get state for session %s: %s", - qPrintable(sessionId), qPrintable(reply.error().message())); - return QString(); - } - - return reply.value().toString(); -} - -void LogindPrivate::getSessionActive() -{ - Q_Q(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QLatin1String("Get")); - message.setArguments(QVariantList() << LOGIN1_SESSION_INTERFACE << QStringLiteral("Active")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(result, q); - q->connect(callWatcher, &QDBusPendingCallWatcher::finished, q, - [q, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get \"Active\" property from session: %s", - qPrintable(reply.error().message())); - return; - } - - const bool active = reply.value().toBool(); - if (sessionActive != active) { - sessionActive = active; - Q_EMIT q->sessionActiveChanged(active); - } - }); -} - -void LogindPrivate::getVirtualTerminal() -{ - Q_Q(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QLatin1String("Get")); - message.setArguments(QVariantList() << LOGIN1_SESSION_INTERFACE << QStringLiteral("VTNr")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(result, q); - q->connect(callWatcher, &QDBusPendingCallWatcher::finished, q, - [q, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get \"VTNr\" property from session: %s", - qPrintable(reply.error().message())); - return; - } - - const uint vtnr = reply.value().toUInt(); - if (vt != static_cast(vtnr)) { - vt = static_cast(vtnr); - Q_EMIT q->vtNumberChanged(vt); - } - }); -} - -void LogindPrivate::getSeat() -{ - Q_Q(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QLatin1String("Get")); - message.setArguments(QVariantList() << LOGIN1_SESSION_INTERFACE << QStringLiteral("Seat")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(result, q); - q->connect(callWatcher, &QDBusPendingCallWatcher::finished, q, - [q, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(gLcLogind, "Failed to get \"Seat\" property from session: %s", - qPrintable(reply.error().message())); - return; - } - - const DBusSeat dbusSeat = qdbus_cast(reply.value().value()); - if (seat != dbusSeat.id) { - seat = dbusSeat.id; - Q_EMIT q->seatChanged(seat); - } - }); -} - -/* - * Logind - */ - -/*! - * \class Logind - * \inmodule LiriLogind - * \brief Qt-style API for logind. - * - * LiriLogind is a Qt-style API for logind. - * - * More information on logind can be obtained - * \l{https://www.freedesktop.org/wiki/Software/systemd/logind/}(here). - * - * Logging category is "liri.logind". - * - * This class is a singleton, you cannot instantiate it. Use the instance() - * method to get access. - */ - -/*! - * Constructs a Logind instance with the given \a parent and D-Bus \a connection. - */ -Logind::Logind(const QDBusConnection &connection, QObject *parent) - : QObject(parent) - , d_ptr(new LogindPrivate(this)) -{ - // Register custom types - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - - // Initialize and respond to logind service (un)registration - Q_D(Logind); - d->bus = connection; - d->watcher = - new QDBusServiceWatcher(LOGIN1_SERVICE, d->bus, - QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, - this); - connect(d->watcher, SIGNAL(serviceRegistered(QString)), - this, SLOT(_q_serviceRegistered())); - connect(d->watcher, SIGNAL(serviceUnregistered(QString)), - this, SLOT(_q_serviceUnregistered())); - - // Is logind already registered? - d->checkServiceRegistration(); -} - -/*! - * Destroys the Logind object. - */ -Logind::~Logind() -{ - delete d_ptr; -} - -/*! - * Return the instance of Logind. - */ -Logind *Logind::instance() -{ - return s_logind(); -} - -bool Logind::checkService() -{ - QDBusConnectionInterface *interface = QDBusConnection::systemBus().interface(); - return interface->isServiceRegistered(LOGIN1_SERVICE); -} - -/*! - * \property Logind::isConnected - * - * This property holds whether we are connected to logind. - */ -bool Logind::isConnected() const -{ - Q_D(const Logind); - return d->isConnected; -} - -/*! - * \property Logind::isConnected - * - * This property holds whether session control was acquired. - * - * \sa Logind::takeControl() - * \sa Logind::releaseControl() - */ -bool Logind::hasSessionControl() const -{ - Q_D(const Logind); - return d->hasSessionControl; -} - -/*! - * \property Logind::isSessionActive - * - * This property holds whether the session this process lives in - * is active or not, that is whether the current vt is the one - * where the session was executed. - */ -bool Logind::isSessionActive() const -{ - Q_D(const Logind); - return d->sessionActive; -} - -/*! - * \property Logind::isInhibited - * - * This property holds if there are inhibitions installed. - */ -bool Logind::isInhibited() const -{ - Q_D(const Logind); - return d->inhibitFds.size() > 0; -} - -/*! - * \property Logind::vtNumber - * - * This property holds the current vt number. - */ -int Logind::vtNumber() const -{ - Q_D(const Logind); - return d->vt; -} - -/*! - * \property Logind::seat - * - * This property holds the current seat. - */ -QString Logind::seat() const -{ - Q_D(const Logind); - return d->seat; -} - -/*! - * Set the idle hint state to \a idle. - */ -void Logind::setIdleHint(bool idle) -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty()) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QStringLiteral("SetIdleHint")); - d->bus.asyncCall(message, idle); -} - -/*! - * Install an inhibitor. - * \param who Name of the application that is installing the inhibitor - * \param why Reason why the inhibitor is being installed - * \param flags What is being inhibited - * \param mode Inhibition mode - * - * \sa Logind::inhibited() - * \sa Logind::uninhibited() - */ -void Logind::inhibit(const QString &who, const QString &why, - InhibitFlags flags, InhibitMode mode) -{ - Q_D(Logind); - - if (!d->isConnected) - return; - - QStringList what; - if (flags.testFlag(InhibitShutdown)) - what.append(QStringLiteral("shutdown")); - if (flags.testFlag(InhibitSleep)) - what.append(QStringLiteral("sleep")); - if (flags.testFlag(InhibitIdle)) - what.append(QStringLiteral("idle")); - if (flags.testFlag(InhibitPowerKey)) - what.append(QStringLiteral("handle-power-key")); - if (flags.testFlag(InhibitSuspendKey)) - what.append(QStringLiteral("handle-suspend-key")); - if (flags.testFlag(InhibitHibernateKey)) - what.append(QStringLiteral("handle-hibernate-key")); - if (flags.testFlag(InhibitLidSwitch)) - what.append(QStringLiteral("handle-lid-switch")); - - QString modeStr = mode == Block ? QStringLiteral("block") : QStringLiteral("delay"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QLatin1String("Inhibit")); - message.setArguments(QVariantList() << what.join(':') << who << why << modeStr); - - QDBusPendingReply result = d->bus.asyncCall(message); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this); - connect(watcher, &QDBusPendingCallWatcher::finished, this, - [d, this, who, why](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(gLcLogind, "Unable to acquire inhibition lock: %s", - qPrintable(reply.error().message())); - return; - } - - qCDebug(gLcLogind) << "Inhibition lock acquired successfully"; - - const int fd = ::dup(reply.value().fileDescriptor()); - d->inhibitFds.append(fd); - if (d->inhibitFds.size() == 1) - Q_EMIT inhibitedChanged(true); - Q_EMIT inhibited(who, why, fd); - }); -} - -/*! - * Uninstall the inhibitor with \a fd file descriptor. - */ -void Logind::uninhibit(int fd) -{ - Q_D(Logind); - - if (!d->isConnected || !d->inhibitFds.contains(fd)) - return; - - ::close(fd); - d->inhibitFds.removeOne(fd); - - if (d->inhibitFds.size() == 0) - Q_EMIT inhibitedChanged(false); - Q_EMIT uninhibited(fd); -} - -/*! - * Lock the session. - * - * \sa Logind::unlockSession() - */ -void Logind::lockSession() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty()) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("Lock")); - d->bus.asyncCall(message); -} - -/*! - * Unlock the session. - * - * \sa Logind::lockSession() - */ -void Logind::unlockSession() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty()) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("Unlock")); - d->bus.asyncCall(message); -} - -/*! - * Take control of the session. No other process will be - * able to take control, until the releaaseControl() method is called. - * - * Access to video and input devices will be granted to the caller. - * - * \sa Logind::releaseControl() - */ -void Logind::takeControl() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty() || d->hasSessionControl) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("TakeControl")); - message.setArguments(QVariantList() << false); - - QDBusPendingReply result = d->bus.asyncCall(message); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this); - connect(watcher, &QDBusPendingCallWatcher::finished, this, - [d, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(gLcLogind, "Unable to take control of the session: %s", - qPrintable(reply.error().message())); - d->hasSessionControl = false; - Q_EMIT hasSessionControlChanged(d->hasSessionControl); - return; - } - - qCDebug(gLcLogind) << "Acquired control of the session"; - d->hasSessionControl = true; - Q_EMIT hasSessionControlChanged(d->hasSessionControl); - - d->bus.connect(LOGIN1_SERVICE, d->sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("PauseDevice"), - this, SIGNAL(devicePaused(quint32,quint32,QString))); - d->bus.connect(LOGIN1_SERVICE, d->sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("ResumeDevice"), - this, SIGNAL(deviceResumed(quint32,quint32,int))); - }); -} - -/*! - * Release control of the session. - * - * Access to video and input devices will be revoked from the caller. - * - * \sa Logind::takeControl() - */ -void Logind::releaseControl() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty() || !d->hasSessionControl) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("ReleaseControl")); - d->bus.asyncCall(message); - - qCDebug(gLcLogind) << "Released control of the session"; - d->hasSessionControl = false; - Q_EMIT hasSessionControlChanged(d->hasSessionControl); -} - -/*! - * Request access to the device \a fileName. - * - * \return File descriptor of the device - * - * \sa Logind::releaseDevice() - */ -int Logind::takeDevice(const QString &fileName) -{ - Q_D(Logind); - - struct stat st; - if (::stat(qPrintable(fileName), &st) < 0) { - qCWarning(gLcLogind, "Failed to stat: %s", qPrintable(fileName)); - return -1; - } - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("TakeDevice")); - message.setArguments(QVariantList() - << QVariant(major(st.st_rdev)) - << QVariant(minor(st.st_rdev))); - - // Block until the device is taken - QDBusMessage reply = d->bus.call(message); - if (reply.type() == QDBusMessage::ErrorMessage) { - qCWarning(gLcLogind, "Failed to take device \"%s\": %s", - qPrintable(fileName), qPrintable(reply.errorMessage())); - return -1; - } - - const int fd = reply.arguments().at(0).value().fileDescriptor(); - return ::fcntl(fd, F_DUPFD_CLOEXEC, 0); -} - -/* - * Revoke access to the device \a fd. - * - * \sa Logind::takeDevice() - */ -void Logind::releaseDevice(int fd) -{ - Q_D(Logind); - - struct stat st; - if (::fstat(fd, &st) < 0) { - qCWarning(gLcLogind, "Failed to stat the file descriptor"); - return; - } - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("ReleaseDevice")); - message.setArguments(QVariantList() - << QVariant(major(st.st_rdev)) - << QVariant(minor(st.st_rdev))); - - d->bus.asyncCall(message); -} - -/*! - * Allow a session-controller to synchronously pause a device - * with \a devMajor major and \a devMinor minor after receiving - * the devicePaused signal. - * - * \sa Logind::devicePaused() - */ -void Logind::pauseDeviceComplete(quint32 devMajor, quint32 devMinor) -{ - Q_D(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("PauseDeviceComplete")); - message.setArguments(QVariantList() << devMajor << devMinor); - - d->bus.asyncCall(message); -} - -/*! - * Switch to the vt number \a vt. - */ -void Logind::switchTo(quint32 vt) -{ - Q_D(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - QLatin1String("/org/freedesktop/login1/seat/self"), - LOGIN1_SEAT_INTERFACE, - QLatin1String("SwitchTo")); - message.setArguments(QVariantList() << QVariant(vt)); - - d->bus.asyncCall(message); -} - -} // namespace PlatformSupport - -} // namespace Aurora - -#include "moc_logind.cpp" diff --git a/src/platformsupport/logind/logind.h b/src/platformsupport/logind/logind.h deleted file mode 100644 index 791456c1..00000000 --- a/src/platformsupport/logind/logind.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include -#include - -#include - -namespace Aurora { - -namespace PlatformSupport { - -class LogindPrivate; - -class LIRIAURORALOGIND_EXPORT Logind : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(Logind) - Q_PROPERTY(bool connected READ isConnected NOTIFY connectedChanged) - Q_PROPERTY(bool hasSessionControl READ hasSessionControl NOTIFY hasSessionControlChanged) - Q_PROPERTY(bool sessionActive READ isSessionActive NOTIFY sessionActiveChanged) - Q_PROPERTY(bool inhibited READ isInhibited NOTIFY inhibitedChanged) - Q_PROPERTY(int vtNumber READ vtNumber NOTIFY vtNumberChanged) - Q_PROPERTY(QString seat READ seat NOTIFY seatChanged) -public: - enum InhibitFlag { - InhibitShutdown = 0x01, - InhibitSleep = 0x02, - InhibitIdle = 0x04, - InhibitPowerKey = 0x08, - InhibitSuspendKey = 0x10, - InhibitHibernateKey = 0x20, - InhibitLidSwitch = 0x40 - }; - Q_DECLARE_FLAGS(InhibitFlags, InhibitFlag) - - enum InhibitMode { - Block = 0, - Delay - }; - - ~Logind(); - - static bool checkService(); - - static Logind *instance(); - - bool isConnected() const; - bool hasSessionControl() const; - bool isSessionActive() const; - bool isInhibited() const; - int vtNumber() const; - QString seat() const; - - void setIdleHint(bool idle); - -public Q_SLOTS: - void inhibit(const QString &who, const QString &why, Logind::InhibitFlags flags, Logind::InhibitMode mode); - void uninhibit(int fd); - - void lockSession(); - void unlockSession(); - - void takeControl(); - void releaseControl(); - - int takeDevice(const QString &fileName); - void releaseDevice(int fd); - - void pauseDeviceComplete(quint32 devMajor, quint32 devMinor); - - void switchTo(quint32 vt); - -Q_SIGNALS: - void connectedChanged(bool); - void hasSessionControlChanged(bool); - void sessionActiveChanged(bool); - void inhibitedChanged(bool); - void vtNumberChanged(int); - void seatChanged(const QString &seat); - - void prepareForSleep(bool before); - void prepareForShutdown(bool before); - - void lockSessionRequested(); - void unlockSessionRequested(); - - void inhibited(const QString &who, const QString &why, - int fd); - void uninhibited(int fd); - - void devicePaused(quint32 major, quint32 minor, const QString &type); - void deviceResumed(quint32 major, quint32 minor, int fd); - -protected: - explicit Logind(const QDBusConnection &connection, QObject *parent = nullptr); - -private: - Q_DISABLE_COPY(Logind) - - LogindPrivate *const d_ptr; - - Q_PRIVATE_SLOT(d_func(), void _q_serviceRegistered()) - Q_PRIVATE_SLOT(d_func(), void _q_serviceUnregistered()) - Q_PRIVATE_SLOT(d_func(), void _q_sessionPropertiesChanged()) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(Logind::InhibitFlags) - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/logind/logind_p.h b/src/platformsupport/logind/logind_p.h deleted file mode 100644 index 93209d10..00000000 --- a/src/platformsupport/logind/logind_p.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Liri API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include - -#include "logindtypes_p.h" - -Q_DECLARE_LOGGING_CATEGORY(gLcLogind) - -namespace Aurora { - -namespace PlatformSupport { - -class Logind; - -class LogindPrivate -{ - Q_DECLARE_PUBLIC(Logind) -public: - explicit LogindPrivate(Logind *qq); - - void _q_serviceRegistered(); - void _q_serviceUnregistered(); - void _q_sessionPropertiesChanged(); - - void checkServiceRegistration(); - - QDBusConnection bus; - QDBusServiceWatcher *watcher = nullptr; - bool isConnected = false; - bool hasSessionControl = false; - QString sessionPath; - bool sessionActive = false; - int vt = -1; - QString seat; - QVector inhibitFds; - -protected: - Logind *q_ptr; - -private: - bool getSessionById(const QString &sessionId, QDBusObjectPath &path) const; - bool getSessionByPid(QDBusObjectPath &path) const; - bool getUserSession(DBusUserSession &session) const; - QString getSessionId(const QString &sessionPath) const; - QString getSessionType(const QString &sessionId, const QString &sessionPath) const; - QString getSessionState(const QString &sessionId, const QString &sessionPath) const; - - void getSessionActive(); - void getVirtualTerminal(); - void getSeat(); -}; - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/logind/logindtypes.cpp b/src/platformsupport/logind/logindtypes.cpp deleted file mode 100644 index bb804ccb..00000000 --- a/src/platformsupport/logind/logindtypes.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2019 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include "logindtypes_p.h" - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusUserSession &userSession) -{ - argument.beginStructure(); - argument << userSession.id << userSession.objectPath; - argument.endStructure(); - return argument; -} - -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusUserSession &userSession) -{ - argument.beginStructure(); - argument >> userSession.id >> userSession.objectPath; - argument.endStructure(); - return argument; -} - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusSeat &seat) -{ - argument.beginStructure(); - argument << seat.id << seat.objectPath; - argument.endStructure(); - return argument; -} - -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusSeat &seat) -{ - argument.beginStructure(); - argument >> seat.id >> seat.objectPath; - argument.endStructure(); - return argument; -} diff --git a/src/platformsupport/logind/logindtypes_p.h b/src/platformsupport/logind/logindtypes_p.h deleted file mode 100644 index 673d47f7..00000000 --- a/src/platformsupport/logind/logindtypes_p.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2019 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include -#include -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Liri API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -class DBusUserSession -{ -public: - QString id; - QDBusObjectPath objectPath; -}; -Q_DECLARE_METATYPE(DBusUserSession) - -typedef QVector DBusUserSessionVector; -Q_DECLARE_METATYPE(DBusUserSessionVector) - -class DBusSeat -{ -public: - QString id; - QDBusObjectPath objectPath; -}; -Q_DECLARE_METATYPE(DBusSeat) - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusUserSession &userSession); -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusUserSession &userSession); - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusSeat &seat); -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusSeat &seat); - diff --git a/src/platformsupport/udev/CMakeLists.txt b/src/platformsupport/udev/CMakeLists.txt deleted file mode 100644 index 17daa4de..00000000 --- a/src/platformsupport/udev/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_module(AuroraUdev - DESCRIPTION - "Qt style API for udev" - SOURCES - udev.cpp udev.h udev_p.h - udevdevice.cpp udevdevice.h udevdevice_p.h - udevenumerate.cpp udevenumerate.h udevenumerate_p.h - udevmonitor.cpp udevmonitor.h udevmonitor_p.h - DEFINES - QT_NO_CAST_FROM_ASCII - QT_NO_FOREACH - PUBLIC_LIBRARIES - Qt::Core - Qt::DBus - Liri::AuroraLogind - PkgConfig::Libudev - NO_CMAKE - NO_PKGCONFIG -) - -liri_finalize_module(AuroraUdev) diff --git a/src/platformsupport/udev/qtudevglobal.h b/src/platformsupport/udev/qtudevglobal.h deleted file mode 100644 index 82089b3b..00000000 --- a/src/platformsupport/udev/qtudevglobal.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -#if defined(LIRI_BUILD_QTUDEV_LIB) -# define QTUDEV_EXPORT Q_DECL_EXPORT -#else -# define QTUDEV_EXPORT Q_DECL_IMPORT -#endif -#define QTUDEV_NO_EXPORT Q_DECL_HIDDEN - diff --git a/src/platformsupport/udev/udev.cpp b/src/platformsupport/udev/udev.cpp deleted file mode 100644 index cdafd0d6..00000000 --- a/src/platformsupport/udev/udev.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include "udev.h" -#include "udev_p.h" -#include "udevdevice.h" - -Q_LOGGING_CATEGORY(gLcUdev, "aurora.udev") - -namespace Aurora { - -namespace PlatformSupport { - -/* - * UdevPrivate - */ - -UdevPrivate::UdevPrivate() -{ - udev = udev_new(); - if (!udev) - qCWarning(gLcUdev, "Unable to get udev library context: no devices can be detected"); -} - -UdevPrivate::~UdevPrivate() -{ - if (udev) - udev_unref(udev); -} - -UdevPrivate *UdevPrivate::get(Udev *u) -{ - return u ? u->d_func() : nullptr; -} - -/* - * Udev - */ - -Udev::Udev() - : d_ptr(new UdevPrivate) -{ -} - -Udev::~Udev() -{ - delete d_ptr; -} - -bool Udev::isValid() const -{ - Q_D(const Udev); - return d->udev; -} - -UdevDevice *Udev::deviceFromFileName(const QString &fileName) const -{ - Q_D(const Udev); - - if (!isValid()) - return nullptr; - - QT_STATBUF sb; - - if (QT_STAT(qPrintable(fileName), &sb) != 0) - return nullptr; - - udev_device *dev = nullptr; - - if (S_ISBLK(sb.st_mode)) - dev = udev_device_new_from_devnum(d->udev, 'b', sb.st_rdev); - else if (S_ISCHR(sb.st_mode)) - dev = udev_device_new_from_devnum(d->udev, 'c', sb.st_rdev); - - if (!dev) - return nullptr; - - UdevDevice *device = new UdevDevice; - device->initialize(dev); - return device; -} - -UdevDevice *Udev::deviceFromSubSystemAndName(const QString &subSystem, const QString &name) const -{ - Q_D(const Udev); - - if (!isValid()) - return nullptr; - - udev_device *dev = udev_device_new_from_subsystem_sysname(d->udev, - qPrintable(subSystem), - qPrintable(name)); - UdevDevice *device = new UdevDevice; - device->initialize(dev); - return device; -} - -UdevDevice *Udev::deviceFromSysfsPath(const QString &sysfsPath) const -{ - Q_D(const Udev); - - if (!isValid()) - return nullptr; - - udev_device *dev = udev_device_new_from_syspath(d->udev, qPrintable(sysfsPath)); - UdevDevice *device = new UdevDevice; - device->initialize(dev); - return device; -} - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/udev/udev.h b/src/platformsupport/udev/udev.h deleted file mode 100644 index 16b27f9a..00000000 --- a/src/platformsupport/udev/udev.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -#include - -namespace Aurora { - -namespace PlatformSupport { - -class UdevDevice; -class UdevPrivate; - -class LIRIAURORAUDEV_EXPORT Udev -{ - Q_DECLARE_PRIVATE(Udev) -public: - Udev(); - ~Udev(); - - bool isValid() const; - - UdevDevice *deviceFromFileName(const QString &fileName) const; - UdevDevice *deviceFromSubSystemAndName(const QString &subSystem, const QString &name) const; - UdevDevice *deviceFromSysfsPath(const QString &sysfsPath) const; - -private: - UdevPrivate *const d_ptr; -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/udev/udev_p.h b/src/platformsupport/udev/udev_p.h deleted file mode 100644 index 3e700bff..00000000 --- a/src/platformsupport/udev/udev_p.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QtUdev. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#include - -extern "C" { -#include -} - -Q_DECLARE_LOGGING_CATEGORY(gLcUdev) - -namespace Aurora { - -namespace PlatformSupport { - -class Udev; - -class LIRIAURORAUDEV_EXPORT UdevPrivate -{ -public: - UdevPrivate(); - ~UdevPrivate(); - - static UdevPrivate *get(Udev *u); - - struct udev *udev; -}; - -} // namespace PlatformSupport - -} // namespace Aurora - - diff --git a/src/platformsupport/udev/udevdevice.cpp b/src/platformsupport/udev/udevdevice.cpp deleted file mode 100644 index 40ebe997..00000000 --- a/src/platformsupport/udev/udevdevice.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include "udev_p.h" -#include "udevdevice.h" -#include "udevdevice_p.h" - -namespace Aurora { - -namespace PlatformSupport { - -static inline QStringList listFromEntries(udev_list_entry *l) -{ - QStringList list; - udev_list_entry *entry; - - udev_list_entry_foreach(entry, l) { - list.append(QString::fromUtf8(udev_list_entry_get_name(entry))); - } - - return list; -} - -/* - * UdevDevicePrivate - */ - -UdevDevicePrivate::UdevDevicePrivate() -{ -} - -UdevDevicePrivate::~UdevDevicePrivate() -{ - if (device) - udev_device_unref(device); -} - -/* - * UdevDevice - */ - -UdevDevice::UdevDevice() - : d_ptr(new UdevDevicePrivate) -{ -} - -UdevDevice::~UdevDevice() -{ - delete d_ptr; -} - -bool UdevDevice::isValid() const -{ - Q_D(const UdevDevice); - return d->device != nullptr; -} - -UdevDevice::DeviceTypes UdevDevice::type() const -{ - Q_D(const UdevDevice); - - DeviceTypes result; - - if (!d->device) - return result; - - if (qstrcmp(udev_device_get_property_value(d->device, "ID_INPUT_KEYBOARD"), "1") == 0) - result |= KeyboardDevice; - if (qstrcmp(udev_device_get_property_value(d->device, "ID_INPUT_KEY"), "1") == 0) - result |= KeyboardDevice; - - if (qstrcmp(udev_device_get_property_value(d->device, "ID_INPUT_MOUSE"), "1") == 0) - result |= MouseDevice; - - if (qstrcmp(udev_device_get_property_value(d->device, "ID_INPUT_TOUCHPAD"), "1") == 0) - result |= TouchpadDevice; - - if (qstrcmp(udev_device_get_property_value(d->device, "ID_INPUT_TOUCHSCREEN"), "1") == 0) - result |= TouchscreenDevice; - - if (qstrcmp(udev_device_get_property_value(d->device, "ID_INPUT_TABLET"), "1") == 0) - result |= TabletDevice; - - if (qstrcmp(udev_device_get_property_value(d->device, "ID_INPUT_JOYSTICK"), "1") == 0) - result |= JoystickDevice; - - if (qstrcmp(udev_device_get_subsystem(d->device), "drm") == 0) { - bool isSet = false; - - udev_device *pci = - udev_device_get_parent_with_subsystem_devtype(d->device, "pci", nullptr); - if (pci) { - if (qstrcmp(udev_device_get_sysattr_value(pci, "boot_vga"), "1") == 0) { - result |= PrimaryVideoDevice; - isSet = true; - } - } - - if (!isSet) - result |= GenericVideoDevice; - } - - return result; -} - -QString UdevDevice::subsystem() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QString(); - return QString::fromUtf8(udev_device_get_subsystem(d->device)); -} - -QString UdevDevice::devType() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QString(); - return QString::fromUtf8(udev_device_get_devtype(d->device)); -} - -QString UdevDevice::name() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QString(); - return QString::fromUtf8(udev_device_get_sysname(d->device)); -} - -QString UdevDevice::driver() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QString(); - return QString::fromUtf8(udev_device_get_driver(d->device)); -} - -QString UdevDevice::deviceNode() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QString(); - return QString::fromUtf8(udev_device_get_devnode(d->device)); -} - -QStringList UdevDevice::alternateDeviceSymlinks() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QStringList(); - return listFromEntries(udev_device_get_devlinks_list_entry(d->device)); -} - -QString UdevDevice::sysfsPath() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QString(); - return QString::fromUtf8(udev_device_get_syspath(d->device)); -} - -int UdevDevice::sysfsNumber() const -{ - Q_D(const UdevDevice); - if (!d->device) - return -1; - return QByteArray(udev_device_get_sysnum(d->device)).toInt(); -} - -QString UdevDevice::property(const QString &name) const -{ - Q_D(const UdevDevice); - if (!d->device) - return QString(); - return QString::fromLatin1(udev_device_get_property_value(d->device, name.toLatin1().constData())); -} - -bool UdevDevice::hasProperty(const QString &name) const -{ - Q_D(const UdevDevice); - if (!d->device) - return false; - return udev_device_get_property_value(d->device, name.toLatin1().constData()) != nullptr; -} - -QStringList UdevDevice::deviceProperties() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QStringList(); - return listFromEntries(udev_device_get_properties_list_entry(d->device)); -} - -QStringList UdevDevice::sysfsProperties() const -{ - Q_D(const UdevDevice); - if (!d->device) - return QStringList(); - return listFromEntries(udev_device_get_sysattr_list_entry(d->device)); -} - -UdevDevice *UdevDevice::parent() const -{ - Q_D(const UdevDevice); - - if (!d->device) - return nullptr; - - udev_device *p = udev_device_get_parent(d->device); - if (p) { - UdevDevice *parentDevice = new UdevDevice; - parentDevice->d_ptr->device = p; - return parentDevice; - } - return nullptr; -} - -void UdevDevice::initialize(udev_device *dev) -{ - Q_D(UdevDevice); - d->device = dev; -} - -QDebug operator<<(QDebug dbg, const UdevDevice &device) -{ - QDebugStateSaver saver(dbg); - if (device.isValid()) - dbg.nospace() << "UdevDevice(" << device.deviceNode() << ')'; - else - dbg.nospace() << "Invalid UdevDevice)"; - return dbg; -} - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/udev/udevdevice.h b/src/platformsupport/udev/udevdevice.h deleted file mode 100644 index b129be35..00000000 --- a/src/platformsupport/udev/udevdevice.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -#include - -struct udev_device; - -namespace Aurora { - -namespace PlatformSupport { - -class Udev; -class UdevEnumerate; -class UdevDevicePrivate; -class UdevMonitorPrivate; - -class LIRIAURORAUDEV_EXPORT UdevDevice -{ - Q_DECLARE_PRIVATE(UdevDevice) -public: - enum DeviceType { - UnknownDevice = 0x00, - KeyboardDevice = 0x01, - MouseDevice = 0x02, - TouchpadDevice = 0x04, - TouchscreenDevice = 0x08, - TabletDevice = 0x10, - JoystickDevice = 0x20, - GenericVideoDevice = 0x40, - PrimaryVideoDevice = 0x80, - InputDevice_Mask = KeyboardDevice | MouseDevice | TouchpadDevice | TouchscreenDevice | TabletDevice | JoystickDevice, - VideoDevice_Mask = GenericVideoDevice - }; - Q_DECLARE_FLAGS(DeviceTypes, DeviceType) - - explicit UdevDevice(); - ~UdevDevice(); - - bool isValid() const; - - DeviceTypes type() const; - - QString subsystem() const; - QString devType() const; - QString name() const; - QString driver() const; - - QString deviceNode() const; - QStringList alternateDeviceSymlinks() const; - - QString sysfsPath() const; - int sysfsNumber() const; - - QString property(const QString &name) const; - bool hasProperty(const QString &name) const; - - QStringList deviceProperties() const; - QStringList sysfsProperties() const; - - UdevDevice *parent() const; - -private: - void initialize(udev_device *dev); - - UdevDevicePrivate *const d_ptr; - - friend class Udev; - friend class UdevEnumerate; - friend class UdevMonitorPrivate; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(UdevDevice::DeviceTypes) - -QDebug operator<<(QDebug, const UdevDevice &); - -} // namespace PlatformSupport - -} // namespace Aurora - -Q_DECLARE_METATYPE(Aurora::PlatformSupport::UdevDevice) - diff --git a/src/platformsupport/udev/udevdevice_p.h b/src/platformsupport/udev/udevdevice_p.h deleted file mode 100644 index 983dc828..00000000 --- a/src/platformsupport/udev/udevdevice_p.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QtUdev. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -extern "C" { -#include -} - -namespace Aurora { - -namespace PlatformSupport { - -class UdevDevicePrivate -{ -public: - UdevDevicePrivate(); - ~UdevDevicePrivate(); - - udev_device *device = nullptr; -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/udev/udevenumerate.cpp b/src/platformsupport/udev/udevenumerate.cpp deleted file mode 100644 index cec4f7b9..00000000 --- a/src/platformsupport/udev/udevenumerate.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include "udev.h" -#include "udev_p.h" -#include "udevenumerate.h" -#include "udevenumerate_p.h" - -namespace Aurora { - -namespace PlatformSupport { - -/* - * UdevEnumeratePrivate - */ - -UdevEnumeratePrivate::UdevEnumeratePrivate(UdevDevice::DeviceTypes t, Udev *u) - : types(t) - , udev(u) -{ - enumerate = udev_enumerate_new(UdevPrivate::get(u)->udev); - if (!enumerate) { - qCWarning(gLcUdev, "Unable to enumerate connected devices"); - return; - } - - if (types.testFlag(UdevDevice::InputDevice_Mask)) - udev_enumerate_add_match_subsystem(enumerate, "input"); - - if (types.testFlag(UdevDevice::VideoDevice_Mask)) { - udev_enumerate_add_match_subsystem(enumerate, "drm"); - udev_enumerate_add_match_sysname(enumerate, "card[0-9]*"); - } - - if (types.testFlag(UdevDevice::KeyboardDevice)) { - udev_enumerate_add_match_property(enumerate, "ID_INPUT_KEYBOARD", "1"); - udev_enumerate_add_match_property(enumerate, "ID_INPUT_KEY", "1"); - } - - if (types.testFlag(UdevDevice::MouseDevice)) - udev_enumerate_add_match_property(enumerate, "ID_INPUT_MOUSE", "1"); - - if (types.testFlag(UdevDevice::TouchpadDevice)) - udev_enumerate_add_match_property(enumerate, "ID_INPUT_TOUCHPAD", "1"); - - if (types.testFlag(UdevDevice::TouchscreenDevice)) - udev_enumerate_add_match_property(enumerate, "ID_INPUT_TOUCHSCREEN", "1"); - - if (types.testFlag(UdevDevice::TabletDevice)) - udev_enumerate_add_match_property(enumerate, "ID_INPUT_TABLET", "1"); - - if (types.testFlag(UdevDevice::JoystickDevice)) - udev_enumerate_add_match_property(enumerate, "ID_INPUT_JOYSTICK", "1"); -} - -UdevEnumeratePrivate::~UdevEnumeratePrivate() -{ - if (enumerate) - udev_enumerate_unref(enumerate); -} - -/* - * UdevEnumerate - */ - -UdevEnumerate::UdevEnumerate(UdevDevice::DeviceTypes types, Udev *udev) - : d_ptr(new UdevEnumeratePrivate(types, udev)) -{ - qRegisterMetaType(); -} - -UdevEnumerate::~UdevEnumerate() -{ - delete d_ptr; -} - -QList UdevEnumerate::scan() const -{ - Q_D(const UdevEnumerate); - - QList list; - - if (!d->enumerate) - return list; - - if (udev_enumerate_scan_devices(d->enumerate) != 0) { - qCWarning(gLcUdev, "Unable to enumerate connected devices"); - return list; - } - - udev_device *drmDevice = nullptr; - udev_device *drmPrimaryDevice = nullptr; - - udev_list_entry *entry; - udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(d->enumerate)) { - const char *syspath = udev_list_entry_get_name(entry); - udev_device *dev = udev_device_new_from_syspath(UdevPrivate::get(d->udev)->udev, syspath); - if (!dev) - continue; - - // Must be on the same seat - QString seat = QString::fromUtf8(udev_device_get_property_value(dev, "ID_SEAT")); - if (seat.isEmpty()) - seat = QStringLiteral("seat0"); - if (seat != Logind::instance()->seat()) { - udev_device_unref(dev); - continue; - } - - QString node = QString::fromUtf8(udev_device_get_devnode(dev)); - - if (d->types.testFlag(UdevDevice::InputDevice_Mask) && node.startsWith(QLatin1String("/dev/input/event"))) { - UdevDevice *device = new UdevDevice; - device->initialize(dev); - list.append(device); - } - - if (d->types.testFlag(UdevDevice::VideoDevice_Mask) && node.startsWith(QLatin1String("/dev/dri/card"))) { - // We can have more than one DRM device on our seat, so the filter - // might want us to pick up only the primary video device - // In any case we'll be adding just one DRM device to the list - if (d->types.testFlag(UdevDevice::PrimaryVideoDevice)) { - udev_device *pci = - udev_device_get_parent_with_subsystem_devtype(dev, "pci", nullptr); - if (pci) { - if (qstrcmp(udev_device_get_sysattr_value(pci, "boot_vga"), "1") == 0) - drmPrimaryDevice = dev; - } - } - if (!drmPrimaryDevice) { - if (drmDevice) - udev_device_unref(drmDevice); - drmDevice = dev; - } - } - } - - // Add any DRM device previously enumerated - if (drmPrimaryDevice) { - UdevDevice *device = new UdevDevice; - device->initialize(drmPrimaryDevice); - list.append(device); - } else if (drmDevice) { - UdevDevice *device = new UdevDevice; - device->initialize(drmDevice); - list.append(device); - } - - return list; -} - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/platformsupport/udev/udevenumerate.h b/src/platformsupport/udev/udevenumerate.h deleted file mode 100644 index 5df61ff2..00000000 --- a/src/platformsupport/udev/udevenumerate.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -namespace Aurora { - -namespace PlatformSupport { - -class UdevEnumeratePrivate; - -class LIRIAURORAUDEV_EXPORT UdevEnumerate -{ - Q_DECLARE_PRIVATE(UdevEnumerate) -public: - UdevEnumerate(UdevDevice::DeviceTypes types, Udev *udev); - ~UdevEnumerate(); - - QList scan() const; - -private: - UdevEnumeratePrivate *const d_ptr; -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/udev/udevenumerate_p.h b/src/platformsupport/udev/udevenumerate_p.h deleted file mode 100644 index b05f792c..00000000 --- a/src/platformsupport/udev/udevenumerate_p.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QtUdev. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "udevdevice.h" - -extern "C" { -#include -} - -namespace Aurora { - -namespace PlatformSupport { - -class UdevEnumeratePrivate -{ -public: - UdevEnumeratePrivate(UdevDevice::DeviceTypes t, Udev *u); - ~UdevEnumeratePrivate(); - - UdevDevice::DeviceTypes types; - Udev *udev; - udev_enumerate *enumerate; -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/udev/udevmonitor.cpp b/src/platformsupport/udev/udevmonitor.cpp deleted file mode 100644 index 14d41192..00000000 --- a/src/platformsupport/udev/udevmonitor.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include "udev.h" -#include "udev_p.h" -#include "udevdevice.h" -#include "udevmonitor.h" -#include "udevmonitor_p.h" - -namespace Aurora { - -namespace PlatformSupport { - -/* - * UdevMonitorPrivate - */ - -UdevMonitorPrivate::UdevMonitorPrivate(UdevMonitor *qq, Udev *u) - : udev(u) - , monitor(nullptr) - , q_ptr(qq) -{ - monitor = udev_monitor_new_from_netlink(UdevPrivate::get(u)->udev, "udev"); - if (!monitor) { - qCWarning(gLcUdev, "Unable to create an udev monitor: no devices can be detected"); - return; - } - - udev_monitor_enable_receiving(monitor); -} - -UdevMonitorPrivate::~UdevMonitorPrivate() -{ - if (monitor) - udev_monitor_unref(monitor); -} - -void UdevMonitorPrivate::_q_udevEventHandler() -{ - Q_Q(UdevMonitor); - - udev_device *dev = udev_monitor_receive_device(monitor); - if (!dev) - return; - - const char *action = udev_device_get_action(dev); - if (!action) { - udev_device_unref(dev); - return; - } - - UdevDevice device; - device.initialize(dev); - - if (strcmp(action, "add") == 0) - Q_EMIT q->deviceAdded(device); - else if (strcmp(action, "remove") == 0) - Q_EMIT q->deviceRemoved(device); - else if (strcmp(action, "change") == 0) - Q_EMIT q->deviceChanged(device); - else if (strcmp(action, "online") == 0) - Q_EMIT q->deviceOnlined(device); - else if (strcmp(action, "offline") == 0) - Q_EMIT q->deviceOfflined(device); -} - -/* - * UdevMonitor - */ - -UdevMonitor::UdevMonitor(Udev *udev, QObject *parent) - : QObject(parent) - , d_ptr(new UdevMonitorPrivate(this, udev)) -{ - qRegisterMetaType(); - - Q_D(UdevMonitor); - int fd = udev_monitor_get_fd(d->monitor); - QSocketNotifier *notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)), this, SLOT(_q_udevEventHandler())); -} - -UdevMonitor::~UdevMonitor() -{ - delete d_ptr; -} - -bool UdevMonitor::isValid() const -{ - Q_D(const UdevMonitor); - return d->monitor; -} - -void UdevMonitor::filterSubSystemDevType(const QString &subSystem, const QString &devType) -{ - Q_D(UdevMonitor); - - if (!isValid()) - return; - - udev_monitor_filter_add_match_subsystem_devtype(d->monitor, - qPrintable(subSystem), - qPrintable(devType)); -} - -void UdevMonitor::filterTag(const QString &tag) -{ - Q_D(UdevMonitor); - - if (!isValid()) - return; - - udev_monitor_filter_add_match_tag(d->monitor, qPrintable(tag)); -} - -} // namespace PlatformSupport - -} // namespace Aurora - -#include "moc_udevmonitor.cpp" diff --git a/src/platformsupport/udev/udevmonitor.h b/src/platformsupport/udev/udevmonitor.h deleted file mode 100644 index 11145897..00000000 --- a/src/platformsupport/udev/udevmonitor.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -#include - -namespace Aurora { - -namespace PlatformSupport { - -class Udev; -class UdevDevice; -class UdevMonitorPrivate; - -class LIRIAURORAUDEV_EXPORT UdevMonitor : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(UdevMonitor) -public: - explicit UdevMonitor(Udev *udev, QObject *parent = nullptr); - ~UdevMonitor(); - - bool isValid() const; - - void filterSubSystemDevType(const QString &subSystem, const QString &devType); - void filterTag(const QString &tag); - -Q_SIGNALS: - void deviceAdded(const Aurora::PlatformSupport::UdevDevice &device); - void deviceRemoved(const Aurora::PlatformSupport::UdevDevice &device); - void deviceChanged(const Aurora::PlatformSupport::UdevDevice &device); - void deviceOnlined(const Aurora::PlatformSupport::UdevDevice &device); - void deviceOfflined(const Aurora::PlatformSupport::UdevDevice &device); - -private: - UdevMonitorPrivate *const d_ptr; - - Q_PRIVATE_SLOT(d_func(), void _q_udevEventHandler()) -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/platformsupport/udev/udevmonitor_p.h b/src/platformsupport/udev/udevmonitor_p.h deleted file mode 100644 index c72b0e6b..00000000 --- a/src/platformsupport/udev/udevmonitor_p.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the QtUdev. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "udevmonitor.h" - -namespace Aurora { - -namespace PlatformSupport { - -class UdevMonitorPrivate -{ - Q_DECLARE_PUBLIC(UdevMonitor) -public: - UdevMonitorPrivate(UdevMonitor *qq, Udev *u); - ~UdevMonitorPrivate(); - - void _q_udevEventHandler(); - - Udev *udev; - struct udev_monitor *monitor; - -protected: - UdevMonitor *q_ptr; -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/plugins/platforms/eglfs/CMakeLists.txt b/src/plugins/platforms/eglfs/CMakeLists.txt deleted file mode 100644 index a0f6fc8f..00000000 --- a/src/plugins/platforms/eglfs/CMakeLists.txt +++ /dev/null @@ -1,99 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_module(EglFSDeviceIntegration - DESCRIPTION - "EGL device integration" - SOURCES - api/libinputmanager.cpp - api/libinputmanager_p.h - api/qeglfscontext.cpp - api/qeglfscontext_p.h - api/qeglfscursor.cpp - api/qeglfscursor_p.h - api/qeglfsdeviceintegration.cpp - api/qeglfsdeviceintegration_p.h - api/qeglfsglobal_p.h - api/qeglfshooks.cpp - api/qeglfshooks_p.h - api/qeglfsintegration.cpp - api/qeglfsintegration_p.h - api/qeglfslogindhandler.cpp - api/qeglfslogindhandler_p.h - api/qeglfsoffscreenwindow.cpp - api/qeglfsoffscreenwindow_p.h - api/qeglfsscreen.cpp - api/qeglfsscreen_p.h - api/qeglfswindow.cpp - api/qeglfswindow_p.h - api/vthandler.cpp - api/vthandler.h - api/vthandler_p.h - api/xcursor.c - api/xcursor.h - api/xcursortheme.cpp - api/xcursortheme_p.h - PRIVATE_HEADERS - api/libinputmanager_p.h - api/qeglfscontext_p.h - api/qeglfscursor_p.h - api/qeglfsdeviceintegration_p.h - api/qeglfshooks_p.h - api/qeglfsintegration_p.h - api/qeglfslogindhandler_p.h - api/qeglfsoffscreenwindow_p.h - api/qeglfsscreen_p.h - api/qeglfswindow_p.h - api/vthandler_p.h - api/xcursortheme_p.h - DEFINES - QT_NO_CAST_FROM_ASCII - #QT_NO_FOREACH - ${DEFINES} - RESOURCES - cursor.qrc - PUBLIC_INCLUDE_DIRECTORIES - "$" - PUBLIC_DEFINES - QT_EGL_NO_X11 - PUBLIC_LIBRARIES - Qt5::CorePrivate - Qt5::GuiPrivate - Qt5FontDatabaseSupport::Qt5FontDatabaseSupport - Qt5ThemeSupport::Qt5ThemeSupport - Qt5EventDispatcherSupport::Qt5EventDispatcherSupport - Qt5EglSupport::Qt5EglSupport - Qt5PlatformCompositorSupport::Qt5PlatformCompositorSupport - Qt5ServiceSupport::Qt5ServiceSupport - Qt5FbSupport::Qt5FbSupport - Liri::AuroraLibInput - Liri::AuroraLibInputPrivate - Liri::AuroraPlatformHeaders - Liri::AuroraUdev - Liri::AuroraLogind - PkgConfig::EGL - EXPORT_IMPORT_CONDITION - QT_BUILD_EGL_DEVICE_LIB - NO_CMAKE - NO_PKGCONFIG -) - -liri_extend_target(EglFSDeviceIntegration CONDITION FEATURE_aurora_drm_atomic - DEFINES - EGLFS_ENABLE_DRM_ATOMIC -) - -liri_finalize_module(EglFSDeviceIntegration) - -liri_add_plugin(aurora-eglfs - TYPE - platforms - SOURCES - qeglfsmain.cpp - LIBRARIES - Liri::EglFSDeviceIntegration - Fontconfig::Fontconfig -) - -liri_finalize_plugin(aurora-eglfs) diff --git a/src/plugins/platforms/eglfs/api/libinputmanager.cpp b/src/plugins/platforms/eglfs/api/libinputmanager.cpp deleted file mode 100644 index 2e1438a6..00000000 --- a/src/plugins/platforms/eglfs/api/libinputmanager.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include -#include - -#include - -#include "libinputmanager_p.h" - -namespace Aurora { - -namespace PlatformSupport { - -LibInputManager::LibInputManager(QObject *parent) - : QObject(parent) - , m_handler(new LibInputHandler(this)) -{ - QInputDeviceManager *inputManager = - QGuiApplicationPrivate::inputDeviceManager(); - QInputDeviceManagerPrivate *inputManagerPriv - = QInputDeviceManagerPrivate::get(inputManager); - - // Set existing device count - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeKeyboard, - m_handler->keyboardCount()); - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypePointer, - m_handler->pointerCount()); - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeTouch, - m_handler->touchCount()); - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeTablet, - m_handler->tabletCount()); - - // Tell QPA about input devices - connect(m_handler, &LibInputHandler::keyboardCountChanged, this, - [inputManagerPriv](int count) { - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeKeyboard, - count); - }); - connect(m_handler, &LibInputHandler::pointerCountChanged, this, - [inputManagerPriv](int count) { - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypePointer, - count); - }); - connect(m_handler, &LibInputHandler::touchCountChanged, this, - [inputManagerPriv](int count) { - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeTouch, - count); - }); - connect(m_handler, &LibInputHandler::tabletCountChanged, this, - [inputManagerPriv](int count) { - inputManagerPriv->setDeviceCount(QInputDeviceManager::DeviceTypeTablet, - count); - }); - connect(m_handler, &LibInputHandler::touchDeviceRegistered, this, - [](QTouchDevice *td) { - QWindowSystemInterface::registerTouchDevice(td); - }); - - // Events - connect(m_handler, &LibInputHandler::keyPressed, this, - [](const LibInputKeyEvent &e) { - QWindowSystemInterface::handleExtendedKeyEvent( - nullptr, QKeyEvent::KeyPress, e.key, - e.modifiers, e.nativeScanCode, - e.nativeVirtualKey, e.nativeModifiers, - e.text, e.autoRepeat, e.repeatCount); - }); - connect(m_handler, &LibInputHandler::keyReleased, this, - [](const LibInputKeyEvent &e) { - QWindowSystemInterface::handleExtendedKeyEvent( - nullptr, QKeyEvent::KeyRelease, e.key, - e.modifiers, e.nativeScanCode, - e.nativeVirtualKey, e.nativeModifiers, - e.text, e.autoRepeat, e.repeatCount); - }); - connect(m_handler, &LibInputHandler::mousePressed, this, - [](const LibInputMouseEvent &e) { - QWindowSystemInterface::handleMouseEvent( - nullptr, e.pos, e.pos, e.buttons, - e.button, QEvent::MouseButtonPress, - e.modifiers); - }); - connect(m_handler, &LibInputHandler::mouseReleased, this, - [](const LibInputMouseEvent &e) { - QWindowSystemInterface::handleMouseEvent( - nullptr, e.pos, e.pos, e.buttons, - e.button, QEvent::MouseButtonRelease, - e.modifiers); - }); - connect(m_handler, &LibInputHandler::mouseMoved, this, - [](const LibInputMouseEvent &e) { - QWindowSystemInterface::handleMouseEvent( - nullptr, e.pos, e.pos, e.buttons, - Qt::NoButton, QEvent::MouseMove, - e.modifiers); - }); - connect(m_handler, &LibInputHandler::mouseWheel, this, - [](const LibInputMouseEvent &e) { - QWindowSystemInterface::handleWheelEvent( - nullptr, e.pos, e.pos, - QPoint(), e.wheelDelta, - e.modifiers); - }); - connect(m_handler, &LibInputHandler::touchEvent, this, - [](const LibInputTouchEvent &e) { - QWindowSystemInterface::handleTouchEvent( - nullptr, e.device, e.touchPoints, - e.modifiers); - }); - connect(m_handler, &LibInputHandler::touchCancel, this, - [](const LibInputTouchEvent &e) { - QWindowSystemInterface::handleTouchCancelEvent( - nullptr, e.device, e.modifiers); - }); - - // Change pointer coordinates when requested by QPA - connect(inputManager, &QInputDeviceManager::cursorPositionChangeRequested, this, - [this](const QPoint &pos) { - m_handler->setPointerPosition(pos); - }); -} - -LibInputHandler *LibInputManager::handler() const -{ - return m_handler; -} - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/plugins/platforms/eglfs/api/libinputmanager_p.h b/src/plugins/platforms/eglfs/api/libinputmanager_p.h deleted file mode 100644 index e9d1733d..00000000 --- a/src/plugins/platforms/eglfs/api/libinputmanager_p.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Liri LibInput API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -namespace Aurora { - -namespace PlatformSupport { - -class LibInputHandler; - -class LibInputManager : public QObject -{ - Q_OBJECT -public: - explicit LibInputManager(QObject *parent = nullptr); - - LibInputHandler *handler() const; - -private: - LibInputHandler *m_handler; -}; - -} // namespace PlatformSupport - -} // namespace Aurora - diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp deleted file mode 100644 index 48fafbda..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfsglobal_p.h" -#include -#include -#include - -#include "qeglfscontext_p.h" -#include "qeglfswindow_p.h" -#include "qeglfshooks_p.h" -#include "qeglfscursor_p.h" - -QT_BEGIN_NAMESPACE - -QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLConfig *config, const QVariant &nativeHandle) - : QEGLPlatformContext(format, share, display, config, nativeHandle, - qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags() : QEGLPlatformContext::NoSurfaceless), - m_tempWindow(0) -{ -} - -EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) -{ - if (surface->surface()->surfaceClass() == QSurface::Window) - return static_cast(surface)->surface(); - else - return static_cast(surface)->pbuffer(); -} - -EGLSurface QEglFSContext::createTemporaryOffscreenSurface() -{ - if (qt_egl_device_integration()->supportsPBuffers()) - return QEGLPlatformContext::createTemporaryOffscreenSurface(); - - if (!m_tempWindow) { - m_tempWindow = qt_egl_device_integration()->createNativeOffscreenWindow(format()); - if (!m_tempWindow) { - qWarning("QEglFSContext: Failed to create temporary native window"); - return EGL_NO_SURFACE; - } - } - EGLConfig config = q_configFromGLFormat(eglDisplay(), format()); - return eglCreateWindowSurface(eglDisplay(), config, m_tempWindow, nullptr); -} - -void QEglFSContext::destroyTemporaryOffscreenSurface(EGLSurface surface) -{ - if (qt_egl_device_integration()->supportsPBuffers()) { - QEGLPlatformContext::destroyTemporaryOffscreenSurface(surface); - } else { - eglDestroySurface(eglDisplay(), surface); - qt_egl_device_integration()->destroyNativeWindow(m_tempWindow); - m_tempWindow = 0; - } -} - -void QEglFSContext::runGLChecks() -{ - // Note that even though there is an EGL context current here, - // QOpenGLContext and QOpenGLFunctions are not yet usable at this stage. - const char *renderer = reinterpret_cast(glGetString(GL_RENDERER)); - // Be nice and warn about a common source of confusion. - if (renderer && strstr(renderer, "llvmpipe")) - qWarning("Running on a software rasterizer (LLVMpipe), expect limited performance."); -} - -void QEglFSContext::swapBuffers(QPlatformSurface *surface) -{ - // draw the cursor - if (surface->surface()->surfaceClass() == QSurface::Window) { - QPlatformWindow *window = static_cast(surface); - if (QEglFSCursor *cursor = qobject_cast(window->screen()->cursor())) - cursor->paintOnScreen(); - } - - qt_egl_device_integration()->waitForVSync(surface); - QEGLPlatformContext::swapBuffers(surface); - qt_egl_device_integration()->presentBuffer(surface); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h deleted file mode 100644 index 3467a98f..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include "qeglfscursor_p.h" -#include -#include - -QT_BEGIN_NAMESPACE - -class Q_EGLFS_EXPORT QEglFSContext : public QEGLPlatformContext -{ -public: - QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLConfig *config, const QVariant &nativeHandle); - EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override; - EGLSurface createTemporaryOffscreenSurface() override; - void destroyTemporaryOffscreenSurface(EGLSurface surface) override; - void runGLChecks() override; - void swapBuffers(QPlatformSurface *surface) override; - - QEglFSCursorData cursorData; - -private: - EGLNativeWindowType m_tempWindow; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp deleted file mode 100644 index 404fa0aa..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp +++ /dev/null @@ -1,578 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfscursor_p.h" -#include "qeglfsintegration_p.h" -#include "qeglfsscreen_p.h" -#include "qeglfscontext_p.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef GL_VERTEX_ARRAY_BINDING -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#endif - -QT_BEGIN_NAMESPACE - -QEglFSCursor::QEglFSCursor(QPlatformScreen *screen) - : m_visible(true), - m_screen(static_cast(screen)), - m_activeScreen(nullptr), - m_deviceListener(nullptr), - m_updateRequested(false) -{ - QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); - if (!hideCursorVal.isEmpty()) - m_visible = hideCursorVal.toInt() == 0; - if (!m_visible) - return; - - int rotation = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION"); - if (rotation) - m_rotationMatrix.rotate(rotation, 0, 0, 1); - - // Load the default cursor - m_cursorTheme.loadTheme(QString(), 32); - - // Try to load the cursor atlas. If this fails, m_visible is set to false and - // paintOnScreen() and setCurrentCursor() become no-ops. - initCursorAtlas(); - - // initialize the cursor -#ifndef QT_NO_CURSOR - QCursor cursor(Qt::ArrowCursor); - setCurrentCursor(&cursor); -#endif - - m_deviceListener = new QEglFSCursorDeviceListener(this); - connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, - m_deviceListener, &QEglFSCursorDeviceListener::onDeviceListChanged); - updateMouseStatus(); -} - -QEglFSCursor::~QEglFSCursor() -{ - resetResources(); - delete m_deviceListener; -} - -void QEglFSCursor::updateMouseStatus() -{ - m_visible = m_deviceListener->hasMouse(); -} - -void QEglFSCursor::setCursorTheme(const QString &name, int size) -{ - m_cursorTheme.loadTheme(name, size); -} - -bool QEglFSCursorDeviceListener::hasMouse() const -{ - return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; -} - -void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) -{ - if (type == QInputDeviceManager::DeviceTypePointer) - m_cursor->updateMouseStatus(); -} - -void QEglFSCursor::resetResources() -{ - m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull(); -} - -void QEglFSCursor::createShaderPrograms() -{ - static const char *textureVertexProgram = - "attribute highp vec2 vertexCoordEntry;\n" - "attribute highp vec2 textureCoordEntry;\n" - "varying highp vec2 textureCoord;\n" - "uniform highp mat4 mat;\n" - "void main() {\n" - " textureCoord = textureCoordEntry;\n" - " gl_Position = mat * vec4(vertexCoordEntry, 1.0, 1.0);\n" - "}\n"; - - static const char *textureFragmentProgram = - "uniform sampler2D texture;\n" - "varying highp vec2 textureCoord;\n" - "void main() {\n" - " gl_FragColor = texture2D(texture, textureCoord).bgra;\n" - "}\n"; - - QEglFSCursorData &gfx = static_cast(QOpenGLContext::currentContext()->handle())->cursorData; - gfx.program.reset(new QOpenGLShaderProgram); - gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); - gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); - gfx.program->bindAttributeLocation("vertexCoordEntry", 0); - gfx.program->bindAttributeLocation("textureCoordEntry", 1); - gfx.program->link(); - - gfx.textureEntry = gfx.program->uniformLocation("texture"); - gfx.matEntry = gfx.program->uniformLocation("mat"); -} - -void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image) -{ - if (!*texture) - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */, - GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); -} - -void QEglFSCursor::initCursorAtlas() -{ - static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); - if (json.isEmpty()) - json = ":/cursor.json"; - - QFile file(QString::fromUtf8(json)); - if (!file.open(QFile::ReadOnly)) { - m_visible = false; - return; - } - - QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); - QJsonObject object = doc.object(); - - QString atlas = object.value(QLatin1String("image")).toString(); - Q_ASSERT(!atlas.isEmpty()); - - const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble(); - Q_ASSERT(cursorsPerRow); - m_cursorAtlas.cursorsPerRow = cursorsPerRow; - - const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray(); - Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1); - for (int i = 0; i < hotSpots.count(); i++) { - QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble()); - m_cursorAtlas.hotSpots << hotSpot; - } - - QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied); - m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow; - m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow) / cursorsPerRow); - m_cursorAtlas.width = image.width(); - m_cursorAtlas.height = image.height(); - m_cursorAtlas.image = std::move(image); -} - -#ifndef QT_NO_CURSOR -void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) -{ - Q_UNUSED(window); - const QRect oldCursorRect = cursorRect(); - if (setCurrentCursor(cursor)) - update(oldCursorRect | cursorRect(), false); -} - -bool QEglFSCursor::setCurrentCursor(QCursor *cursor) -{ - if (!m_visible) - return false; - - const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; - if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor) - return false; - - if (m_cursor.shape == Qt::BitmapCursor) { - m_cursor.customCursorImage = QImage(); - m_cursor.customCursorPending = false; - } - m_cursor.shape = newShape; - if (newShape != Qt::BitmapCursor) { // standard cursor - if (m_cursorTheme.isLoaded()) { - auto cursor = m_cursorTheme.cursorForShape(m_cursor.shape); - if (cursor.isValid) { - m_cursor.textureRect = QRect(QPoint(0, 0), cursor.image.size()); - m_cursor.hotSpot = cursor.hotSpot; - m_cursor.useCustomCursor = false; - m_cursor.size = cursor.image.size(); - } - } else { - const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width, - hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height; - m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow), - hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow), - ws, hs); - m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape]; - m_cursor.useCustomCursor = false; - m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight); - } - } else { - QImage image = cursor->pixmap().toImage(); - m_cursor.textureRect = QRectF(0, 0, 1, 1); - m_cursor.hotSpot = cursor->hotSpot(); - m_cursor.useCustomCursor = false; // will get updated in the next render() - m_cursor.size = image.size(); - m_cursor.customCursorImage = std::move(image); - m_cursor.customCursorPending = true; - m_cursor.customCursorKey = m_cursor.customCursorImage.cacheKey(); - } - - return true; -} -#endif - -class CursorUpdateEvent : public QEvent -{ -public: - CursorUpdateEvent(const QPoint &pos, const QRect &rect, bool allScreens) - : QEvent(QEvent::Type(QEvent::User + 1)), - m_pos(pos), - m_rect(rect), - m_allScreens(allScreens) - { } - QPoint pos() const { return m_pos; } - QRegion rect() const { return m_rect; } - bool allScreens() const { return m_allScreens; } - -private: - QPoint m_pos; - QRect m_rect; - bool m_allScreens; -}; - -bool QEglFSCursor::event(QEvent *e) -{ - if (e->type() == QEvent::User + 1) { - CursorUpdateEvent *ev = static_cast(e); - m_updateRequested = false; - if (!ev->allScreens()) { - QWindow *w = m_screen->topLevelAt(ev->pos()); // works for the entire virtual desktop, no need to loop - if (w) { - QWindowSystemInterface::handleExposeEvent(w, ev->rect()); - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); - } - } else { - const auto windows = qGuiApp->topLevelWindows(); - for (QWindow *w : windows) - QWindowSystemInterface::handleExposeEvent(w, w->geometry()); - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); - } - return true; - } - return QPlatformCursor::event(e); -} - -void QEglFSCursor::update(const QRect &rect, bool allScreens) -{ - if (!m_updateRequested) { - // Must not flush the window system events directly from here since we are likely to - // be a called directly from QGuiApplication's processMouseEvents. Flushing events - // could cause reentering by dispatching more queued mouse events. - m_updateRequested = true; - QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rect, allScreens)); - } -} - -QRect QEglFSCursor::cursorRect() const -{ - return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size); -} - -QPoint QEglFSCursor::pos() const -{ - return m_cursor.pos; -} - -void QEglFSCursor::setPos(const QPoint &pos) -{ - QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); - const QRect oldCursorRect = cursorRect(); - m_cursor.pos = pos; - update(oldCursorRect | cursorRect(), false); - const auto screens = m_screen->virtualSiblings(); - for (QPlatformScreen *screen : screens) - static_cast(screen)->handleCursorMove(m_cursor.pos); -} - -void QEglFSCursor::pointerEvent(const QMouseEvent &event) -{ - if (event.type() != QEvent::MouseMove) - return; - const QRect oldCursorRect = cursorRect(); - m_cursor.pos = event.screenPos().toPoint(); - update(oldCursorRect | cursorRect(), false); - const auto screens = m_screen->virtualSiblings(); - for (QPlatformScreen *screen : screens) - static_cast(screen)->handleCursorMove(m_cursor.pos); -} - -void QEglFSCursor::paintOnScreen() -{ - if (!m_visible) - return; - - // cr must be a QRectF, otherwise cr.right() and bottom() would be off by - // one in the calculations below. - QRectF cr = cursorRect(); // hotspot included - - // Support virtual desktop too. Backends with multi-screen support (e.g. all - // variants of KMS/DRM) will enable this by default. In this case all - // screens are siblings of each other. When not enabled, the sibling list - // only contains m_screen itself. - const auto screens = m_screen->virtualSiblings(); - for (QPlatformScreen *screen : screens) { - if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot) - && QOpenGLContext::currentContext()->screen() == screen->screen()) - { - cr.translate(-screen->geometry().topLeft()); - const QSize screenSize = screen->geometry().size(); - const GLfloat x1 = 2 * (cr.left() / GLfloat(screenSize.width())) - 1; - const GLfloat x2 = 2 * (cr.right() / GLfloat(screenSize.width())) - 1; - const GLfloat y1 = 1 - (cr.top() / GLfloat(screenSize.height())) * 2; - const GLfloat y2 = 1 - (cr.bottom() / GLfloat(screenSize.height())) * 2; - QRectF r(QPointF(x1, y1), QPointF(x2, y2)); - - draw(r); - - if (screen != m_activeScreen) { - m_activeScreen = screen; - // Do not want a leftover cursor on the screen the cursor just left. - update(cursorRect(), true); - } - - break; - } - } -} - -// In order to prevent breaking code doing custom OpenGL rendering while -// expecting the state in the context unchanged, save and restore all the state -// we touch. The exception is Qt Quick where the scenegraph is known to be able -// to deal with the changes we make. -struct StateSaver -{ - StateSaver() { - f = QOpenGLContext::currentContext()->functions(); - vaoHelper = new QOpenGLVertexArrayObjectHelper(QOpenGLContext::currentContext()); - - static bool windowsChecked = false; - static bool shouldSave = true; - if (!windowsChecked) { - windowsChecked = true; - QWindowList windows = QGuiApplication::allWindows(); - if (!windows.isEmpty() && windows[0]->inherits("QQuickWindow")) - shouldSave = false; - } - saved = shouldSave; - if (!shouldSave) - return; - - f->glGetIntegerv(GL_CURRENT_PROGRAM, &program); - f->glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); - f->glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); - f->glGetIntegerv(GL_FRONT_FACE, &frontFace); - cull = f->glIsEnabled(GL_CULL_FACE); - depthTest = f->glIsEnabled(GL_DEPTH_TEST); - blend = f->glIsEnabled(GL_BLEND); - f->glGetIntegerv(GL_BLEND_SRC_RGB, blendFunc); - f->glGetIntegerv(GL_BLEND_SRC_ALPHA, blendFunc + 1); - f->glGetIntegerv(GL_BLEND_DST_RGB, blendFunc + 2); - f->glGetIntegerv(GL_BLEND_DST_ALPHA, blendFunc + 3); - f->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBuf); - if (vaoHelper->isValid()) - f->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao); - else - vao = 0; - for (int i = 0; i < 2; ++i) { - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &va[i].enabled); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &va[i].size); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &va[i].type); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &va[i].normalized); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &va[i].stride); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &va[i].buffer); - f->glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &va[i].pointer); - } - } - ~StateSaver() { - if (saved) { - f->glUseProgram(program); - f->glBindTexture(GL_TEXTURE_2D, texture); - f->glActiveTexture(activeTexture); - f->glFrontFace(frontFace); - if (cull) - f->glEnable(GL_CULL_FACE); - else - f->glDisable(GL_CULL_FACE); - if (depthTest) - f->glEnable(GL_DEPTH_TEST); - else - f->glDisable(GL_DEPTH_TEST); - if (blend) - f->glEnable(GL_BLEND); - else - f->glDisable(GL_BLEND); - f->glBlendFuncSeparate(blendFunc[0], blendFunc[1], blendFunc[2], blendFunc[3]); - f->glBindBuffer(GL_ARRAY_BUFFER, arrayBuf); - if (vaoHelper->isValid()) - vaoHelper->glBindVertexArray(vao); - for (int i = 0; i < 2; ++i) { - if (va[i].enabled) - f->glEnableVertexAttribArray(i); - else - f->glDisableVertexAttribArray(i); - f->glBindBuffer(GL_ARRAY_BUFFER, va[i].buffer); - f->glVertexAttribPointer(i, va[i].size, va[i].type, va[i].normalized, va[i].stride, va[i].pointer); - } - } - delete vaoHelper; - } - QOpenGLFunctions *f; - QOpenGLVertexArrayObjectHelper *vaoHelper; - bool saved; - GLint program; - GLint texture; - GLint activeTexture; - GLint frontFace; - bool cull; - bool depthTest; - bool blend; - GLint blendFunc[4]; - GLint vao; - GLint arrayBuf; - struct { GLint enabled, type, size, normalized, stride, buffer; GLvoid *pointer; } va[2]; -}; - -void QEglFSCursor::draw(const QRectF &r) -{ - StateSaver stateSaver; - - QEglFSCursorData &gfx = static_cast(QOpenGLContext::currentContext()->handle())->cursorData; - if (!gfx.program) { - // one time initialization - initializeOpenGLFunctions(); - - createShaderPrograms(); - - if (!gfx.atlasTexture) { - if (m_cursorTheme.isLoaded()) { - auto cursor = m_cursorTheme.cursorForShape(m_cursor.shape); - if (cursor.isValid) - createCursorTexture(&gfx.atlasTexture, cursor.image); - } else { - createCursorTexture(&gfx.atlasTexture, m_cursorAtlas.image); - } - - if (m_cursor.shape != Qt::BitmapCursor) - m_cursor.useCustomCursor = false; - } - } - - if (m_cursor.shape == Qt::BitmapCursor && (m_cursor.customCursorPending || m_cursor.customCursorKey != gfx.customCursorKey)) { - // upload the custom cursor - createCursorTexture(&gfx.customCursorTexture, m_cursor.customCursorImage); - m_cursor.useCustomCursor = true; - m_cursor.customCursorPending = false; - gfx.customCursorKey = m_cursor.customCursorKey; - } - - GLuint cursorTexture = !m_cursor.useCustomCursor ? gfx.atlasTexture : gfx.customCursorTexture; - Q_ASSERT(cursorTexture); - - gfx.program->bind(); - - const GLfloat x1 = r.left(); - const GLfloat x2 = r.right(); - const GLfloat y1 = r.top(); - const GLfloat y2 = r.bottom(); - const GLfloat cursorCoordinates[] = { - x1, y2, - x2, y2, - x1, y1, - x2, y1 - }; - - const GLfloat s1 = m_cursor.textureRect.left(); - const GLfloat s2 = m_cursor.textureRect.right(); - const GLfloat t1 = m_cursor.textureRect.top(); - const GLfloat t2 = m_cursor.textureRect.bottom(); - const GLfloat textureCoordinates[] = { - s1, t2, - s2, t2, - s1, t1, - s2, t1 - }; - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, cursorTexture); - - if (stateSaver.vaoHelper->isValid()) - stateSaver.vaoHelper->glBindVertexArray(0); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - gfx.program->enableAttributeArray(0); - gfx.program->enableAttributeArray(1); - gfx.program->setAttributeArray(0, cursorCoordinates, 2); - gfx.program->setAttributeArray(1, textureCoordinates, 2); - - gfx.program->setUniformValue(gfx.textureEntry, 0); - gfx.program->setUniformValue(gfx.matEntry, m_rotationMatrix); - - glDisable(GL_CULL_FACE); - glFrontFace(GL_CCW); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - gfx.program->disableAttributeArray(0); - gfx.program->disableAttributeArray(1); - gfx.program->release(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h deleted file mode 100644 index 01a4011a..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include -#include -#include -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -class QOpenGLShaderProgram; -class QEglFSCursor; -class QEglFSScreen; - -class QEglFSCursorDeviceListener : public QObject -{ - Q_OBJECT - -public: - QEglFSCursorDeviceListener(QEglFSCursor *cursor) : m_cursor(cursor) { } - bool hasMouse() const; - -public slots: - void onDeviceListChanged(QInputDeviceManager::DeviceType type); - -private: - QEglFSCursor *m_cursor; -}; - -#if QT_CONFIG(opengl) - -struct QEglFSCursorData { - QScopedPointer program; - int textureEntry = 0; - int matEntry = 0; - uint customCursorTexture = 0; - uint atlasTexture = 0; - qint64 customCursorKey = 0; -}; - -class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor - , protected QOpenGLFunctions -{ - Q_OBJECT -public: - QEglFSCursor(QPlatformScreen *screen); - ~QEglFSCursor(); - -#ifndef QT_NO_CURSOR - void changeCursor(QCursor *cursor, QWindow *widget) override; -#endif - void pointerEvent(const QMouseEvent &event) override; - QPoint pos() const override; - void setPos(const QPoint &pos) override; - - QRect cursorRect() const; - void paintOnScreen(); - void resetResources(); - - void updateMouseStatus(); - - void setCursorTheme(const QString &name, int size); - -private: - bool event(QEvent *e) override; -#ifndef QT_NO_CURSOR - bool setCurrentCursor(QCursor *cursor); -#endif - void draw(const QRectF &rect); - void update(const QRect &rect, bool allScreens); - void createShaderPrograms(); - void createCursorTexture(uint *texture, const QImage &image); - void initCursorAtlas(); - - // current cursor information - struct Cursor { - Cursor() : shape(Qt::BlankCursor), customCursorPending(false), customCursorKey(0), useCustomCursor(false) { } - Qt::CursorShape shape; - QRectF textureRect; // normalized rect inside texture - QSize size; // size of the cursor - QPoint hotSpot; - QImage customCursorImage; - QPoint pos; // current cursor position - bool customCursorPending; - qint64 customCursorKey; - bool useCustomCursor; - } m_cursor; - - // cursor atlas information - struct CursorAtlas { - CursorAtlas() : cursorsPerRow(0), cursorWidth(0), cursorHeight(0) { } - int cursorsPerRow; - int width, height; // width and height of the atlas - int cursorWidth, cursorHeight; // width and height of cursors inside the atlas - QVector hotSpots; - QImage image; // valid until it's uploaded - } m_cursorAtlas; - - bool m_visible; - QEglFSScreen *m_screen; - QPlatformScreen *m_activeScreen; - QEglFSCursorDeviceListener *m_deviceListener; - Liri::Platform::XcursorTheme m_cursorTheme; - bool m_updateRequested; - QMatrix4x4 m_rotationMatrix; -}; -#endif // QT_CONFIG(opengl) - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp deleted file mode 100644 index 45754681..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfsdeviceintegration_p.h" -#include "qeglfsintegration_p.h" -#ifndef QT_NO_OPENGL -# include "qeglfscursor_p.h" -#endif -#include "qeglfswindow_p.h" -#include "qeglfsscreen_p.h" -#include "qeglfshooks_p.h" - -#include -#include -#include -#include -#include -#if QT_CONFIG(regularexpression) -# include -# include -#endif -#include - -#if defined(Q_OS_LINUX) -#include -#include -#include -#include -#endif - -#include -#include - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qLcEglDevDebug, "aurora.eglfs.egldeviceintegration", QtInfoMsg) - -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QEglFSDeviceIntegrationFactoryInterface_iid, QLatin1String("/liri/egldeviceintegrations"), Qt::CaseInsensitive)) - -#if QT_CONFIG(library) -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, - (QEglFSDeviceIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) - -#endif // QT_CONFIG(library) - -QStringList QEglFSDeviceIntegrationFactory::keys(const QString &pluginPath) -{ - QStringList list; -#if QT_CONFIG(library) - if (!pluginPath.isEmpty()) { - QCoreApplication::addLibraryPath(pluginPath); - list = directLoader()->keyMap().values(); - if (!list.isEmpty()) { - const QString postFix = QLatin1String(" (from ") - + QDir::toNativeSeparators(pluginPath) - + QLatin1Char(')'); - const QStringList::iterator end = list.end(); - for (QStringList::iterator it = list.begin(); it != end; ++it) - (*it).append(postFix); - } - } -#else - Q_UNUSED(pluginPath); -#endif - list.append(loader()->keyMap().values()); - qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys:" << list; - return list; -} - -QEglFSDeviceIntegration *QEglFSDeviceIntegrationFactory::create(const QString &key, const QString &pluginPath) -{ - QEglFSDeviceIntegration *integration = nullptr; -#if QT_CONFIG(library) - if (!pluginPath.isEmpty()) { - QCoreApplication::addLibraryPath(pluginPath); - integration = qLoadPlugin(directLoader(), key); - } -#else - Q_UNUSED(pluginPath); -#endif - if (!integration) - integration = qLoadPlugin(loader(), key); - if (integration) - qCDebug(qLcEglDevDebug) << "Using EGL device integration" << key; - else - qCWarning(qLcEglDevDebug) << "Failed to load EGL device integration" << key; - - return integration; -} - -static int framebuffer = -1; - -QByteArray QEglFSDeviceIntegration::fbDeviceName() const -{ -#ifdef Q_OS_LINUX - QByteArray fbDev = qgetenv("QT_QPA_EGLFS_FB"); - if (fbDev.isEmpty()) - fbDev = QByteArrayLiteral("/dev/fb0"); - - return fbDev; -#else - return QByteArray(); -#endif -} - -int QEglFSDeviceIntegration::framebufferIndex() const -{ - int fbIndex = 0; -#if QT_CONFIG(regularexpression) - QRegularExpression fbIndexRx(QLatin1String("fb(\\d+)")); - QFileInfo fbinfo(QString::fromLocal8Bit(fbDeviceName())); - QRegularExpressionMatch match; - if (fbinfo.isSymLink()) - match = fbIndexRx.match(fbinfo.symLinkTarget()); - else - match = fbIndexRx.match(fbinfo.fileName()); - if (match.hasMatch()) - fbIndex = match.captured(1).toInt(); -#endif - return fbIndex; -} - -void QEglFSDeviceIntegration::platformInit() -{ -#ifdef Q_OS_LINUX - QByteArray fbDev = fbDeviceName(); - - framebuffer = qt_safe_open(fbDev, O_RDONLY); - - if (Q_UNLIKELY(framebuffer == -1)) { - qWarning("EGLFS: Failed to open %s", fbDev.constData()); - qFatal("EGLFS: Can't continue without a display"); - } - -#ifdef FBIOBLANK - ioctl(framebuffer, FBIOBLANK, VESA_NO_BLANKING); -#endif -#endif -} - -void QEglFSDeviceIntegration::platformDestroy() -{ -#ifdef Q_OS_LINUX - if (framebuffer != -1) - close(framebuffer); -#endif -} - -EGLNativeDisplayType QEglFSDeviceIntegration::platformDisplay() const -{ - bool displayOk; - const int defaultDisplay = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEFAULT_DISPLAY", &displayOk); - return displayOk ? EGLNativeDisplayType(quintptr(defaultDisplay)) : EGL_DEFAULT_DISPLAY; -} - -EGLDisplay QEglFSDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) -{ - return eglGetDisplay(nativeDisplay); -} - -bool QEglFSDeviceIntegration::usesDefaultScreen() -{ - return true; -} - -void QEglFSDeviceIntegration::screenInit() -{ - // Nothing to do here. Called only when usesDefaultScreen is false. -} - -void QEglFSDeviceIntegration::screenDestroy() -{ - QGuiApplication *app = qGuiApp; - while (!app->screens().isEmpty()) - QWindowSystemInterface::handleScreenRemoved(app->screens().constLast()->handle()); -} - -QSizeF QEglFSDeviceIntegration::physicalScreenSize() const -{ - return q_physicalScreenSizeFromFb(framebuffer, screenSize()); -} - -QSize QEglFSDeviceIntegration::screenSize() const -{ - return q_screenSizeFromFb(framebuffer); -} - -QDpi QEglFSDeviceIntegration::logicalDpi() const -{ - const QSizeF ps = physicalScreenSize(); - const QSize s = screenSize(); - - if (!ps.isEmpty() && !s.isEmpty()) - return QDpi(25.4 * s.width() / ps.width(), - 25.4 * s.height() / ps.height()); - else - return QDpi(100, 100); -} - -qreal QEglFSDeviceIntegration::pixelDensity() const -{ - return qMax(1, qRound(logicalDpi().first / qreal(100))); -} - -Qt::ScreenOrientation QEglFSDeviceIntegration::nativeOrientation() const -{ - return Qt::PrimaryOrientation; -} - -Qt::ScreenOrientation QEglFSDeviceIntegration::orientation() const -{ - return Qt::PrimaryOrientation; -} - -int QEglFSDeviceIntegration::screenDepth() const -{ - return q_screenDepthFromFb(framebuffer); -} - -QImage::Format QEglFSDeviceIntegration::screenFormat() const -{ - return screenDepth() == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32; -} - -qreal QEglFSDeviceIntegration::refreshRate() const -{ - return q_refreshRateFromFb(framebuffer); -} - -EGLint QEglFSDeviceIntegration::surfaceType() const -{ - return EGL_WINDOW_BIT; -} - -QSurfaceFormat QEglFSDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const -{ - QSurfaceFormat format = inputFormat; - - static const bool force888 = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCE888"); - if (force888) { - format.setRedBufferSize(8); - format.setGreenBufferSize(8); - format.setBlueBufferSize(8); - } - - return format; -} - -bool QEglFSDeviceIntegration::filterConfig(EGLDisplay, EGLConfig) const -{ - return true; -} - -QEglFSWindow *QEglFSDeviceIntegration::createWindow(QWindow *window) const -{ - return new QEglFSWindow(window); -} - -EGLNativeWindowType QEglFSDeviceIntegration::createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) -{ - Q_UNUSED(platformWindow); - Q_UNUSED(size); - Q_UNUSED(format); - return 0; -} - -EGLNativeWindowType QEglFSDeviceIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format) -{ - Q_UNUSED(format); - return 0; -} - -void QEglFSDeviceIntegration::destroyNativeWindow(EGLNativeWindowType window) -{ - Q_UNUSED(window); -} - -bool QEglFSDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - Q_UNUSED(cap); - return false; -} - -QPlatformCursor *QEglFSDeviceIntegration::createCursor(QPlatformScreen *screen) const -{ -#ifndef QT_NO_OPENGL - return new QEglFSCursor(static_cast(screen)); -#else - Q_UNUSED(screen); - return nullptr; -#endif -} - -void QEglFSDeviceIntegration::waitForVSync(QPlatformSurface *surface) const -{ - Q_UNUSED(surface); - -#if defined(Q_OS_LINUX) && defined(FBIO_WAITFORVSYNC) - static const bool forceSync = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCEVSYNC"); - if (forceSync && framebuffer != -1) { - int arg = 0; - if (ioctl(framebuffer, FBIO_WAITFORVSYNC, &arg) == -1) - qWarning("Could not wait for vsync."); - } -#endif -} - -void QEglFSDeviceIntegration::presentBuffer(QPlatformSurface *surface) -{ - Q_UNUSED(surface); -} - -bool QEglFSDeviceIntegration::supportsPBuffers() const -{ - return true; -} - -bool QEglFSDeviceIntegration::supportsSurfacelessContexts() const -{ - return true; -} - -QFunctionPointer QEglFSDeviceIntegration::platformFunction(const QByteArray &function) const -{ - Q_UNUSED(function); - return nullptr; -} - -void *QEglFSDeviceIntegration::nativeResourceForIntegration(const QByteArray &name) -{ - Q_UNUSED(name); - return nullptr; -} - -void *QEglFSDeviceIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) -{ - Q_UNUSED(resource); - Q_UNUSED(screen); - return nullptr; -} - -void *QEglFSDeviceIntegration::wlDisplay() const -{ - return nullptr; -} - -#if QT_CONFIG(vulkan) -QPlatformVulkanInstance *QEglFSDeviceIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) -{ - Q_UNUSED(instance); - return nullptr; -} -#endif - -EGLConfig QEglFSDeviceIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) -{ - class Chooser : public QEglConfigChooser { - public: - Chooser(EGLDisplay display) - : QEglConfigChooser(display) { } - bool filterConfig(EGLConfig config) const override { - return qt_egl_device_integration()->filterConfig(display(), config) - && QEglConfigChooser::filterConfig(config); - } - }; - - Chooser chooser(display); - chooser.setSurfaceType(qt_egl_device_integration()->surfaceType()); - chooser.setSurfaceFormat(format); - return chooser.chooseConfig(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h deleted file mode 100644 index 055a261d..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QPlatformSurface; -class QEglFSWindow; - -#define QEglFSDeviceIntegrationFactoryInterface_iid "org.qt-project.qt.qpa.egl.QEglFSDeviceIntegrationFactoryInterface.5.5" - -class Q_EGLFS_EXPORT QEglFSDeviceIntegration -{ -public: - virtual ~QEglFSDeviceIntegration() { } - - virtual void platformInit(); - virtual void platformDestroy(); - virtual EGLNativeDisplayType platformDisplay() const; - virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay); - virtual bool usesDefaultScreen(); - virtual void screenInit(); - virtual void screenDestroy(); - virtual QSizeF physicalScreenSize() const; - virtual QSize screenSize() const; - virtual QDpi logicalDpi() const; - virtual qreal pixelDensity() const; - virtual Qt::ScreenOrientation nativeOrientation() const; - virtual Qt::ScreenOrientation orientation() const; - virtual int screenDepth() const; - virtual QImage::Format screenFormat() const; - virtual qreal refreshRate() const; - virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; - virtual EGLint surfaceType() const; - virtual QEglFSWindow *createWindow(QWindow *window) const; - virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format); - virtual EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format); - virtual void destroyNativeWindow(EGLNativeWindowType window); - virtual bool hasCapability(QPlatformIntegration::Capability cap) const; - virtual QPlatformCursor *createCursor(QPlatformScreen *screen) const; - virtual bool filterConfig(EGLDisplay display, EGLConfig config) const; - virtual void waitForVSync(QPlatformSurface *surface) const; - virtual void presentBuffer(QPlatformSurface *surface); - virtual QByteArray fbDeviceName() const; - virtual int framebufferIndex() const; - virtual bool supportsPBuffers() const; - virtual bool supportsSurfacelessContexts() const; - virtual QFunctionPointer platformFunction(const QByteArray &function) const; - virtual void *nativeResourceForIntegration(const QByteArray &name); - virtual void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen); - virtual void *wlDisplay() const; - -#if QT_CONFIG(vulkan) - virtual QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance); -#endif - - static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); -}; - -class Q_EGLFS_EXPORT QEglFSDeviceIntegrationPlugin : public QObject -{ - Q_OBJECT - -public: - virtual QEglFSDeviceIntegration *create() = 0; - - // the pattern expected by qLoadPlugin calls for a QString argument. - // we don't need it, so don't bother subclasses with it: - QEglFSDeviceIntegration *create(const QString &) { return create(); } -}; - -class Q_EGLFS_EXPORT QEglFSDeviceIntegrationFactory -{ -public: - static QStringList keys(const QString &pluginPath = QString()); - static QEglFSDeviceIntegration *create(const QString &name, const QString &platformPluginPath = QString()); -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfsglobal_p.h b/src/plugins/platforms/eglfs/api/qeglfsglobal_p.h deleted file mode 100644 index 6212e7d6..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsglobal_p.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#include - -QT_BEGIN_NAMESPACE - -#ifdef QT_BUILD_EGL_DEVICE_LIB -#define Q_EGLFS_EXPORT Q_DECL_EXPORT -#else -#define Q_EGLFS_EXPORT Q_DECL_IMPORT -#endif - -#undef Status -#undef None -#undef Bool -#undef CursorShape -#undef KeyPress -#undef KeyRelease -#undef FocusIn -#undef FocusOut -#undef FontChange -#undef Expose -#undef Unsorted - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfshooks.cpp b/src/plugins/platforms/eglfs/api/qeglfshooks.cpp deleted file mode 100644 index ff5c5dee..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfshooks.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfshooks_p.h" -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug) - -#ifdef EGLFS_PLATFORM_HOOKS - -QEglFSDeviceIntegration *qt_egl_device_integration() -{ - extern QEglFSHooks *platformHooks; - return platformHooks; -} - -#else - -namespace { -class DeviceIntegration -{ -public: - DeviceIntegration(); - ~DeviceIntegration() { delete m_integration; } - QEglFSDeviceIntegration *integration() { return m_integration; } -private: - QEglFSDeviceIntegration *m_integration; -}; -} - -Q_GLOBAL_STATIC(DeviceIntegration, deviceIntegration) - -DeviceIntegration::DeviceIntegration() - : m_integration(nullptr) -{ - QStringList pluginKeys = QEglFSDeviceIntegrationFactory::keys(); - if (!pluginKeys.isEmpty()) { - // Some built-in logic: Prioritize either X11 or KMS/DRM. - if (qEnvironmentVariableIsSet("DISPLAY")) { - const QString x11key = QStringLiteral("eglfs_x11"); - if (pluginKeys.contains(x11key)) { - pluginKeys.removeOne(x11key); - pluginKeys.prepend(x11key); - } - } else { - const QString kmskey = QStringLiteral("eglfs_kms"); - if (pluginKeys.contains(kmskey)) { - pluginKeys.removeOne(kmskey); - pluginKeys.prepend(kmskey); - } - } - - QByteArray requested; - - // The environment variable can override everything. - if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_INTEGRATION")) { - requested = qgetenv("QT_QPA_EGLFS_INTEGRATION"); - } else { - // Device-specific makespecs may define a preferred plugin. -#ifdef EGLFS_PREFERRED_PLUGIN -#define DEFAULT_PLUGIN EGLFS_PREFERRED_PLUGIN -#define STR(s) #s -#define STRQ(s) STR(s) - requested = STRQ(DEFAULT_PLUGIN); -#endif - } - - // Treat "none" as special. There has to be a way to indicate - // that plugins must be ignored when the device is known to be - // functional with the default, non-specialized integration. - if (requested != QByteArrayLiteral("none")) { - if (!requested.isEmpty()) { - QString reqStr = QString::fromLocal8Bit(requested); - pluginKeys.removeOne(reqStr); - pluginKeys.prepend(reqStr); - } - qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys (sorted):" << pluginKeys; - while (!m_integration && !pluginKeys.isEmpty()) { - QString key = pluginKeys.takeFirst(); - qCDebug(qLcEglDevDebug) << "Trying to load device EGL integration" << key; - m_integration = QEglFSDeviceIntegrationFactory::create(key); - } - } - } - - if (!m_integration) { - // Use a default, non-specialized device integration when no plugin is available. - // For some systems this is sufficient. - qCDebug(qLcEglDevDebug) << "Using base device integration"; - m_integration = new QEglFSDeviceIntegration; - } -} - -QEglFSDeviceIntegration *qt_egl_device_integration() -{ - return deviceIntegration()->integration(); -} - -#endif // EGLFS_PLATFORM_HOOKS - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfshooks_p.h b/src/plugins/platforms/eglfs/api/qeglfshooks_p.h deleted file mode 100644 index a7c6aaec..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfshooks_p.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include "qeglfsdeviceintegration_p.h" -#include - -QT_BEGIN_NAMESPACE - -Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug) - -class QEglFSHooks : public QEglFSDeviceIntegration -{ -}; - -Q_EGLFS_EXPORT QEglFSDeviceIntegration *qt_egl_device_integration(); - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp deleted file mode 100644 index 3b97be59..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include -#include -#include -#ifndef QT_NO_OPENGL -# include -# include -#endif -#include -#include -#include -#include - -#include "qeglfsintegration_p.h" -#include "qeglfswindow_p.h" -#include "qeglfshooks_p.h" -#ifndef QT_NO_OPENGL -# include "qeglfscontext_p.h" -# include "qeglfscursor_p.h" -#endif -#include "qeglfsoffscreenwindow_p.h" -#include "qeglfslogindhandler_p.h" -#include "vthandler.h" -#include "libinputmanager_p.h" - -#include -#ifndef QT_NO_OPENGL -# include -# include -#endif - -#include -#include -#include -#include -#include -#ifndef QT_NO_OPENGL -# include -#endif - -#include - -#include - -using namespace Aurora::PlatformSupport; - -static void initResources() -{ -#ifndef QT_NO_CURSOR - Q_INIT_RESOURCE(cursor); -#endif -} - -QT_BEGIN_NAMESPACE - -QEglFSIntegration::QEglFSIntegration() - : m_display(EGL_NO_DISPLAY), - m_inputContext(nullptr), - m_fontDb(new QGenericUnixFontDatabase), - m_services(new QGenericUnixServices), - m_logindHandler(nullptr), - m_disableInputHandlers(false) -{ - m_disableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT"); - - initResources(); -} - -void QEglFSIntegration::initialize() -{ - m_logindHandler = new QEglFSLogindHandler(); - connect(m_logindHandler, &QEglFSLogindHandler::initializationRequested, this, [&] { - qt_egl_device_integration()->platformInit(); - - m_display = qt_egl_device_integration()->createDisplay(nativeDisplay()); - if (Q_UNLIKELY(m_display == EGL_NO_DISPLAY)) - qFatal("Could not open egl display"); - - EGLint major, minor; - if (Q_UNLIKELY(!eglInitialize(m_display, &major, &minor))) - qFatal("Could not initialize egl display"); - - m_inputContext = QPlatformInputContextFactory::create(); - - m_vtHandler.reset(new VtHandler); - - if (qt_egl_device_integration()->usesDefaultScreen()) - QWindowSystemInterface::handleScreenAdded(new QEglFSScreen(display())); - else - qt_egl_device_integration()->screenInit(); - - // Input code may rely on the screens, so do it only after the screen init. - if (!m_disableInputHandlers) - createInputHandlers(); - - // Exit initialization - m_logindHandler->stop(); - }); - m_logindHandler->initialize(); -} - -void QEglFSIntegration::destroy() -{ - foreach (QWindow *w, qGuiApp->topLevelWindows()) - w->destroy(); - - qt_egl_device_integration()->screenDestroy(); - - if (m_display != EGL_NO_DISPLAY) - eglTerminate(m_display); - - qt_egl_device_integration()->platformDestroy(); - - m_logindHandler->deleteLater(); -} - -QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const -{ - return createUnixEventDispatcher(); -} - -QPlatformServices *QEglFSIntegration::services() const -{ - return m_services.data(); -} - -QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const -{ - return m_fontDb.data(); -} - -QPlatformTheme *QEglFSIntegration::createPlatformTheme(const QString &name) const -{ - return QGenericUnixTheme::createUnixTheme(name); -} - -QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const -{ -#ifndef QT_NO_OPENGL - QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window); - if (!window->handle()) - window->create(); - static_cast(window->handle())->setBackingStore(bs); - return bs; -#else - Q_UNUSED(window); - return nullptr; -#endif -} - -QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const -{ - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); - QEglFSWindow *w = qt_egl_device_integration()->createWindow(window); - w->create(); - - const auto showWithoutActivating = window->property("_q_showWithoutActivating"); - if (showWithoutActivating.isValid() && showWithoutActivating.toBool()) - return w; - - // Activate only the window for the primary screen to make input work - if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen()) - w->requestActivateWindow(); - - return w; -} - -#ifndef QT_NO_OPENGL -QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const -{ - EGLDisplay dpy = context->screen() ? static_cast(context->screen()->handle())->display() : display(); - QPlatformOpenGLContext *share = context->shareHandle(); - QVariant nativeHandle = context->nativeHandle(); - - QEglFSContext *ctx; - QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(context->format()); - if (nativeHandle.isNull()) { - EGLConfig config = QEglFSDeviceIntegration::chooseConfig(dpy, adjustedFormat); - ctx = new QEglFSContext(adjustedFormat, share, dpy, &config, QVariant()); - } else { - ctx = new QEglFSContext(adjustedFormat, share, dpy, nullptr, nativeHandle); - } - nativeHandle = QVariant::fromValue(QEGLNativeContext(ctx->eglContext(), dpy)); - - context->setNativeHandle(nativeHandle); - return ctx; -} - -QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const -{ - EGLDisplay dpy = surface->screen() ? static_cast(surface->screen()->handle())->display() : display(); - QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(surface->requestedFormat()); - if (qt_egl_device_integration()->supportsPBuffers()) { - QEGLPlatformContext::Flags flags = {}; - if (!qt_egl_device_integration()->supportsSurfacelessContexts()) - flags |= QEGLPlatformContext::NoSurfaceless; - return new QEGLPbuffer(dpy, fmt, surface, flags); - } else { - return new QEglFSOffscreenWindow(dpy, fmt, surface); - } - // Never return null. Multiple QWindows are not supported by this plugin. -} -#endif // QT_NO_OPENGL - -#if QT_CONFIG(vulkan) -QPlatformVulkanInstance *QEglFSIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const -{ - return qt_egl_device_integration()->createPlatformVulkanInstance(instance); -} -#endif - -bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - // We assume that devices will have more and not less capabilities - if (qt_egl_device_integration()->hasCapability(cap)) - return true; - - switch (cap) { - case ThreadedPixmaps: return true; -#ifndef QT_NO_OPENGL - case OpenGL: return true; - case ThreadedOpenGL: return true; - case RasterGLSurface: return true; -#else - case OpenGL: return false; - case ThreadedOpenGL: return false; - case RasterGLSurface: return false; -#endif - case WindowManagement: return false; - case OpenGLOnRasterSurface: return true; - default: return QPlatformIntegration::hasCapability(cap); - } -} - -QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const -{ - return const_cast(this); -} - -enum ResourceType { - EglDisplay, - EglWindow, - EglContext, - EglConfig, - NativeDisplay, - XlibDisplay, - WaylandDisplay, - EglSurface, - VkSurface -}; - -static int resourceType(const QByteArray &key) -{ - static const QByteArray names[] = { // match ResourceType - QByteArrayLiteral("egldisplay"), - QByteArrayLiteral("eglwindow"), - QByteArrayLiteral("eglcontext"), - QByteArrayLiteral("eglconfig"), - QByteArrayLiteral("nativedisplay"), - QByteArrayLiteral("display"), - QByteArrayLiteral("server_wl_display"), - QByteArrayLiteral("eglsurface"), - QByteArrayLiteral("vksurface") - }; - const QByteArray *end = names + sizeof(names) / sizeof(names[0]); - const QByteArray *result = std::find(names, end, key); - if (result == end) - result = std::find(names, end, key.toLower()); - return int(result - names); -} - -void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource) -{ - void *result = nullptr; - - switch (resourceType(resource)) { - case EglDisplay: - result = display(); - break; - case NativeDisplay: - result = reinterpret_cast(nativeDisplay()); - break; - case WaylandDisplay: - result = qt_egl_device_integration()->wlDisplay(); - break; - default: - result = qt_egl_device_integration()->nativeResourceForIntegration(resource); - break; - } - - return result; -} - -void *QEglFSIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) -{ - void *result = nullptr; - - switch (resourceType(resource)) { - case XlibDisplay: - // Play nice when using the x11 hooks: Be compatible with xcb that allows querying - // the X Display pointer, which is nothing but our native display. - result = reinterpret_cast(nativeDisplay()); - break; - default: - result = qt_egl_device_integration()->nativeResourceForScreen(resource, screen); - break; - } - - return result; -} - -void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) -{ - void *result = nullptr; - - switch (resourceType(resource)) { - case EglDisplay: - if (window && window->handle()) - result = static_cast(window->handle()->screen())->display(); - else - result = display(); - break; - case EglWindow: - if (window && window->handle()) - result = reinterpret_cast(static_cast(window->handle())->eglWindow()); - break; - case EglSurface: - if (window && window->handle()) - result = reinterpret_cast(static_cast(window->handle())->surface()); - break; -#if QT_CONFIG(vulkan) - case VkSurface: - if (window && window->handle() && window->surfaceType() == QSurface::VulkanSurface) - result = static_cast(window->handle())->vulkanSurfacePtr(); - break; -#endif - default: - break; - } - - return result; -} - -#ifndef QT_NO_OPENGL -void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) -{ - void *result = nullptr; - - switch (resourceType(resource)) { - case EglContext: - if (context->handle()) - result = static_cast(context->handle())->eglContext(); - break; - case EglConfig: - if (context->handle()) - result = static_cast(context->handle())->eglConfig(); - break; - case EglDisplay: - if (context->handle()) - result = static_cast(context->handle())->eglDisplay(); - break; - default: - break; - } - - return result; -} - -static void *eglContextForContext(QOpenGLContext *context) -{ - Q_ASSERT(context); - - QEglFSContext *handle = static_cast(context->handle()); - if (!handle) - return nullptr; - - return handle->eglContext(); -} -#endif - -QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource) -{ -#ifndef QT_NO_OPENGL - if (resource.compare("get_egl_context", Qt::CaseInsensitive) == 0) - return NativeResourceForContextFunction(eglContextForContext); -#else - Q_UNUSED(resource); -#endif - return nullptr; -} - -QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) const -{ - if (function == Aurora::PlatformSupport::EglFSFunctions::setCursorThemeIdentifier()) - return QFunctionPointer(setCursorThemeStatic); - else if (function == Aurora::PlatformSupport::EglFSFunctions::getPowerStateIdentifier()) - return QFunctionPointer(getPowerStateStatic); - else if (function == Aurora::PlatformSupport::EglFSFunctions::setPowerStateIdentifier()) - return QFunctionPointer(setPowerStateStatic); - else if (function == Aurora::PlatformSupport::EglFSFunctions::enableScreenCastIdentifier()) - return QFunctionPointer(enableScreenCastStatic); - else if (function == Aurora::PlatformSupport::EglFSFunctions::disableScreenCastIdentifier()) - return QFunctionPointer(disableScreenCastStatic); - - return qt_egl_device_integration()->platformFunction(function); -} - -void QEglFSIntegration::createInputHandlers() -{ - m_liHandler.reset(new Aurora::PlatformSupport::LibInputManager(this)); -} - -void QEglFSIntegration::setCursorThemeStatic(const QString &name, int size) -{ - const auto screens = qGuiApp->screens(); - for (auto *screen : screens) { - auto *platformScreen = static_cast(screen->handle()); - if (platformScreen) - platformScreen->setCursorTheme(name, size); - } -} - -Aurora::PlatformSupport::EglFSFunctions::PowerState QEglFSIntegration::getPowerStateStatic(QScreen *screen) -{ - QPlatformScreen::PowerState powerState = screen->handle()->powerState(); - switch (powerState) { - case QPlatformScreen::PowerStateOn: - return Aurora::PlatformSupport::EglFSFunctions::PowerStateOn; - case QPlatformScreen::PowerStateOff: - return Aurora::PlatformSupport::EglFSFunctions::PowerStateOff; - case QPlatformScreen::PowerStateStandby: - return Aurora::PlatformSupport::EglFSFunctions::PowerStateStandby; - case QPlatformScreen::PowerStateSuspend: - return Aurora::PlatformSupport::EglFSFunctions::PowerStateSuspend; - } - Q_UNREACHABLE(); -} - -void QEglFSIntegration::setPowerStateStatic(QScreen *screen, Aurora::PlatformSupport::EglFSFunctions::PowerState powerState) -{ - switch (powerState) { - case Aurora::PlatformSupport::EglFSFunctions::PowerStateOn: - screen->handle()->setPowerState(QPlatformScreen::PowerStateOn); - break; - case Aurora::PlatformSupport::EglFSFunctions::PowerStateOff: - screen->handle()->setPowerState(QPlatformScreen::PowerStateOff); - break; - case Aurora::PlatformSupport::EglFSFunctions::PowerStateStandby: - screen->handle()->setPowerState(QPlatformScreen::PowerStateStandby); - break; - case Aurora::PlatformSupport::EglFSFunctions::PowerStateSuspend: - screen->handle()->setPowerState(QPlatformScreen::PowerStateSuspend); - break; - } -} - -void QEglFSIntegration::enableScreenCastStatic(QScreen *screen) -{ - QEglFSScreen *platformScreen = static_cast(screen->handle()); - platformScreen->setRecordingEnabled(true); -} - -void QEglFSIntegration::disableScreenCastStatic(QScreen *screen) -{ - QEglFSScreen *platformScreen = static_cast(screen->handle()); - platformScreen->setRecordingEnabled(false); -} - -EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const -{ - return qt_egl_device_integration()->platformDisplay(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h deleted file mode 100644 index ae5eb10e..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include -#include -#include -#include -#include -#include - -#include - -namespace Aurora { -namespace PlatformSupport { -class LibInputManager; -class VtHandler; -} -} - -QT_BEGIN_NAMESPACE - -class QEglFSWindow; -class QEglFSContext; -class QEglFSLogindHandler; -class QFbVtHandler; -class QEvdevKeyboardManager; - -class Q_EGLFS_EXPORT QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface -{ -public: - QEglFSIntegration(); - - void initialize() override; - void destroy() override; - - EGLDisplay display() const { return m_display; } - - QAbstractEventDispatcher *createEventDispatcher() const override; - QPlatformFontDatabase *fontDatabase() const override; - QPlatformServices *services() const override; - QPlatformInputContext *inputContext() const override { return m_inputContext; } - QPlatformTheme *createPlatformTheme(const QString &name) const override; - - QPlatformWindow *createPlatformWindow(QWindow *window) const override; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; -#ifndef QT_NO_OPENGL - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; - QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; -#endif -#if QT_CONFIG(vulkan) - QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override; -#endif - bool hasCapability(QPlatformIntegration::Capability cap) const override; - - QPlatformNativeInterface *nativeInterface() const override; - - // QPlatformNativeInterface - void *nativeResourceForIntegration(const QByteArray &resource) override; - void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override; - void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override; -#ifndef QT_NO_OPENGL - void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override; -#endif - NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) override; - - QFunctionPointer platformFunction(const QByteArray &function) const override; - - Aurora::PlatformSupport::VtHandler *vtHandler() { return m_vtHandler.data(); } - - QPointer pointerWindow() { return m_pointerWindow; } - void setPointerWindow(QWindow *pointerWindow) { m_pointerWindow = pointerWindow; } - -private: - EGLNativeDisplayType nativeDisplay() const; - void createInputHandlers(); - - static void setCursorThemeStatic(const QString &name, int size); - static Aurora::PlatformSupport::EglFSFunctions::PowerState getPowerStateStatic(QScreen *screen); - static void setPowerStateStatic(QScreen *screen, Aurora::PlatformSupport::EglFSFunctions::PowerState powerState); - - static void enableScreenCastStatic(QScreen *screen); - static void disableScreenCastStatic(QScreen *screen); - - EGLDisplay m_display; - QPlatformInputContext *m_inputContext; - QScopedPointer m_fontDb; - QScopedPointer m_services; - QScopedPointer m_vtHandler; - QScopedPointer m_liHandler; - QEglFSLogindHandler *m_logindHandler; - QPointer m_pointerWindow; - bool m_disableInputHandlers; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfslogindhandler.cpp b/src/plugins/platforms/eglfs/api/qeglfslogindhandler.cpp deleted file mode 100644 index 7d52aca3..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfslogindhandler.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Pier Luigi Fiorini -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfshooks_p.h" -#include "qeglfslogindhandler_p.h" - -#include - -using namespace Aurora::PlatformSupport; - -QEglFSLogindHandler::QEglFSLogindHandler() - : QObject() - , m_loop(new QEventLoop(this)) -{ -} - -void QEglFSLogindHandler::initialize() -{ - // Connect to logind and take control - Logind *logind = Logind::instance(); - if (logind->isConnected()) { - qCDebug(qLcEglDevDebug) << "logind connection already established"; - takeControl(true); - } else { - qCDebug(qLcEglDevDebug) << "logind connection not yet established"; - connect(logind, &Logind::connectedChanged, - this, &QEglFSLogindHandler::takeControl, - Qt::QueuedConnection); - } - - // Wait for logind setup - m_loop->exec(); -} - -void QEglFSLogindHandler::stop() -{ - m_loop->quit(); -} - -void QEglFSLogindHandler::takeControl(bool connected) -{ - if (!connected) - return; - - Logind *logind = Logind::instance(); - - disconnect(logind, &Logind::connectedChanged, - this, &QEglFSLogindHandler::takeControl); - - if (logind->hasSessionControl()) { - qCDebug(qLcEglDevDebug) << "Session control already acquired via logind"; - Q_EMIT initializationRequested(); - } else { - qCDebug(qLcEglDevDebug) << "Take control of session via logind"; - logind->takeControl(); - connect(logind, &Logind::hasSessionControlChanged, - this, &QEglFSLogindHandler::initializationRequested, - Qt::QueuedConnection); - } -} diff --git a/src/plugins/platforms/eglfs/api/qeglfslogindhandler_p.h b/src/plugins/platforms/eglfs/api/qeglfslogindhandler_p.h deleted file mode 100644 index 2eff422b..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfslogindhandler_p.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 Pier Luigi Fiorini -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include - -#include "qeglfsglobal_p.h" - -QT_BEGIN_NAMESPACE - -class Q_EGLFS_EXPORT QEglFSLogindHandler : public QObject -{ - Q_OBJECT -public: - QEglFSLogindHandler(); - - void initialize(); - void stop(); - -Q_SIGNALS: - void initializationRequested(); - -private Q_SLOTS: - void takeControl(bool connected); - -private: - QEventLoop *m_loop; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp deleted file mode 100644 index c96e3298..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfsoffscreenwindow_p.h" -#include "qeglfshooks_p.h" -#include -#include - -QT_BEGIN_NAMESPACE - -/* - In some cases pbuffers are not available. Triggering QtGui's built-in - fallback for a hidden QWindow is not suitable for eglfs since this would be - treated as an attempt to create multiple top-level, native windows. - - Therefore this class is provided as an alternative to QEGLPbuffer. - - This class requires the hooks to implement createNativeOffscreenWindow(). -*/ - -QEglFSOffscreenWindow::QEglFSOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface) - : QPlatformOffscreenSurface(offscreenSurface) - , m_format(format) - , m_display(display) - , m_surface(EGL_NO_SURFACE) - , m_window(0) -{ - m_window = qt_egl_device_integration()->createNativeOffscreenWindow(format); - if (!m_window) { - qWarning("QEglFSOffscreenWindow: Failed to create native window"); - return; - } - EGLConfig config = q_configFromGLFormat(m_display, m_format); - m_surface = eglCreateWindowSurface(m_display, config, m_window, nullptr); - if (m_surface != EGL_NO_SURFACE) - m_format = q_glFormatFromConfig(m_display, config); -} - -QEglFSOffscreenWindow::~QEglFSOffscreenWindow() -{ - if (m_surface != EGL_NO_SURFACE) - eglDestroySurface(m_display, m_surface); - if (m_window) - qt_egl_device_integration()->destroyNativeWindow(m_window); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h deleted file mode 100644 index 7264a884..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include - -QT_BEGIN_NAMESPACE - -class Q_EGLFS_EXPORT QEglFSOffscreenWindow : public QPlatformOffscreenSurface -{ -public: - QEglFSOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface); - ~QEglFSOffscreenWindow(); - - QSurfaceFormat format() const override { return m_format; } - bool isValid() const override { return m_surface != EGL_NO_SURFACE; } - -private: - QSurfaceFormat m_format; - EGLDisplay m_display; - EGLSurface m_surface; - EGLNativeWindowType m_window; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp deleted file mode 100644 index aaf8abd6..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#ifndef QT_NO_OPENGL -# include -#endif - -#include "qeglfscursor_p.h" -#include "qeglfsscreen_p.h" -#include "qeglfswindow_p.h" -#include "qeglfshooks_p.h" - -QT_BEGIN_NAMESPACE - -QEglFSScreen::QEglFSScreen(EGLDisplay dpy) - : m_dpy(dpy), - m_surface(EGL_NO_SURFACE), - m_cursor(nullptr) -{ - m_cursor = qt_egl_device_integration()->createCursor(this); -} - -QEglFSScreen::~QEglFSScreen() -{ - delete m_cursor; -} - -QRect QEglFSScreen::geometry() const -{ - QRect r = rawGeometry(); - - static int rotation = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION"); - switch (rotation) { - case 0: - case 180: - case -180: - break; - case 90: - case -90: { - int h = r.height(); - r.setHeight(r.width()); - r.setWidth(h); - break; - } - default: - qWarning("Invalid rotation %d specified in QT_QPA_EGLFS_ROTATION", rotation); - break; - } - - return r; -} - -QRect QEglFSScreen::rawGeometry() const -{ - return QRect(QPoint(0, 0), qt_egl_device_integration()->screenSize()); -} - -int QEglFSScreen::depth() const -{ - return qt_egl_device_integration()->screenDepth(); -} - -QImage::Format QEglFSScreen::format() const -{ - return qt_egl_device_integration()->screenFormat(); -} - -QSizeF QEglFSScreen::physicalSize() const -{ - return qt_egl_device_integration()->physicalScreenSize(); -} - -QDpi QEglFSScreen::logicalDpi() const -{ - return qt_egl_device_integration()->logicalDpi(); -} - -qreal QEglFSScreen::pixelDensity() const -{ - if (m_scaleFactor > 1) - return m_scaleFactor; - return qt_egl_device_integration()->pixelDensity(); -} - -Qt::ScreenOrientation QEglFSScreen::nativeOrientation() const -{ - return qt_egl_device_integration()->nativeOrientation(); -} - -Qt::ScreenOrientation QEglFSScreen::orientation() const -{ - return qt_egl_device_integration()->orientation(); -} - -QPlatformCursor *QEglFSScreen::cursor() const -{ - return m_cursor; -} - -qreal QEglFSScreen::refreshRate() const -{ - return qt_egl_device_integration()->refreshRate(); -} - -void QEglFSScreen::setPrimarySurface(EGLSurface surface) -{ - m_surface = surface; -} - -void QEglFSScreen::handleCursorMove(const QPoint &pos) -{ -#ifndef QT_NO_OPENGL - const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - const QList windows = compositor->windows(); - QEglFSIntegration *platformIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); - - // Generate enter and leave events like a real windowing system would do. - if (windows.isEmpty()) - return; - - // First window is always fullscreen. - if (windows.count() == 1) { - QWindow *window = windows[0]->sourceWindow(); - if (platformIntegration->pointerWindow() != window) { - platformIntegration->setPointerWindow(window); - QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); - } - return; - } - - QWindow *enter = nullptr, *leave = nullptr; - for (int i = windows.count() - 1; i >= 0; --i) { - QWindow *window = windows[i]->sourceWindow(); - const QRect geom = window->geometry(); - if (geom.contains(pos)) { - if (platformIntegration->pointerWindow() != window) { - leave = platformIntegration->pointerWindow(); - platformIntegration->setPointerWindow(window); - enter = window; - } - break; - } - } - - if (enter && leave) { - QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); - } else if (enter) { - QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(pos), pos); - } else if (leave) { - QWindowSystemInterface::handleLeaveEvent(leave); - } -#else - Q_UNUSED(pos); -#endif -} - -qreal QEglFSScreen::scaleFactor() const -{ - return m_scaleFactor; -} - -void QEglFSScreen::setScaleFactor(qreal factor) -{ - m_scaleFactor = factor; -} - -void QEglFSScreen::setCursorTheme(const QString &name, int size) -{ - auto *cursor = static_cast(m_cursor); - if (cursor) - cursor->setCursorTheme(name, size); -} - -QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) const -{ -#ifndef QT_NO_OPENGL - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - const QList windows = compositor->windows(); - Q_ASSERT(!windows.isEmpty()); - - QImage img; - - if (static_cast(windows.first()->sourceWindow()->handle())->isRaster()) { - // Request the compositor to render everything into an FBO and read it back. This - // is of course slow, but it's safe and reliable. It will not include the mouse - // cursor, which is a plus. - img = compositor->grab(); - } else { - // Just a single OpenGL window without compositing. Do not support this case for now. Doing - // glReadPixels is not an option since it would read from the back buffer which may have - // undefined content when calling right after a swapBuffers (unless preserved swap is - // available and enabled, but we have no support for that). - qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead."); - return QPixmap(); - } - - if (!wid) { - const QSize screenSize = geometry().size(); - if (width < 0) - width = screenSize.width() - x; - if (height < 0) - height = screenSize.height() - y; - return QPixmap::fromImage(img).copy(x, y, width, height); - } - - foreach (QOpenGLCompositorWindow *w, windows) { - const QWindow *window = w->sourceWindow(); - if (window->winId() == wid) { - const QRect geom = window->geometry(); - if (width < 0) - width = geom.width() - x; - if (height < 0) - height = geom.height() - y; - QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); - rect &= window->geometry(); - return QPixmap::fromImage(img).copy(rect); - } - } -#else // QT_NO_OPENGL - Q_UNUSED(wid); - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(width); - Q_UNUSED(height); -#endif - return QPixmap(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h deleted file mode 100644 index caafbbcb..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include - -#include - -QT_BEGIN_NAMESPACE - -class QEglFSWindow; -class QOpenGLContext; - -class Q_EGLFS_EXPORT QEglFSScreen : public QPlatformScreen -{ -public: - QEglFSScreen(EGLDisplay display); - ~QEglFSScreen(); - - QRect geometry() const override; - virtual QRect rawGeometry() const; - int depth() const override; - QImage::Format format() const override; - - QSizeF physicalSize() const override; - QDpi logicalDpi() const override; - qreal pixelDensity() const override; - Qt::ScreenOrientation nativeOrientation() const override; - Qt::ScreenOrientation orientation() const override; - - QPlatformCursor *cursor() const override; - - qreal refreshRate() const override; - - QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override; - - EGLSurface primarySurface() const { return m_surface; } - - EGLDisplay display() const { return m_dpy; } - - void handleCursorMove(const QPoint &pos); - - qreal scaleFactor() const; - void setScaleFactor(qreal factor); - - virtual void setCursorTheme(const QString &name, int size); - - virtual bool modeChangeRequested() const { return m_modeChangeRequested; } - virtual void setModeChangeRequested(bool enabled) { m_modeChangeRequested = enabled; } - - bool isRecordingEnabled() const { return m_recordingEnabled; } - void setRecordingEnabled(bool enabled) { m_recordingEnabled = enabled; } - -protected: - bool m_modeChangeRequested = false; - -private: - void setPrimarySurface(EGLSurface surface); - - EGLDisplay m_dpy; - EGLSurface m_surface; - QPlatformCursor *m_cursor; - qreal m_scaleFactor = 1; - bool m_recordingEnabled = false; - - friend class QEglFSWindow; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp deleted file mode 100644 index 24cd2528..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#ifndef QT_NO_OPENGL -# include -# include -# include -#endif -#include - -#include "qeglfswindow_p.h" -#ifndef QT_NO_OPENGL -# include "qeglfscursor_p.h" -#endif -#include "qeglfshooks_p.h" -#include "qeglfsdeviceintegration_p.h" - -QT_BEGIN_NAMESPACE - -QEglFSWindow::QEglFSWindow(QWindow *w) - : QPlatformWindow(w), -#ifndef QT_NO_OPENGL - m_backingStore(nullptr), - m_rasterCompositingContext(nullptr), -#endif - m_winId(0), - m_surface(EGL_NO_SURFACE), - m_window(0) -{ -} - -QEglFSWindow::~QEglFSWindow() -{ - destroy(); -} - -static WId newWId() -{ - static WId id = 0; - - if (id == std::numeric_limits::max()) - qWarning("QEGLPlatformWindow: Out of window IDs"); - - return ++id; -} - -void QEglFSWindow::create() -{ - if (m_flags.testFlag(Created)) - return; - - m_winId = newWId(); - - if (window()->type() == Qt::Desktop) { - QRect fullscreenRect(QPoint(), screen()->availableGeometry().size()); - QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect); - return; - } - - m_flags = Created; - - if (window()->type() == Qt::Desktop) - return; - - // Stop if there is already a window backed by a native window and surface. Additional - // raster windows will not have their own native window, surface and context. Instead, - // they will be composited onto the root window's surface. - QEglFSScreen *screen = this->screen(); -#ifndef QT_NO_OPENGL - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - if (screen->primarySurface() != EGL_NO_SURFACE) { - if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) { -#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED) - // We can have either a single OpenGL window or multiple raster windows. - // Other combinations cannot work. - qFatal("EGLFS: OpenGL windows cannot be mixed with others."); -#endif - return; - } - m_format = compositor->targetWindow()->format(); - return; - } -#endif // QT_NO_OPENGL - - m_flags |= HasNativeWindow; - setGeometry(QRect()); // will become fullscreen - - resetSurface(); - - if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) { - EGLint error = eglGetError(); - eglTerminate(screen->display()); - qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); - } - - screen->setPrimarySurface(m_surface); - -#ifndef QT_NO_OPENGL - if (isRaster()) { - m_rasterCompositingContext = new QOpenGLContext; - m_rasterCompositingContext->setShareContext(qt_gl_global_share_context()); - m_rasterCompositingContext->setFormat(m_format); - m_rasterCompositingContext->setScreen(window()->screen()); - if (Q_UNLIKELY(!m_rasterCompositingContext->create())) - qFatal("EGLFS: Failed to create compositing context"); - compositor->setTarget(m_rasterCompositingContext, window(), screen->rawGeometry()); - compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION")); - // If there is a "root" window into which raster and QOpenGLWidget content is - // composited, all other contexts must share with its context. - if (!qt_gl_global_share_context()) - qt_gl_set_global_share_context(m_rasterCompositingContext); - } -#endif // QT_NO_OPENGL -} - -void QEglFSWindow::destroy() -{ - if (!m_flags.testFlag(Created)) - return; // already destroyed - -#ifndef QT_NO_OPENGL - QOpenGLCompositor::instance()->removeWindow(this); -#endif - - QEglFSScreen *screen = this->screen(); - if (m_flags.testFlag(HasNativeWindow)) { -#ifndef QT_NO_OPENGL - QEglFSCursor *cursor = qobject_cast(screen->cursor()); - if (cursor) - cursor->resetResources(); -#endif - if (screen->primarySurface() == m_surface) - screen->setPrimarySurface(EGL_NO_SURFACE); - - invalidateSurface(); - -#ifndef QT_NO_OPENGL - QOpenGLCompositor::destroy(); - delete m_rasterCompositingContext; -#endif - } - - m_flags = { }; -} - -void QEglFSWindow::invalidateSurface() -{ - if (m_surface != EGL_NO_SURFACE) { - eglDestroySurface(screen()->display(), m_surface); - m_surface = EGL_NO_SURFACE; - } - qt_egl_device_integration()->destroyNativeWindow(m_window); - m_window = 0; -} - -void QEglFSWindow::resetSurface() -{ - EGLDisplay display = screen()->display(); - QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat()); - - m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); - m_format = q_glFormatFromConfig(display, m_config, platformFormat); - const QSize surfaceSize = screen()->rawGeometry().size(); - m_window = qt_egl_device_integration()->createNativeWindow(this, surfaceSize, m_format); -} - -bool QEglFSWindow::resizeSurface(const QSize &size) -{ - EGLDisplay display = screen()->display(); - EGLNativeWindowType window = qt_egl_device_integration()->createNativeWindow(this, size, m_format); - EGLSurface surface = eglCreateWindowSurface(display, m_config, window, nullptr); - - if (Q_UNLIKELY(surface == EGL_NO_SURFACE)) { - qt_egl_device_integration()->destroyNativeWindow(window); - return false; - } - - // Keep track of the old surface - EGLSurface oldSurface = m_surface; - EGLNativeWindowType oldWindow = m_window; - - // Switch to the new one - screen()->setPrimarySurface(surface); - m_window = window; - m_surface = surface; - - // New surface created: destroy the old one - if (oldSurface != EGL_NO_SURFACE) - eglDestroySurface(display, oldSurface); - if (oldWindow) - qt_egl_device_integration()->destroyNativeWindow(oldWindow); - - return true; -} - -void QEglFSWindow::setVisible(bool visible) -{ -#ifndef QT_NO_OPENGL - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - QList windows = compositor->windows(); - QWindow *wnd = window(); - - if (wnd->type() != Qt::Desktop) { - if (visible) { - compositor->addWindow(this); - } else { - compositor->removeWindow(this); - windows = compositor->windows(); - if (windows.size()) - windows.last()->sourceWindow()->requestActivate(); - } - } -#else - QWindow *wnd = window(); -#endif - QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); - - if (visible) - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); -} - -void QEglFSWindow::setGeometry(const QRect &r) -{ - QRect rect = r; - if (m_flags.testFlag(HasNativeWindow)) - rect = screen()->availableGeometry(); - - QPlatformWindow::setGeometry(rect); - - QWindowSystemInterface::handleGeometryChange(window(), rect); - - const QRect lastReportedGeometry = qt_window_private(window())->geometry; - if (rect != lastReportedGeometry) - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size())); -} - -QRect QEglFSWindow::geometry() const -{ - // For yet-to-become-fullscreen windows report the geometry covering the entire - // screen. This is particularly important for Quick where the root object may get - // sized to some geometry queried before calling create(). - if (!m_flags.testFlag(Created) && screen()->primarySurface() == EGL_NO_SURFACE) - return screen()->availableGeometry(); - - return QPlatformWindow::geometry(); -} - -void QEglFSWindow::requestActivateWindow() -{ -#ifndef QT_NO_OPENGL - if (window()->type() != Qt::Desktop) - QOpenGLCompositor::instance()->moveToTop(this); -#endif - QWindow *wnd = window(); - QWindowSystemInterface::handleWindowActivated(wnd); - QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); -} - -void QEglFSWindow::raise() -{ - QWindow *wnd = window(); - if (wnd->type() != Qt::Desktop) { -#ifndef QT_NO_OPENGL - QOpenGLCompositor::instance()->moveToTop(this); -#endif - QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); - } -} - -void QEglFSWindow::lower() -{ -#ifndef QT_NO_OPENGL - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - QList windows = compositor->windows(); - if (window()->type() != Qt::Desktop && windows.count() > 1) { - int idx = windows.indexOf(this); - if (idx > 0) { - compositor->changeWindowIndex(this, idx - 1); - QWindowSystemInterface::handleExposeEvent(windows.last()->sourceWindow(), - QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size())); - } - } -#endif -} - -EGLSurface QEglFSWindow::surface() const -{ - return m_surface != EGL_NO_SURFACE ? m_surface : screen()->primarySurface(); -} - -QSurfaceFormat QEglFSWindow::format() const -{ - return m_format; -} - -EGLNativeWindowType QEglFSWindow::eglWindow() const -{ - return m_window; -} - -QEglFSScreen *QEglFSWindow::screen() const -{ - return static_cast(QPlatformWindow::screen()); -} - -bool QEglFSWindow::isRaster() const -{ - const QWindow::SurfaceType type = window()->surfaceType(); - return type == QSurface::RasterSurface || type == QSurface::RasterGLSurface; -} - -#ifndef QT_NO_OPENGL -QWindow *QEglFSWindow::sourceWindow() const -{ - return window(); -} - -const QPlatformTextureList *QEglFSWindow::textures() const -{ - if (m_backingStore) - return m_backingStore->textures(); - - return nullptr; -} - -void QEglFSWindow::endCompositing() -{ - if (m_backingStore) - m_backingStore->notifyComposited(); -} -#endif - -WId QEglFSWindow::winId() const -{ - return m_winId; -} - -void QEglFSWindow::setOpacity(qreal) -{ - if (!isRaster()) - qWarning("QEglFSWindow: Cannot set opacity for non-raster windows"); - - // Nothing to do here. The opacity is stored in the QWindow. -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h deleted file mode 100644 index 1e886132..00000000 --- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Aurora API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qeglfsglobal_p.h" -#include "qeglfsintegration_p.h" -#include "qeglfsscreen_p.h" - -#include -#ifndef QT_NO_OPENGL -# include -#endif - -QT_BEGIN_NAMESPACE - -class QOpenGLCompositorBackingStore; -class QPlatformTextureList; - -#ifndef QT_NO_OPENGL -class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow -#else -class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow -#endif -{ -public: - QEglFSWindow(QWindow *w); - ~QEglFSWindow(); - - void create(); - void destroy(); - - void setGeometry(const QRect &) override; - QRect geometry() const override; - void setVisible(bool visible) override; - void requestActivateWindow() override; - void raise() override; - void lower() override; - - void propagateSizeHints() override { } - void setMask(const QRegion &) override { } - bool setKeyboardGrabEnabled(bool) override { return false; } - bool setMouseGrabEnabled(bool) override { return false; } - void setOpacity(qreal) override; - WId winId() const override; - - QSurfaceFormat format() const override; - - EGLNativeWindowType eglWindow() const; - EGLSurface surface() const; - QEglFSScreen *screen() const override; -#if QT_CONFIG(vulkan) - virtual void *vulkanSurfacePtr() { return nullptr; } -#endif - - bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); } - - void invalidateSurface() override; - virtual void resetSurface(); - virtual bool resizeSurface(const QSize &size); - -#ifndef QT_NO_OPENGL - QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } - void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; } -#endif - bool isRaster() const; -#ifndef QT_NO_OPENGL - QWindow *sourceWindow() const override; - const QPlatformTextureList *textures() const override; - void endCompositing() override; -#endif - -protected: -#ifndef QT_NO_OPENGL - QOpenGLCompositorBackingStore *m_backingStore; - QOpenGLContext *m_rasterCompositingContext; -#endif - WId m_winId; - - EGLSurface m_surface; - EGLNativeWindowType m_window; - - EGLConfig m_config; - QSurfaceFormat m_format; - - enum Flag { - Created = 0x01, - HasNativeWindow = 0x02 - }; - Q_DECLARE_FLAGS(Flags, Flag) - Flags m_flags; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/api/vthandler.cpp b/src/plugins/platforms/eglfs/api/vthandler.cpp deleted file mode 100644 index 649663af..00000000 --- a/src/plugins/platforms/eglfs/api/vthandler.cpp +++ /dev/null @@ -1,437 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2015-2016 Pier Luigi Fiorini - * - * Author(s): - * Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include -#include - -#include - -#include "vthandler.h" -#include "vthandler_p.h" - -extern "C" { -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -} - -#ifndef KDSKBMUTE -#define KDSKBMUTE 0x4B51 -#endif - -#ifndef DRM_MAJOR -#define DRM_MAJOR 226 -#endif - -#define VT_HANDLER_LOGIND 1 - -Q_LOGGING_CATEGORY(lcVtHandler, "aurora.eglfs.vthandler", QtInfoMsg) - -namespace Aurora { - -namespace PlatformSupport { - -static VtHandler *vth; - -/* - * VtHandlerPrivate - */ - -VtHandlerPrivate::VtHandlerPrivate(VtHandler *self) - : logind(Logind::instance()) - , notifier(nullptr) - , vtFd(-1) - , vtNumber(0) - , kbMode(K_OFF) - , active(false) - , q_ptr(self) -{ - vth = self; - - // Disable the cursor - toggleTtyCursor(false); -} - -VtHandlerPrivate::~VtHandlerPrivate() -{ - toggleKeyboard(true); - toggleTtyCursor(true); - - if (notifier) { - ::close(signalFd[0]); - ::close(signalFd[1]); - } - - closeFd(); -} - -void VtHandlerPrivate::setup(int nr) -{ - Q_Q(VtHandler); - - // A fd already open means we are good - if (vtFd != -1) - return; - - // Need a valid vt number - if (nr < 0) { - qCWarning(lcVtHandler, "Invalid vt number"); - return; - } - - // Open the tty for this vt - devName = QStringLiteral("/dev/tty%1").arg(nr); - vtFd = ::open(qPrintable(devName), O_RDWR | O_CLOEXEC | O_NONBLOCK); - if (vtFd < 0) { - qCWarning(lcVtHandler, "Failed to open vt \"%s\": %s", - qPrintable(devName), ::strerror(errno)); - return; - } - - // Must be a valid vt - if (!isValidVt(vtFd)) { - qCWarning(lcVtHandler, "TTY \"%s\" is not a virtual terminal", - qPrintable(devName)); - closeFd(); - return; - } - - // Avoid input going to the tty - toggleKeyboard(false); - - // Graphics mode - if (::ioctl(vtFd, KDSETMODE, KD_GRAPHICS) < 0) { - qCWarning(lcVtHandler, "Unable to set KD_GRAPHICS mode on \"%s\": %s", - qPrintable(devName), ::strerror(errno)); - toggleKeyboard(true); - closeFd(); - return; - } - - // Signal handler - if (!installSignalHandler()) { - ::ioctl(vtFd, KDSETMODE, KD_TEXT); - toggleKeyboard(true); - closeFd(); - return; - } - -#if !VT_HANDLER_LOGIND - // Take over VT - vt_mode mode = { VT_PROCESS, 0, short(SIGRTMIN), short(SIGRTMIN), 0 }; - if (::ioctl(vtFd, VT_SETMODE, &mode) < 0) { - qCWarning(lcVtHandler, "Unable to take over VT \"%s\": %s", - qPrintable(devName), qPrintable(::strerror(errno))); - ::ioctl(vtFd, KDSETMODE, KD_TEXT); - toggleKeyboard(true); - closeFd(); - return ; - } -#endif - - vtNumber = nr; - setActive(true); - Q_EMIT q->created(); -} - -bool VtHandlerPrivate::installSignalHandler() -{ - Q_Q(VtHandler); - -#if !VT_HANDLER_LOGIND - // SIGRTMIN is used as global VT-release signal while SIGRTMIN + 1 is - // used as VT-acquire signal, these must be checked on runtime because - // their exact values are unknown at compile time; verify if we - // exceed the limit (POSIX has 32 of them) - if (SIGRTMIN > SIGRTMAX) { - qCWarning(lcVtHandler, "Not enough RT signals available: %u-%u", - SIGRTMIN, SIGRTMAX); - return false; - } -#endif - - if (::socketpair(AF_UNIX, SOCK_STREAM, 0, signalFd)) { - qCWarning(lcVtHandler, "Failed to create socket pair: %s", - ::strerror(errno)); - } - notifier = new QSocketNotifier(signalFd[1], QSocketNotifier::Read, q); - q->connect(notifier, &QSocketNotifier::activated, q, [this, q] { - if (vtFd < 0) - return; - - if (notifier) - notifier->setEnabled(false); - - char sigNo; - if (QT_READ(signalFd[1], &sigNo, sizeof(sigNo)) == sizeof(sigNo)) { - switch (sigNo) { - case SIGINT: - case SIGTERM: - Q_EMIT q->interrupted(); - toggleKeyboard(true); - toggleTtyCursor(true); - ::_exit(1); - case SIGTSTP: - Q_EMIT q->aboutToSuspend(); - toggleKeyboard(true); - toggleTtyCursor(true); - ::kill(::getpid(), SIGSTOP); - break; - case SIGCONT: - toggleKeyboard(false); - toggleTtyCursor(false); - Q_EMIT q->resumed(); - break; - default: - break; - } - -#if !VT_HANDLER_LOGIND - if (sigNo >= SIGRTMIN && sigNo <= SIGRTMAX) { - if (active) { - setActive(false); - ::ioctl(vtFd, VT_RELDISP, 1); - } else { - ::ioctl(vtFd, VT_RELDISP, VT_ACKACQ); - setActive(true); - } - } -#endif - } - - if (notifier) - notifier->setEnabled(true); - }); - - struct sigaction sa; - sa.sa_flags = 0; - sa.sa_handler = signalHandler; - ::sigemptyset(&sa.sa_mask); - ::sigaction(SIGINT, &sa, nullptr); - ::sigaction(SIGTSTP, &sa, nullptr); - ::sigaction(SIGCONT, &sa, nullptr); - ::sigaction(SIGTERM, &sa, nullptr); -#if !VT_HANDLER_LOGIND - ::sigaction(SIGRTMIN, &sa, nullptr); - ::sigaction(SIGRTMIN + 1, &sa, nullptr); -#endif - - return true; -} - -void VtHandlerPrivate::toggleTtyCursor(bool enable) -{ - int fd = -1; - - const char *const devices[] = { "/dev/tty0", "/dev/tty", "/dev/console", nullptr }; - for (const char *const *device = devices; *device; ++device) { - fd = ::open(*device, O_RDWR); - if (fd >= 0) { - const char *escape = enable - ? "\033[9;15]\033[?33h\033[?25h\033[?0c" - : "\033[9;0]\033[?33l\033[?25l\033[?1c"; - (void)::write(fd, escape, ::strlen(escape) + 1); - ::close(fd); - return; - } - } -} - -void VtHandlerPrivate::toggleKeyboard(bool enable) -{ - if (vtFd < 0) - return; - - if (enable) { - if (::ioctl(vtFd, KDSKBMUTE, 0) < 0) - qCWarning(lcVtHandler, "Unable to unmute keyboard on \"%s\": %s", - qPrintable(devName), ::strerror(errno)); - if (::ioctl(vtFd, KDSKBMODE, kbMode) < 0) - qCWarning(lcVtHandler, "Unable to restore keyboard mode on \"%s\": %s", - qPrintable(devName), ::strerror(errno)); - } else { - // Read keyboard mode - if (::ioctl(vtFd, KDGKBMODE, &kbMode) < 0) { - qCWarning(lcVtHandler, "Unable to read keyboard mode on \"%s\": %s", - qPrintable(devName), ::strerror(errno)); - kbMode = K_UNICODE; - } else if (kbMode == K_OFF) { - kbMode = K_UNICODE; - } - - if (!qEnvironmentVariableIntValue("QT_QPA_ENABLE_TERMINAL_KEYBOARD")) { - // Avoid input going to the tty - if (::ioctl(vtFd, KDSKBMUTE, 1) < 0 && - ::ioctl(vtFd, KDSKBMODE, K_OFF) < 0) { - qCWarning(lcVtHandler, "Unable to set K_OFF keyboard mode on \"%s\": %s", - qPrintable(devName), ::strerror(errno)); - closeFd(); - } - } - } -} - -void VtHandlerPrivate::closeFd() -{ - if (vtFd < 0) - return; - - if (notifier) { - delete notifier; - notifier = nullptr; - - ::close(signalFd[0]); - ::close(signalFd[1]); - } - - ::close(vtFd); - vtFd = -1; -} - -void VtHandlerPrivate::setActive(bool v) -{ - Q_Q(VtHandler); - - if (active == v) - return; - - active = v; - Q_EMIT q->activeChanged(v); -} - -bool VtHandlerPrivate::isValidVt(int fd) -{ - if (fd < 0) - return false; - - struct stat st; - if (::fstat(fd, &st) == -1) { - qCWarning(lcVtHandler) << "Failed to fstat tty"; - return false; - } - - if (major(st.st_rdev) != TTY_MAJOR || minor(st.st_rdev) <= 0 || - minor(st.st_rdev) >= 64) - return false; - - return true; -} - -void VtHandlerPrivate::signalHandler(int sigNo) -{ - char a = static_cast(sigNo); // sigNo fits 1 byte anyway - QT_WRITE(vth->d_func()->signalFd[0], &a, sizeof(a)); -} - -/* - * VtHandler - */ - -VtHandler::VtHandler(QObject *parent) - : QObject(parent) - , d_ptr(new VtHandlerPrivate(this)) -{ - Q_D(VtHandler); - - // Setup vt if we already know the number - if (d->logind->vtNumber() != -1) - d->setup(d->logind->vtNumber()); - - // Setup vt when the number will be assigned - connect(d->logind, &Logind::vtNumberChanged, this, [d](int nr) { - d->setup(nr); - }); - -#if VT_HANDLER_LOGIND - // Vt is active when the session is - connect(d->logind, &Logind::sessionActiveChanged, this, [d](bool active) { - d->setActive(active); - }); - - // Handle pause and resume of DRM devices - connect(d->logind, &Logind::devicePaused, this, [d] - (quint32 devMajor, quint32 devMinor, const QString &type) { - qCDebug(lcVtHandler, "Device with major %d minor %d paused with %s", - devMajor, devMinor, qPrintable(type)); - - if (type == QLatin1String("pause")) - d->logind->pauseDeviceComplete(devMajor, devMinor); - }); - connect(d->logind, &Logind::deviceResumed, this, [] - (quint32 devMajor, quint32 devMinor, int) { - qCDebug(lcVtHandler, "Device with major %d minor %d resumed", - devMajor, devMinor); - }); -#endif - - // Take control upon connection - if (d->logind->isConnected()) - d->logind->takeControl(); - else - connect(d->logind, &Logind::connectedChanged, - d->logind, &Logind::takeControl); -} - -VtHandler::~VtHandler() -{ - delete d_ptr; -} - -bool VtHandler::isActive() const -{ - Q_D(const VtHandler); - return d->active; -} - -void VtHandler::activate(quint32 nr) -{ - Q_D(VtHandler); - - if (d->vtFd < 0) - return; - - if (d->vtNumber == int(nr)) - return; - - qCDebug(lcVtHandler, "Switching to vt %d", nr); - d->logind->switchTo(nr); - d->setActive(false); -} - -} // namespace PlatformSupport - -} // namespace Aurora - -#include "moc_vthandler.cpp" diff --git a/src/plugins/platforms/eglfs/api/vthandler.h b/src/plugins/platforms/eglfs/api/vthandler.h deleted file mode 100644 index a3ab41bc..00000000 --- a/src/plugins/platforms/eglfs/api/vthandler.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include -#include - -#include "qeglfsglobal_p.h" - -Q_DECLARE_LOGGING_CATEGORY(lcVtHandler) - -namespace Aurora { - -namespace PlatformSupport { - -class VtHandlerPrivate; - -class Q_EGLFS_EXPORT VtHandler : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(VtHandler) -public: - explicit VtHandler(QObject *parent = nullptr); - ~VtHandler(); - - bool isActive() const; - - void activate(quint32 nr); - -Q_SIGNALS: - void created(); - void activeChanged(bool active); - void interrupted(); - void aboutToSuspend(); - void resumed(); - -private: - VtHandlerPrivate *const d_ptr; -}; - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/plugins/platforms/eglfs/api/vthandler_p.h b/src/plugins/platforms/eglfs/api/vthandler_p.h deleted file mode 100644 index 73b68262..00000000 --- a/src/plugins/platforms/eglfs/api/vthandler_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include -#include - -#pragma once - -namespace Aurora { - -namespace PlatformSupport { - -class Logind; -class VtHandler; - -class VtHandlerPrivate -{ - Q_DECLARE_PUBLIC(VtHandler) -public: - explicit VtHandlerPrivate(VtHandler *self); - ~VtHandlerPrivate(); - - void setup(int nr); - - bool installSignalHandler(); - void toggleTtyCursor(bool enable); - void toggleKeyboard(bool enable); - - void closeFd(); - - void setActive(bool v); - - static bool isValidVt(int fd); - static void signalHandler(int sigNo); - - Logind *logind; - - int signalFd[2]; - QSocketNotifier *notifier; - - int vtFd; - int vtNumber; - QString devName; - - int kbMode; - - bool active; - -protected: - VtHandler *q_ptr; -}; - -} // namespace PlatformSupport - -} // namespace Aurora diff --git a/src/plugins/platforms/eglfs/api/xcursor.c b/src/plugins/platforms/eglfs/api/xcursor.c deleted file mode 100644 index 0506680f..00000000 --- a/src/plugins/platforms/eglfs/api/xcursor.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * Copyright © 2002 Keith Packard - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "xcursor.h" -#include -#include -#include -#include - -/* - * From libXcursor/include/X11/extensions/Xcursor.h - */ - -#define XcursorTrue 1 -#define XcursorFalse 0 - -/* - * Cursor files start with a header. The header - * contains a magic number, a version number and a - * table of contents which has type and offset information - * for the remaining tables in the file. - * - * File minor versions increment for compatible changes - * File major versions increment for incompatible changes (never, we hope) - * - * Chunks of the same type are always upward compatible. Incompatible - * changes are made with new chunk types; the old data can remain under - * the old type. Upward compatible changes can add header data as the - * header lengths are specified in the file. - * - * File: - * FileHeader - * LISTofChunk - * - * FileHeader: - * CARD32 magic magic number - * CARD32 header bytes in file header - * CARD32 version file version - * CARD32 ntoc number of toc entries - * LISTofFileToc toc table of contents - * - * FileToc: - * CARD32 type entry type - * CARD32 subtype entry subtype (size for images) - * CARD32 position absolute file position - */ - -#define XCURSOR_MAGIC 0x72756358 /* "Xcur" LSBFirst */ - -/* - * Current Xcursor version number. Will be substituted by configure - * from the version in the libXcursor configure.ac file. - */ - -#define XCURSOR_LIB_MAJOR 1 -#define XCURSOR_LIB_MINOR 1 -#define XCURSOR_LIB_REVISION 13 -#define XCURSOR_LIB_VERSION ((XCURSOR_LIB_MAJOR * 10000) + \ - (XCURSOR_LIB_MINOR * 100) + \ - (XCURSOR_LIB_REVISION)) - -/* - * This version number is stored in cursor files; changes to the - * file format require updating this version number - */ -#define XCURSOR_FILE_MAJOR 1 -#define XCURSOR_FILE_MINOR 0 -#define XCURSOR_FILE_VERSION ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR)) -#define XCURSOR_FILE_HEADER_LEN (4 * 4) -#define XCURSOR_FILE_TOC_LEN (3 * 4) - -typedef struct _XcursorFileToc { - XcursorUInt type; /* chunk type */ - XcursorUInt subtype; /* subtype (size for images) */ - XcursorUInt position; /* absolute position in file */ -} XcursorFileToc; - -typedef struct _XcursorFileHeader { - XcursorUInt magic; /* magic number */ - XcursorUInt header; /* byte length of header */ - XcursorUInt version; /* file version number */ - XcursorUInt ntoc; /* number of toc entries */ - XcursorFileToc *tocs; /* table of contents */ -} XcursorFileHeader; - -/* - * The rest of the file is a list of chunks, each tagged by type - * and version. - * - * Chunk: - * ChunkHeader - * - * - * - * ChunkHeader: - * CARD32 header bytes in chunk header + type header - * CARD32 type chunk type - * CARD32 subtype chunk subtype - * CARD32 version chunk type version - */ - -#define XCURSOR_CHUNK_HEADER_LEN (4 * 4) - -typedef struct _XcursorChunkHeader { - XcursorUInt header; /* bytes in chunk header */ - XcursorUInt type; /* chunk type */ - XcursorUInt subtype; /* chunk subtype (size for images) */ - XcursorUInt version; /* version of this type */ -} XcursorChunkHeader; - -/* - * Here's a list of the known chunk types - */ - -/* - * Comments consist of a 4-byte length field followed by - * UTF-8 encoded text - * - * Comment: - * ChunkHeader header chunk header - * CARD32 length bytes in text - * LISTofCARD8 text UTF-8 encoded text - */ - -#define XCURSOR_COMMENT_TYPE 0xfffe0001 -#define XCURSOR_COMMENT_VERSION 1 -#define XCURSOR_COMMENT_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (1 *4)) -#define XCURSOR_COMMENT_COPYRIGHT 1 -#define XCURSOR_COMMENT_LICENSE 2 -#define XCURSOR_COMMENT_OTHER 3 -#define XCURSOR_COMMENT_MAX_LEN 0x100000 - -typedef struct _XcursorComment { - XcursorUInt version; - XcursorUInt comment_type; - char *comment; -} XcursorComment; - -/* - * Each cursor image occupies a separate image chunk. - * The length of the image header follows the chunk header - * so that future versions can extend the header without - * breaking older applications - * - * Image: - * ChunkHeader header chunk header - * CARD32 width actual width - * CARD32 height actual height - * CARD32 xhot hot spot x - * CARD32 yhot hot spot y - * CARD32 delay animation delay - * LISTofCARD32 pixels ARGB pixels - */ - -#define XCURSOR_IMAGE_TYPE 0xfffd0002 -#define XCURSOR_IMAGE_VERSION 1 -#define XCURSOR_IMAGE_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (5*4)) -#define XCURSOR_IMAGE_MAX_SIZE 0x7fff /* 32767x32767 max cursor size */ - -typedef struct _XcursorFile XcursorFile; - -struct _XcursorFile { - void *closure; - int (*read) (XcursorFile *file, unsigned char *buf, int len); - int (*write) (XcursorFile *file, unsigned char *buf, int len); - int (*seek) (XcursorFile *file, long offset, int whence); -}; - -typedef struct _XcursorComments { - int ncomment; /* number of comments */ - XcursorComment **comments; /* array of XcursorComment pointers */ -} XcursorComments; - -/* - * From libXcursor/src/file.c - */ - -static XcursorImage * -XcursorImageCreate (int width, int height) -{ - XcursorImage *image; - - if (width < 0 || height < 0) - return NULL; - if (width > XCURSOR_IMAGE_MAX_SIZE || height > XCURSOR_IMAGE_MAX_SIZE) - return NULL; - - image = malloc (sizeof (XcursorImage) + - width * height * sizeof (XcursorPixel)); - if (!image) - return NULL; - image->version = XCURSOR_IMAGE_VERSION; - image->pixels = (XcursorPixel *) (image + 1); - image->size = width > height ? width : height; - image->width = width; - image->height = height; - image->delay = 0; - return image; -} - -static void -XcursorImageDestroy (XcursorImage *image) -{ - free (image); -} - -static XcursorImages * -XcursorImagesCreate (int size) -{ - XcursorImages *images; - - images = malloc (sizeof (XcursorImages) + - size * sizeof (XcursorImage *)); - if (!images) - return NULL; - images->nimage = 0; - images->images = (XcursorImage **) (images + 1); - images->name = NULL; - return images; -} - -void -XcursorImagesDestroy (XcursorImages *images) -{ - int n; - - if (!images) - return; - - for (n = 0; n < images->nimage; n++) - XcursorImageDestroy (images->images[n]); - if (images->name) - free (images->name); - free (images); -} - -static void -XcursorImagesSetName (XcursorImages *images, const char *name) -{ - char *new; - - if (!images || !name) - return; - - new = malloc (strlen (name) + 1); - - if (!new) - return; - - strcpy (new, name); - if (images->name) - free (images->name); - images->name = new; -} - -static XcursorBool -_XcursorReadUInt (XcursorFile *file, XcursorUInt *u) -{ - unsigned char bytes[4]; - - if (!file || !u) - return XcursorFalse; - - if ((*file->read) (file, bytes, 4) != 4) - return XcursorFalse; - - *u = ((XcursorUInt)(bytes[0]) << 0) | - ((XcursorUInt)(bytes[1]) << 8) | - ((XcursorUInt)(bytes[2]) << 16) | - ((XcursorUInt)(bytes[3]) << 24); - return XcursorTrue; -} - -static void -_XcursorFileHeaderDestroy (XcursorFileHeader *fileHeader) -{ - free (fileHeader); -} - -static XcursorFileHeader * -_XcursorFileHeaderCreate (XcursorUInt ntoc) -{ - XcursorFileHeader *fileHeader; - - if (ntoc > 0x10000) - return NULL; - fileHeader = malloc (sizeof (XcursorFileHeader) + - ntoc * sizeof (XcursorFileToc)); - if (!fileHeader) - return NULL; - fileHeader->magic = XCURSOR_MAGIC; - fileHeader->header = XCURSOR_FILE_HEADER_LEN; - fileHeader->version = XCURSOR_FILE_VERSION; - fileHeader->ntoc = ntoc; - fileHeader->tocs = (XcursorFileToc *) (fileHeader + 1); - return fileHeader; -} - -static XcursorFileHeader * -_XcursorReadFileHeader (XcursorFile *file) -{ - XcursorFileHeader head, *fileHeader; - XcursorUInt skip; - unsigned int n; - - if (!file) - return NULL; - - if (!_XcursorReadUInt (file, &head.magic)) - return NULL; - if (head.magic != XCURSOR_MAGIC) - return NULL; - if (!_XcursorReadUInt (file, &head.header)) - return NULL; - if (!_XcursorReadUInt (file, &head.version)) - return NULL; - if (!_XcursorReadUInt (file, &head.ntoc)) - return NULL; - skip = head.header - XCURSOR_FILE_HEADER_LEN; - if (skip) - if ((*file->seek) (file, skip, SEEK_CUR) == EOF) - return NULL; - fileHeader = _XcursorFileHeaderCreate (head.ntoc); - if (!fileHeader) - return NULL; - fileHeader->magic = head.magic; - fileHeader->header = head.header; - fileHeader->version = head.version; - fileHeader->ntoc = head.ntoc; - for (n = 0; n < fileHeader->ntoc; n++) - { - if (!_XcursorReadUInt (file, &fileHeader->tocs[n].type)) - break; - if (!_XcursorReadUInt (file, &fileHeader->tocs[n].subtype)) - break; - if (!_XcursorReadUInt (file, &fileHeader->tocs[n].position)) - break; - } - if (n != fileHeader->ntoc) - { - _XcursorFileHeaderDestroy (fileHeader); - return NULL; - } - return fileHeader; -} - -static XcursorBool -_XcursorSeekToToc (XcursorFile *file, - XcursorFileHeader *fileHeader, - int toc) -{ - if (!file || !fileHeader || \ - (*file->seek) (file, fileHeader->tocs[toc].position, SEEK_SET) == EOF) - return XcursorFalse; - return XcursorTrue; -} - -static XcursorBool -_XcursorFileReadChunkHeader (XcursorFile *file, - XcursorFileHeader *fileHeader, - int toc, - XcursorChunkHeader *chunkHeader) -{ - if (!file || !fileHeader || !chunkHeader) - return XcursorFalse; - if (!_XcursorSeekToToc (file, fileHeader, toc)) - return XcursorFalse; - if (!_XcursorReadUInt (file, &chunkHeader->header)) - return XcursorFalse; - if (!_XcursorReadUInt (file, &chunkHeader->type)) - return XcursorFalse; - if (!_XcursorReadUInt (file, &chunkHeader->subtype)) - return XcursorFalse; - if (!_XcursorReadUInt (file, &chunkHeader->version)) - return XcursorFalse; - /* sanity check */ - if (chunkHeader->type != fileHeader->tocs[toc].type || - chunkHeader->subtype != fileHeader->tocs[toc].subtype) - return XcursorFalse; - return XcursorTrue; -} - -#define dist(a,b) ((a) > (b) ? (a) - (b) : (b) - (a)) - -static XcursorDim -_XcursorFindBestSize (XcursorFileHeader *fileHeader, - XcursorDim size, - int *nsizesp) -{ - unsigned int n; - int nsizes = 0; - XcursorDim bestSize = 0; - XcursorDim thisSize; - - if (!fileHeader || !nsizesp) - return 0; - - for (n = 0; n < fileHeader->ntoc; n++) - { - if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE) - continue; - thisSize = fileHeader->tocs[n].subtype; - if (!bestSize || dist (thisSize, size) < dist (bestSize, size)) - { - bestSize = thisSize; - nsizes = 1; - } - else if (thisSize == bestSize) - nsizes++; - } - *nsizesp = nsizes; - return bestSize; -} - -static int -_XcursorFindImageToc (XcursorFileHeader *fileHeader, - XcursorDim size, - int count) -{ - unsigned int toc; - XcursorDim thisSize; - - if (!fileHeader) - return 0; - - for (toc = 0; toc < fileHeader->ntoc; toc++) - { - if (fileHeader->tocs[toc].type != XCURSOR_IMAGE_TYPE) - continue; - thisSize = fileHeader->tocs[toc].subtype; - if (thisSize != size) - continue; - if (!count) - break; - count--; - } - if (toc == fileHeader->ntoc) - return -1; - return toc; -} - -static XcursorImage * -_XcursorReadImage (XcursorFile *file, - XcursorFileHeader *fileHeader, - int toc) -{ - XcursorChunkHeader chunkHeader; - XcursorImage head; - XcursorImage *image; - int n; - XcursorPixel *p; - - if (!file || !fileHeader) - return NULL; - - if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader)) - return NULL; - if (!_XcursorReadUInt (file, &head.width)) - return NULL; - if (!_XcursorReadUInt (file, &head.height)) - return NULL; - if (!_XcursorReadUInt (file, &head.xhot)) - return NULL; - if (!_XcursorReadUInt (file, &head.yhot)) - return NULL; - if (!_XcursorReadUInt (file, &head.delay)) - return NULL; - /* sanity check data */ - if (head.width > XCURSOR_IMAGE_MAX_SIZE || - head.height > XCURSOR_IMAGE_MAX_SIZE) - return NULL; - if (head.width == 0 || head.height == 0) - return NULL; - if (head.xhot > head.width || head.yhot > head.height) - return NULL; - - /* Create the image and initialize it */ - image = XcursorImageCreate (head.width, head.height); - if (image == NULL) - return NULL; - if (chunkHeader.version < image->version) - image->version = chunkHeader.version; - image->size = chunkHeader.subtype; - image->xhot = head.xhot; - image->yhot = head.yhot; - image->delay = head.delay; - n = image->width * image->height; - p = image->pixels; - while (n--) - { - if (!_XcursorReadUInt (file, p)) - { - XcursorImageDestroy (image); - return NULL; - } - p++; - } - return image; -} - -static XcursorImages * -XcursorXcFileLoadImages (XcursorFile *file, int size) -{ - XcursorFileHeader *fileHeader; - XcursorDim bestSize; - int nsize; - XcursorImages *images; - int n; - int toc; - - if (!file || size < 0) - return NULL; - fileHeader = _XcursorReadFileHeader (file); - if (!fileHeader) - return NULL; - bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize); - if (!bestSize) - { - _XcursorFileHeaderDestroy (fileHeader); - return NULL; - } - images = XcursorImagesCreate (nsize); - if (!images) - { - _XcursorFileHeaderDestroy (fileHeader); - return NULL; - } - for (n = 0; n < nsize; n++) - { - toc = _XcursorFindImageToc (fileHeader, bestSize, n); - if (toc < 0) - break; - images->images[images->nimage] = _XcursorReadImage (file, fileHeader, - toc); - if (!images->images[images->nimage]) - break; - images->nimage++; - } - _XcursorFileHeaderDestroy (fileHeader); - if (images->nimage != nsize) - { - XcursorImagesDestroy (images); - images = NULL; - } - return images; -} - -static int -_XcursorStdioFileRead (XcursorFile *file, unsigned char *buf, int len) -{ - FILE *f = file->closure; - return fread (buf, 1, len, f); -} - -static int -_XcursorStdioFileWrite (XcursorFile *file, unsigned char *buf, int len) -{ - FILE *f = file->closure; - return fwrite (buf, 1, len, f); -} - -static int -_XcursorStdioFileSeek (XcursorFile *file, long offset, int whence) -{ - FILE *f = file->closure; - return fseek (f, offset, whence); -} - -static void -_XcursorStdioFileInitialize (FILE *stdfile, XcursorFile *file) -{ - file->closure = stdfile; - file->read = _XcursorStdioFileRead; - file->write = _XcursorStdioFileWrite; - file->seek = _XcursorStdioFileSeek; -} - -static XcursorImages * -XcursorFileLoadImages (FILE *file, int size) -{ - XcursorFile f; - - if (!file) - return NULL; - - _XcursorStdioFileInitialize (file, &f); - return XcursorXcFileLoadImages (&f, size); -} - -/* - * From libXcursor/src/library.c - */ - -#ifndef ICONDIR -#define ICONDIR "/usr/X11R6/lib/X11/icons" -#endif - -#ifndef XCURSORPATH -#define XCURSORPATH "~/.icons:/usr/share/icons:/usr/share/pixmaps:~/.cursors:/usr/share/cursors/xorg-x11:"ICONDIR -#endif - -#define XDG_DATA_HOME_FALLBACK "~/.local/share" -#define CURSORDIR "/icons" - -/** Get search path for cursor themes - * - * This function builds the list of directories to look for cursor - * themes in. The format is PATH-like: directories are separated by - * colons. - * - * The memory block returned by this function is allocated on the heap - * and must be freed by the caller. - */ -static char * -XcursorLibraryPath (void) -{ - const char *env_var; - char *path = NULL; - int pathlen = 0; - - env_var = getenv ("XCURSOR_PATH"); - if (env_var) - { - path = strdup (env_var); - } - else - { - env_var = getenv ("XDG_DATA_HOME"); - if (env_var) { - pathlen = strlen (env_var) + strlen (CURSORDIR ":" XCURSORPATH) + 1; - path = malloc (pathlen); - snprintf (path, pathlen, "%s%s", env_var, - CURSORDIR ":" XCURSORPATH); - } - else - { - path = strdup (XDG_DATA_HOME_FALLBACK CURSORDIR ":" XCURSORPATH); - } - } - return path; -} - -static void -_XcursorAddPathElt (char *path, const char *elt, int len) -{ - int pathlen = strlen (path); - - /* append / if the path doesn't currently have one */ - if (path[0] == '\0' || path[pathlen - 1] != '/') - { - strcat (path, "/"); - pathlen++; - } - if (len == -1) - len = strlen (elt); - /* strip leading slashes */ - while (len && elt[0] == '/') - { - elt++; - len--; - } - strncpy (path + pathlen, elt, len); - path[pathlen + len] = '\0'; -} - -static char * -_XcursorBuildThemeDir (const char *dir, const char *theme) -{ - const char *colon; - const char *tcolon; - char *full; - char *home; - int dirlen; - int homelen; - int themelen; - int len; - - if (!dir || !theme) - return NULL; - - colon = strchr (dir, ':'); - if (!colon) - colon = dir + strlen (dir); - - dirlen = colon - dir; - - tcolon = strchr (theme, ':'); - if (!tcolon) - tcolon = theme + strlen (theme); - - themelen = tcolon - theme; - - home = NULL; - homelen = 0; - if (*dir == '~') - { - home = getenv ("HOME"); - if (!home) - return NULL; - homelen = strlen (home); - dir++; - dirlen--; - } - - /* - * add space for any needed directory separators, one per component, - * and one for the trailing null - */ - len = 1 + homelen + 1 + dirlen + 1 + themelen + 1; - - full = malloc (len); - if (!full) - return NULL; - full[0] = '\0'; - - if (home) - _XcursorAddPathElt (full, home, -1); - _XcursorAddPathElt (full, dir, dirlen); - _XcursorAddPathElt (full, theme, themelen); - return full; -} - -static char * -_XcursorBuildFullname (const char *dir, const char *subdir, const char *file) -{ - char *full; - - if (!dir || !subdir || !file) - return NULL; - - full = malloc (strlen (dir) + 1 + strlen (subdir) + 1 + strlen (file) + 1); - if (!full) - return NULL; - full[0] = '\0'; - _XcursorAddPathElt (full, dir, -1); - _XcursorAddPathElt (full, subdir, -1); - _XcursorAddPathElt (full, file, -1); - return full; -} - -static const char * -_XcursorNextPath (const char *path) -{ - char *colon = strchr (path, ':'); - - if (!colon) - return NULL; - return colon + 1; -} - -#define XcursorWhite(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') -#define XcursorSep(c) ((c) == ';' || (c) == ',') - -static char * -_XcursorThemeInherits (const char *full) -{ - char line[8192]; - char *result = NULL; - FILE *f; - - if (!full) - return NULL; - - f = fopen (full, "r"); - if (f) - { - while (fgets (line, sizeof (line), f)) - { - if (!strncmp (line, "Inherits", 8)) - { - char *l = line + 8; - char *r; - while (*l == ' ') l++; - if (*l != '=') continue; - l++; - while (*l == ' ') l++; - result = malloc (strlen (l) + 1); - if (result) - { - r = result; - while (*l) - { - while (XcursorSep(*l) || XcursorWhite (*l)) l++; - if (!*l) - break; - if (r != result) - *r++ = ':'; - while (*l && !XcursorWhite(*l) && - !XcursorSep(*l)) - *r++ = *l++; - } - *r++ = '\0'; - } - break; - } - } - fclose (f); - } - return result; -} - -static FILE * -XcursorScanTheme (const char *theme, const char *name) -{ - FILE *f = NULL; - char *full; - char *dir; - const char *path; - char *inherits = NULL; - const char *i; - char *xcursor_path; - - if (!theme || !name) - return NULL; - - /* - * Scan this theme - */ - xcursor_path = XcursorLibraryPath (); - for (path = xcursor_path; - path && f == NULL; - path = _XcursorNextPath (path)) - { - dir = _XcursorBuildThemeDir (path, theme); - if (dir) - { - full = _XcursorBuildFullname (dir, "cursors", name); - if (full) - { - f = fopen (full, "r"); - free (full); - } - if (!f && !inherits) - { - full = _XcursorBuildFullname (dir, "", "index.theme"); - if (full) - { - inherits = _XcursorThemeInherits (full); - free (full); - } - } - free (dir); - } - } - /* - * Recurse to scan inherited themes - */ - for (i = inherits; i && f == NULL; i = _XcursorNextPath (i)) - f = XcursorScanTheme (i, name); - if (inherits != NULL) - free (inherits); - free (xcursor_path); - return f; -} - -XcursorImages * -XcursorLibraryLoadImages (const char *file, const char *theme, int size) -{ - FILE *f = NULL; - XcursorImages *images = NULL; - - if (!file) - return NULL; - - if (theme) - f = XcursorScanTheme (theme, file); - if (!f) - f = XcursorScanTheme ("default", file); - if (f) - { - images = XcursorFileLoadImages (f, size); - if (images) - XcursorImagesSetName (images, file); - fclose (f); - } - return images; -} - -static void -load_all_cursors_from_dir(const char *path, int size, - void (*load_callback)(XcursorImages *, void *), - void *user_data) -{ - FILE *f; - DIR *dir = opendir(path); - struct dirent *ent; - char *full; - XcursorImages *images; - - if (!dir) - return; - - for(ent = readdir(dir); ent; ent = readdir(dir)) { -#ifdef _DIRENT_HAVE_D_TYPE - if (ent->d_type != DT_UNKNOWN && - (ent->d_type != DT_REG && ent->d_type != DT_LNK)) - continue; -#endif - - full = _XcursorBuildFullname(path, "", ent->d_name); - if (!full) - continue; - - f = fopen(full, "r"); - if (!f) { - free(full); - continue; - } - - images = XcursorFileLoadImages(f, size); - - if (images) { - XcursorImagesSetName(images, ent->d_name); - load_callback(images, user_data); - } - - fclose (f); - free(full); - } - - closedir(dir); -} - -/** Load all the cursor of a theme - * - * This function loads all the cursor images of a given theme and its - * inherited themes. Each cursor is loaded into an XcursorImages object - * which is passed to the caller's load callback. If a cursor appears - * more than once across all the inherited themes, the load callback - * will be called multiple times, with possibly different XcursorImages - * object which have the same name. The user is expected to destroy the - * XcursorImages objects passed to the callback with - * XcursorImagesDestroy(). - * - * \param theme The name of theme that should be loaded - * \param size The desired size of the cursor images - * \param load_callback A callback function that will be called - * for each cursor loaded. The first parameter is the XcursorImages - * object representing the loaded cursor and the second is a pointer - * to data provided by the user. - * \param user_data The data that should be passed to the load callback - */ -void -xcursor_load_theme(const char *theme, int size, - void (*load_callback)(XcursorImages *, void *), - void *user_data) -{ - char *full, *dir; - char *inherits = NULL; - const char *path, *i; - char *xcursor_path; - - if (!theme) - theme = "default"; - - xcursor_path = XcursorLibraryPath(); - for (path = xcursor_path; - path; - path = _XcursorNextPath(path)) { - dir = _XcursorBuildThemeDir(path, theme); - if (!dir) - continue; - - full = _XcursorBuildFullname(dir, "cursors", ""); - - if (full) { - load_all_cursors_from_dir(full, size, load_callback, - user_data); - free(full); - } - - if (!inherits) { - full = _XcursorBuildFullname(dir, "", "index.theme"); - if (full) { - inherits = _XcursorThemeInherits(full); - free(full); - } - } - - free(dir); - } - - for (i = inherits; i; i = _XcursorNextPath(i)) - xcursor_load_theme(i, size, load_callback, user_data); - - if (inherits) - free(inherits); - - free (xcursor_path); -} diff --git a/src/plugins/platforms/eglfs/api/xcursor.h b/src/plugins/platforms/eglfs/api/xcursor.h deleted file mode 100644 index 9fd57891..00000000 --- a/src/plugins/platforms/eglfs/api/xcursor.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright © 2002 Keith Packard - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include - -typedef int XcursorBool; -typedef uint32_t XcursorUInt; - -typedef XcursorUInt XcursorDim; -typedef XcursorUInt XcursorPixel; - -typedef struct _XcursorImage { - XcursorUInt version; /* version of the image data */ - XcursorDim size; /* nominal size for matching */ - XcursorDim width; /* actual width */ - XcursorDim height; /* actual height */ - XcursorDim xhot; /* hot spot x (must be inside image) */ - XcursorDim yhot; /* hot spot y (must be inside image) */ - XcursorUInt delay; /* animation delay to next frame (ms) */ - XcursorPixel *pixels; /* pointer to pixels */ -} XcursorImage; - -/* - * Other data structures exposed by the library API - */ -typedef struct _XcursorImages { - int nimage; /* number of images */ - XcursorImage **images; /* array of XcursorImage pointers */ - char *name; /* name used to load images */ -} XcursorImages; - -XcursorImages * -XcursorLibraryLoadImages (const char *file, const char *theme, int size); - -void -XcursorImagesDestroy (XcursorImages *images); - -void -xcursor_load_theme(const char *theme, int size, - void (*load_callback)(XcursorImages *, void *), - void *user_data); diff --git a/src/plugins/platforms/eglfs/api/xcursortheme.cpp b/src/plugins/platforms/eglfs/api/xcursortheme.cpp deleted file mode 100644 index 134c8cfd..00000000 --- a/src/plugins/platforms/eglfs/api/xcursortheme.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Pier Luigi Fiorini -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#include "xcursortheme_p.h" -extern "C" { -#include "xcursor.h" -} - -namespace Liri { - -namespace Platform { - -class XcursorThemePrivate -{ -public: - static void load_callback(XcursorImages *images, void *user_data) - { - auto *theme = static_cast(user_data); - auto name = QString::fromUtf8(images->name); - - // Do not load a cursor if it's already present - if (theme->m_cursors.contains(name)) { - XcursorImagesDestroy(images); - return; - } - - // Convert only first item of XcursorImages to a QImage, because we won't support animated cursors - QImage image(images->images[0]->width, images->images[0]->height, QImage::Format_ARGB32); - memcpy(image.bits(), images->images[0]->pixels, images->images[0]->width * images->images[0]->height * 4); - - // Hotspot - QPoint hotspot(images->images[0]->xhot, images->images[0]->yhot); - - // Save the cursor - theme->m_cursors[name] = XcursorTheme::Cursor{true, image, hotspot}; - - XcursorImagesDestroy(images); - } -}; - -XcursorTheme::XcursorTheme() -{ -} - -XcursorTheme::~XcursorTheme() -{ - unloadTheme(); -} - -void XcursorTheme::loadTheme(const QString &name, int size) -{ - if (m_name == name && m_size == size) - return; - - if (m_loaded) - unloadTheme(); - - m_name = name.isEmpty() ? QStringLiteral("default") : name; - m_size = size; - xcursor_load_theme(qPrintable(m_name), m_size, XcursorThemePrivate::load_callback, this); - m_loaded = true; -} - -bool XcursorTheme::isLoaded() const -{ - return m_loaded; -} - -QStringList XcursorTheme::cursorNames() const -{ - return m_cursors.keys(); -} - -XcursorTheme::Cursor XcursorTheme::cursorForName(const QString &name) const -{ - if (!m_loaded) - return XcursorTheme::Cursor(); - return m_cursors.value(name); -} - -XcursorTheme::Cursor XcursorTheme::cursorForShape(Qt::CursorShape shape) const -{ - if (!m_loaded) - return XcursorTheme::Cursor(); - - static constexpr struct ShapeMap { - Qt::CursorShape shape; - const char name[50]; - } cursorShapeMap[] = { - {Qt::ArrowCursor, "left_ptr"}, - {Qt::ArrowCursor, "default"}, - {Qt::ArrowCursor, "top_left_arrow"}, - {Qt::ArrowCursor, "left_arrow"}, - - {Qt::UpArrowCursor, "up_arrow"}, - - {Qt::CrossCursor, "cross"}, - - {Qt::WaitCursor, "wait"}, - {Qt::WaitCursor, "watch"}, - {Qt::WaitCursor, "0426c94ea35c87780ff01dc239897213"}, - - {Qt::IBeamCursor, "ibeam"}, - {Qt::IBeamCursor, "text"}, - {Qt::IBeamCursor, "xterm"}, - - {Qt::SizeVerCursor, "size_ver"}, - {Qt::SizeVerCursor, "ns-resize"}, - {Qt::SizeVerCursor, "v_double_arrow"}, - {Qt::SizeVerCursor, "00008160000006810000408080010102"}, - - {Qt::SizeHorCursor, "size_hor"}, - {Qt::SizeHorCursor, "ew-resize"}, - {Qt::SizeHorCursor, "h_double_arrow"}, - {Qt::SizeHorCursor, "028006030e0e7ebffc7f7070c0600140"}, - - {Qt::SizeBDiagCursor, "size_bdiag"}, - {Qt::SizeBDiagCursor, "nesw-resize"}, - {Qt::SizeBDiagCursor, "50585d75b494802d0151028115016902"}, - {Qt::SizeBDiagCursor, "fcf1c3c7cd4491d801f1e1c78f100000"}, - - {Qt::SizeFDiagCursor, "size_fdiag"}, - {Qt::SizeFDiagCursor, "nwse-resize"}, - {Qt::SizeFDiagCursor, "38c5dff7c7b8962045400281044508d2"}, - {Qt::SizeFDiagCursor, "c7088f0f3e6c8088236ef8e1e3e70000"}, - - {Qt::SizeAllCursor, "size_all"}, - - {Qt::SplitVCursor, "split_v"}, - {Qt::SplitVCursor, "row-resize"}, - {Qt::SplitVCursor, "sb_v_double_arrow"}, - {Qt::SplitVCursor, "2870a09082c103050810ffdffffe0204"}, - {Qt::SplitVCursor, "c07385c7190e701020ff7ffffd08103c"}, - - {Qt::SplitHCursor, "split_h"}, - {Qt::SplitHCursor, "col-resize"}, - {Qt::SplitHCursor, "sb_h_double_arrow"}, - {Qt::SplitHCursor, "043a9f68147c53184671403ffa811cc5"}, - {Qt::SplitHCursor, "14fef782d02440884392942c11205230"}, - - {Qt::PointingHandCursor, "pointing_hand"}, - {Qt::PointingHandCursor, "pointer"}, - {Qt::PointingHandCursor, "hand1"}, - {Qt::PointingHandCursor, "e29285e634086352946a0e7090d73106"}, - - {Qt::ForbiddenCursor, "forbidden"}, - {Qt::ForbiddenCursor, "not-allowed"}, - {Qt::ForbiddenCursor, "crossed_circle"}, - {Qt::ForbiddenCursor, "circle"}, - {Qt::ForbiddenCursor, "03b6e0fcb3499374a867c041f52298f0"}, - - {Qt::WhatsThisCursor, "whats_this"}, - {Qt::WhatsThisCursor, "help"}, - {Qt::WhatsThisCursor, "question_arrow"}, - {Qt::WhatsThisCursor, "5c6cd98b3f3ebcb1f9c7f1c204630408"}, - {Qt::WhatsThisCursor, "d9ce0ab605698f320427677b458ad60b"}, - - {Qt::BusyCursor, "left_ptr_watch"}, - {Qt::BusyCursor, "half-busy"}, - {Qt::BusyCursor, "progress"}, - {Qt::BusyCursor, "00000000000000020006000e7e9ffc3f"}, - {Qt::BusyCursor, "08e8e1c95fe2fc01f976f1e063a24ccd"}, - - {Qt::OpenHandCursor, "openhand"}, - {Qt::OpenHandCursor, "fleur"}, - {Qt::OpenHandCursor, "5aca4d189052212118709018842178c0"}, - {Qt::OpenHandCursor, "9d800788f1b08800ae810202380a0822"}, - - {Qt::ClosedHandCursor, "closedhand"}, - {Qt::ClosedHandCursor, "grabbing"}, - {Qt::ClosedHandCursor, "208530c400c041818281048008011002"}, - - {Qt::DragCopyCursor, "dnd-copy"}, - {Qt::DragCopyCursor, "copy"}, - - {Qt::DragMoveCursor, "dnd-move"}, - {Qt::DragMoveCursor, "move"}, - - {Qt::DragLinkCursor, "dnd-link"}, - {Qt::DragLinkCursor, "link"}, - }; - - const auto compareByShape = [](ShapeMap lhs, ShapeMap rhs) { - return lhs.shape < rhs.shape; - }; - - const auto p = std::equal_range(std::begin(cursorShapeMap), std::end(cursorShapeMap), - ShapeMap{shape, ""}, compareByShape); - for (auto it = p.first; it != p.second; ++it) { - const auto name = QString::fromLocal8Bit(it->name); - if (m_cursors.contains(name)) - return m_cursors.value(name); - } - - return XcursorTheme::Cursor(); -} - -void XcursorTheme::unloadTheme() -{ - m_cursors.clear(); - m_loaded = false; -} - -} // namespace Platform - -} // namespace Liri diff --git a/src/plugins/platforms/eglfs/api/xcursortheme_p.h b/src/plugins/platforms/eglfs/api/xcursortheme_p.h deleted file mode 100644 index 9994e248..00000000 --- a/src/plugins/platforms/eglfs/api/xcursortheme_p.h +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Pier Luigi Fiorini -// -// SPDX-License-Identifier: LGPL-3.0-or-later - -#pragma once - -#include -#include -#include - -#include "qeglfsglobal_p.h" - -namespace Liri { - -namespace Platform { - -class Q_EGLFS_EXPORT XcursorTheme -{ - friend class XcursorThemePrivate; -public: - struct Cursor - { - bool isValid = false; - QImage image; - QPoint hotSpot; - }; - - XcursorTheme(); - ~XcursorTheme(); - - void loadTheme(const QString &name, int size); - - bool isLoaded() const; - - QStringList cursorNames() const; - Cursor cursorForName(const QString &name) const; - Cursor cursorForShape(Qt::CursorShape shape) const; - -private: - QString m_name; - int m_size = 0; - QMap m_cursors; - bool m_loaded = false; - - void unloadTheme(); -}; - -} // namespace Platform - -} // namespace Liri - diff --git a/src/plugins/platforms/eglfs/aurora-eglfs.json b/src/plugins/platforms/eglfs/aurora-eglfs.json deleted file mode 100644 index 04cb6e21..00000000 --- a/src/plugins/platforms/eglfs/aurora-eglfs.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "aurora-eglfs" ] -} diff --git a/src/plugins/platforms/eglfs/cursor-atlas.png b/src/plugins/platforms/eglfs/cursor-atlas.png deleted file mode 100644 index 40c5b6ef..00000000 Binary files a/src/plugins/platforms/eglfs/cursor-atlas.png and /dev/null differ diff --git a/src/plugins/platforms/eglfs/cursor.json b/src/plugins/platforms/eglfs/cursor.json deleted file mode 100644 index 44e438bc..00000000 --- a/src/plugins/platforms/eglfs/cursor.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "image": ":/cursor-atlas.png", - "cursorsPerRow": 8, - "hotSpots": [ - [7, 2], - [12, 3], - [12, 12], - [12, 12], - [12, 12], - [12, 12], - [12, 12], - [12, 12], - [12, 12], - [11, 11], - [12, 12], - [12, 12], - [12, 12], - [9, 1], - [12, 12], - [1, 1], - [1, 1], - [12, 12], - [12, 12], - [7, 2], - [7, 2], - [7, 2] - ] -} diff --git a/src/plugins/platforms/eglfs/cursor.qrc b/src/plugins/platforms/eglfs/cursor.qrc deleted file mode 100644 index 8ea6e865..00000000 --- a/src/plugins/platforms/eglfs/cursor.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - cursor-atlas.png - cursor.json - - - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt deleted file mode 100644 index 020918f1..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_plugin(eglfs-kms-integration - TYPE - liri/egldeviceintegrations - SOURCES - qeglfskmsgbmcursor.cpp - qeglfskmsgbmcursor.h - qeglfskmsgbmdevice.cpp - qeglfskmsgbmdevice.h - qeglfskmsgbmintegration.cpp - qeglfskmsgbmintegration.h - qeglfskmsgbmmain.cpp - qeglfskmsgbmscreen.cpp - qeglfskmsgbmscreen.h - qeglfskmsgbmwindow.cpp - qeglfskmsgbmwindow.h - DEFINES - ${DEFINES} - PUBLIC_DEFINES - QT_EGL_NO_X11 - LIBRARIES - Liri::EglFSDeviceIntegration - Liri::EglFSDeviceIntegrationPrivate - Liri::EglFSKmsSupport - Liri::EglFSKmsSupportPrivate - PkgConfig::EGL -) - -liri_extend_target(eglfs-kms-integration CONDITION FEATURE_aurora_drm_atomic - DEFINES - EGLFS_ENABLE_DRM_ATOMIC -) - -liri_finalize_plugin(eglfs-kms-integration) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.json deleted file mode 100644 index 70fec1ca..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "eglfs_kms" ] -} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp deleted file mode 100644 index c2153394..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsgbmcursor.h" -#include "qeglfskmsgbmscreen.h" -#include "qeglfskmsgbmdevice.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef DRM_CAP_CURSOR_WIDTH -#define DRM_CAP_CURSOR_WIDTH 0x8 -#endif - -#ifndef DRM_CAP_CURSOR_HEIGHT -#define DRM_CAP_CURSOR_HEIGHT 0x9 -#endif - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) - : m_screen(screen) - , m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below - , m_bo(nullptr) - , m_cursorImage(nullptr, nullptr, 0, 0, 0, 0) - , m_state(CursorPendingVisible) - , m_deviceListener(nullptr) -{ - QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); - if (!hideCursorVal.isEmpty() && hideCursorVal.toInt()) { - m_state = CursorDisabled; - return; - } - - uint64_t width, height; - if ((drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &width) == 0) - && (drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_HEIGHT, &height) == 0)) { - m_cursorSize.setWidth(width); - m_cursorSize.setHeight(height); - } - - m_bo = gbm_bo_create(static_cast(m_screen->device())->gbmDevice(), m_cursorSize.width(), m_cursorSize.height(), - GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); - if (!m_bo) { - qWarning("Could not create buffer for cursor!"); - } else { - // Load the default cursor - m_cursorTheme.loadTheme(QString(), 32); - - // Always initialize the cursor atlas in case we need it - initCursorAtlas(); - } - - m_deviceListener = new QEglFSKmsGbmCursorDeviceListener(this); - connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, - m_deviceListener, &QEglFSKmsGbmCursorDeviceListener::onDeviceListChanged); - if (!m_deviceListener->hasMouse()) - m_state = CursorPendingHidden; - -#ifndef QT_NO_CURSOR - QCursor cursor(Qt::ArrowCursor); - changeCursor(&cursor, nullptr); -#endif - setPos(QPoint(0, 0)); -} - -QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() -{ - delete m_deviceListener; - - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { - QEglFSKmsScreen *kmsScreen = static_cast(screen); - drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); - drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); - } - - if (m_bo) { - gbm_bo_destroy(m_bo); - m_bo = nullptr; - } -} - -void QEglFSKmsGbmCursor::updateMouseStatus() -{ - const bool wasVisible = m_state == CursorVisible; - const bool visible = m_deviceListener->hasMouse(); - if (visible == wasVisible) - return; - - m_state = visible ? CursorPendingVisible : CursorPendingHidden; - -#ifndef QT_NO_CURSOR - changeCursor(nullptr, m_screen->topLevelAt(pos())); -#endif -} - -void QEglFSKmsGbmCursor::setCursorTheme(const QString &name, int size) -{ - m_cursorTheme.loadTheme(name, size); -} - -bool QEglFSKmsGbmCursorDeviceListener::hasMouse() const -{ - return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; -} - -void QEglFSKmsGbmCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) -{ - if (type == QInputDeviceManager::DeviceTypePointer) - m_cursor->updateMouseStatus(); -} - -void QEglFSKmsGbmCursor::pointerEvent(const QMouseEvent &event) -{ - setPos(event.screenPos().toPoint()); -} - -#ifndef QT_NO_CURSOR -void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window) -{ - Q_UNUSED(window); - - if (!m_bo) - return; - - if (m_state == CursorPendingHidden) { - m_state = CursorHidden; - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { - QEglFSKmsScreen *kmsScreen = static_cast(screen); - drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); - } - } - - if (m_state == CursorHidden || m_state == CursorDisabled) - return; - - const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor; - if (newShape == Qt::BitmapCursor) { - m_cursorImage.set(windowCursor->pixmap().toImage(), - windowCursor->hotSpot().x(), - windowCursor->hotSpot().y()); - } else { - if (m_cursorTheme.isLoaded()) { - auto cursor = m_cursorTheme.cursorForShape(newShape); - if (cursor.isValid) - m_cursorImage.set(cursor.image, cursor.hotSpot.x(), cursor.hotSpot.y()); - } else { - // Standard cursor, look up in atlas - const int width = m_cursorAtlas.cursorWidth; - const int height = m_cursorAtlas.cursorHeight; - const qreal ws = (qreal)m_cursorAtlas.cursorWidth / m_cursorAtlas.width; - const qreal hs = (qreal)m_cursorAtlas.cursorHeight / m_cursorAtlas.height; - - QRect textureRect(ws * (newShape % m_cursorAtlas.cursorsPerRow) * m_cursorAtlas.width, - hs * (newShape / m_cursorAtlas.cursorsPerRow) * m_cursorAtlas.height, - width, - height); - QPoint hotSpot = m_cursorAtlas.hotSpots[newShape]; - m_cursorImage.set(m_cursorAtlas.image.copy(textureRect), - hotSpot.x(), - hotSpot.y()); - } - } - - if (m_cursorImage.image()->width() > m_cursorSize.width() || m_cursorImage.image()->height() > m_cursorSize.height()) - qWarning("Cursor larger than %dx%d, cursor will be clipped.", m_cursorSize.width(), m_cursorSize.height()); - - QImage cursorImage(m_cursorSize, QImage::Format_ARGB32); - cursorImage.fill(Qt::transparent); - - QPainter painter; - painter.begin(&cursorImage); - painter.drawImage(0, 0, *m_cursorImage.image()); - painter.end(); - - gbm_bo_write(m_bo, cursorImage.constBits(), cursorImage.sizeInBytes()); - - uint32_t handle = gbm_bo_get_handle(m_bo).u32; - - if (m_state == CursorPendingVisible) - m_state = CursorVisible; - - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { - QEglFSKmsScreen *kmsScreen = static_cast(screen); - if (kmsScreen->isCursorOutOfRange()) - continue; - int status = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, handle, - m_cursorSize.width(), m_cursorSize.height()); - if (status != 0) - qWarning("Could not set cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), status); - } -} -#endif // QT_NO_CURSOR - -QPoint QEglFSKmsGbmCursor::pos() const -{ - return m_pos; -} - -void QEglFSKmsGbmCursor::setPos(const QPoint &pos) -{ - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { - QEglFSKmsScreen *kmsScreen = static_cast(screen); - const QRect screenGeom = kmsScreen->geometry(); - const QPoint origin = screenGeom.topLeft(); - const QPoint localPos = pos - origin; - const QPoint adjustedLocalPos = localPos - m_cursorImage.hotspot(); - - if (localPos.x() < 0 || localPos.y() < 0 - || localPos.x() >= screenGeom.width() || localPos.y() >= screenGeom.height()) - { - if (!kmsScreen->isCursorOutOfRange()) { - kmsScreen->setCursorOutOfRange(true); - drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); - } - } else { - int ret; - if (kmsScreen->isCursorOutOfRange() && m_bo) { - kmsScreen->setCursorOutOfRange(false); - uint32_t handle = gbm_bo_get_handle(m_bo).u32; - ret = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, - handle, m_cursorSize.width(), m_cursorSize.height()); - } else { - ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, - adjustedLocalPos.x(), adjustedLocalPos.y()); - } - if (ret == 0) - m_pos = pos; - else - qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret); - - kmsScreen->handleCursorMove(pos); - } - } -} - -void QEglFSKmsGbmCursor::initCursorAtlas() -{ - static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); - if (json.isEmpty()) - json = ":/cursor.json"; - - qCDebug(qLcEglfsKmsDebug) << "Initializing cursor atlas from" << json; - - QFile file(QString::fromUtf8(json)); - if (!file.open(QFile::ReadOnly)) { - Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { - QEglFSKmsScreen *kmsScreen = static_cast(screen); - drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); - drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); - } - m_state = CursorDisabled; - return; - } - - QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); - QJsonObject object = doc.object(); - - QString atlas = object.value(QLatin1String("image")).toString(); - Q_ASSERT(!atlas.isEmpty()); - - const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble(); - Q_ASSERT(cursorsPerRow); - m_cursorAtlas.cursorsPerRow = cursorsPerRow; - - const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray(); - Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1); - for (int i = 0; i < hotSpots.count(); i++) { - QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble()); - m_cursorAtlas.hotSpots << hotSpot; - } - - QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32); - m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow; - m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow) / cursorsPerRow); - m_cursorAtlas.width = image.width(); - m_cursorAtlas.height = image.height(); - m_cursorAtlas.image = std::move(image); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h deleted file mode 100644 index 286d03e1..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include -#include -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -class QEglFSKmsGbmScreen; -class QEglFSKmsGbmCursor; - -class QEglFSKmsGbmCursorDeviceListener : public QObject -{ - Q_OBJECT - -public: - QEglFSKmsGbmCursorDeviceListener(QEglFSKmsGbmCursor *cursor) : m_cursor(cursor) { } - bool hasMouse() const; - -public slots: - void onDeviceListChanged(QInputDeviceManager::DeviceType type); - -private: - QEglFSKmsGbmCursor *m_cursor; -}; - -class QEglFSKmsGbmCursor : public QPlatformCursor -{ - Q_OBJECT - -public: - QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen); - ~QEglFSKmsGbmCursor(); - - // input methods - void pointerEvent(const QMouseEvent & event) override; -#ifndef QT_NO_CURSOR - void changeCursor(QCursor * windowCursor, QWindow * window) override; -#endif - QPoint pos() const override; - void setPos(const QPoint &pos) override; - - void updateMouseStatus(); - - void setCursorTheme(const QString &name, int size); - void reevaluateVisibilityForScreens() { setPos(pos()); } - -private: - void initCursorAtlas(); - - enum CursorState { - CursorDisabled, - CursorPendingHidden, - CursorHidden, - CursorPendingVisible, - CursorVisible - }; - - QEglFSKmsGbmScreen *m_screen; - QSize m_cursorSize; - gbm_bo *m_bo; - QPoint m_pos; - QPlatformCursorImage m_cursorImage; - CursorState m_state; - QEglFSKmsGbmCursorDeviceListener *m_deviceListener; - Liri::Platform::XcursorTheme m_cursorTheme; - - // cursor atlas information - struct CursorAtlas { - CursorAtlas() : cursorsPerRow(0), cursorWidth(0), cursorHeight(0) { } - int cursorsPerRow; - int width, height; // width and height of the atlas - int cursorWidth, cursorHeight; // width and height of cursors inside the atlas - QVector hotSpots; - QImage image; - } m_cursorAtlas; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp deleted file mode 100644 index d53bb297..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsgbmdevice.h" -#include "qeglfskmsgbmscreen.h" - -#include "qeglfsintegration_p.h" - -#include -#include - -#include - -#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) - -using namespace Liri; - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(KmsScreenConfig *screenConfig, const QString &path) - : QEglFSKmsDevice(screenConfig, path) - , m_gbm_device(nullptr) - , m_globalCursor(nullptr) -{ -} - -bool QEglFSKmsGbmDevice::open() -{ - Q_ASSERT(fd() == -1); - Q_ASSERT(m_gbm_device == nullptr); - - Logind *logind = Logind::instance(); - - if (!logind->isConnected()) { - qCWarning(qLcEglfsKmsDebug, "Cannot open DRM device %s: logind connection was not established", - qPrintable(devicePath())); - return false; - } - if (!logind->hasSessionControl()) { - qCWarning(qLcEglfsKmsDebug, "Cannot open DRM device %s: session control not acquired", - qPrintable(devicePath())); - return false; - } - - int fd = logind->takeDevice(devicePath()); - if (fd == -1) { - qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath())); - return false; - } - - qCDebug(qLcEglfsKmsDebug) << "Creating GBM device for file descriptor" << fd - << "obtained from" << devicePath(); - m_gbm_device = gbm_create_device(fd); - if (!m_gbm_device) { - qErrnoWarning("Could not create GBM device"); - logind->releaseDevice(fd); - fd = -1; - return false; - } - - setFd(fd); - - m_eventReader.create(this); - - return true; -} - -void QEglFSKmsGbmDevice::close() -{ - // Note: screens are gone at this stage. - - m_eventReader.destroy(); - - if (m_gbm_device) { - gbm_device_destroy(m_gbm_device); - m_gbm_device = nullptr; - } - - if (fd() != -1) { - Logind::instance()->releaseDevice(fd()); - setFd(-1); - } -} - -void *QEglFSKmsGbmDevice::nativeDisplay() const -{ - return m_gbm_device; -} - -gbm_device * QEglFSKmsGbmDevice::gbmDevice() const -{ - return m_gbm_device; -} - -QPlatformCursor *QEglFSKmsGbmDevice::globalCursor() const -{ - return m_globalCursor; -} - -// Cannot do this from close(), it may be too late. -// Call this from the last screen dtor instead. -void QEglFSKmsGbmDevice::destroyGlobalCursor() -{ - if (m_globalCursor) { - qCDebug(qLcEglfsKmsDebug, "Destroying global GBM mouse cursor"); - delete m_globalCursor; - m_globalCursor = nullptr; - } -} - -QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const KmsOutput &output) -{ - QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output, false); - - if (!m_globalCursor && screenConfig()->hwCursor()) { - qCDebug(qLcEglfsKmsDebug, "Creating new global GBM mouse cursor"); - m_globalCursor = new QEglFSKmsGbmCursor(screen); - } - - return screen; -} - -QPlatformScreen *QEglFSKmsGbmDevice::createHeadlessScreen() -{ - return new QEglFSKmsGbmScreen(this, KmsOutput(), true); -} - -void QEglFSKmsGbmDevice::registerScreenCloning(QPlatformScreen *screen, - QPlatformScreen *screenThisScreenClones, - const QVector &screensCloningThisScreen) -{ - if (!screenThisScreenClones && screensCloningThisScreen.isEmpty()) - return; - - QEglFSKmsGbmScreen *gbmScreen = static_cast(screen); - gbmScreen->initCloning(screenThisScreenClones, screensCloningThisScreen); -} - -void QEglFSKmsGbmDevice::registerScreen(QPlatformScreen *screen, - bool isPrimary, - const QPoint &virtualPos, - const QList &virtualSiblings) -{ - QEglFSKmsDevice::registerScreen(screen, isPrimary, virtualPos, virtualSiblings); - if (screenConfig()->hwCursor() && m_globalCursor) - m_globalCursor->reevaluateVisibilityForScreens(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h deleted file mode 100644 index 2f6a029b..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -#include "qeglfskmsgbmcursor.h" - -#include - -QT_BEGIN_NAMESPACE - -class QEglFSKmsScreen; - -class QEglFSKmsGbmDevice: public QEglFSKmsDevice -{ -public: - QEglFSKmsGbmDevice(KmsScreenConfig *screenConfig, const QString &path); - - bool open() override; - void close() override; - - void *nativeDisplay() const override; - gbm_device *gbmDevice() const; - - QPlatformCursor *globalCursor() const; - void destroyGlobalCursor(); - - QPlatformScreen *createScreen(const KmsOutput &output) override; - QPlatformScreen *createHeadlessScreen() override; - void registerScreenCloning(QPlatformScreen *screen, - QPlatformScreen *screenThisScreenClones, - const QVector &screensCloningThisScreen) override; - void registerScreen(QPlatformScreen *screen, - bool isPrimary, - const QPoint &virtualPos, - const QList &virtualSiblings) override; - -private: - Q_DISABLE_COPY(QEglFSKmsGbmDevice) - - gbm_device *m_gbm_device; - - QEglFSKmsGbmCursor *m_globalCursor; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp deleted file mode 100644 index e9c624ec..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsgbmintegration.h" -#include "qeglfskmsgbmdevice.h" -#include "qeglfskmsgbmscreen.h" -#include "qeglfskmsgbmcursor.h" -#include "qeglfskmsgbmwindow.h" -#include "private/qeglfscursor_p.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -using namespace Aurora::PlatformSupport; - -QT_BEGIN_NAMESPACE - -QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration() -{ - qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created"); - - m_udev = new Aurora::PlatformSupport::Udev(); -} - -QEglFSKmsGbmIntegration::~QEglFSKmsGbmIntegration() -{ - delete m_udev; -} - -#ifndef EGL_EXT_platform_base -typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); -#endif - -#ifndef EGL_PLATFORM_GBM_KHR -#define EGL_PLATFORM_GBM_KHR 0x31D7 -#endif - -EGLDisplay QEglFSKmsGbmIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) -{ - qCDebug(qLcEglfsKmsDebug, "Querying EGLDisplay"); - EGLDisplay display; - - PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay = nullptr; - const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) { - getPlatformDisplay = reinterpret_cast( - eglGetProcAddress("eglGetPlatformDisplayEXT")); - } - - if (getPlatformDisplay) { - display = getPlatformDisplay(EGL_PLATFORM_GBM_KHR, nativeDisplay, nullptr); - } else { - qCDebug(qLcEglfsKmsDebug, "No eglGetPlatformDisplay for GBM, falling back to eglGetDisplay"); - display = eglGetDisplay(nativeDisplay); - } - - return display; -} - -EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) -{ - Q_UNUSED(format); - Q_ASSERT(device()); - - QEglFSKmsGbmScreen *screen = static_cast(platformWindow->screen()); - - gbm_surface *surface = - gbm_surface_create(static_cast(device())->gbmDevice(), - size.width(), size.height(), screen->output().drm_format, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - - return reinterpret_cast(surface); -} - -EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format) -{ - Q_UNUSED(format); - Q_ASSERT(device()); - - gbm_surface *surface = gbm_surface_create(static_cast(device())->gbmDevice(), - 1, 1, - GBM_FORMAT_XRGB8888, - GBM_BO_USE_RENDERING); - - return reinterpret_cast(surface); -} - -void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window) -{ - gbm_surface *surface = reinterpret_cast(window); - gbm_surface_destroy(surface); -} - -QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) const -{ -#if QT_CONFIG(opengl) - if (!screenConfig()->hwCursor()) { - qCDebug(qLcEglfsKmsDebug, "Using plain OpenGL mouse cursor"); - return new QEglFSCursor(screen); - } -#else - Q_UNUSED(screen); -#endif - return nullptr; -} - -void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface) -{ - if (!Aurora::PlatformSupport::Logind::instance()->isSessionActive()) - return; - - QWindow *window = static_cast(surface->surface()); - QEglFSKmsGbmScreen *screen = static_cast(window->screen()->handle()); - screen->flip(); -} - -QEglFSWindow *QEglFSKmsGbmIntegration::createWindow(QWindow *window) const -{ - return new QEglFSKmsGbmWindow(window, this); -} - -QFunctionPointer QEglFSKmsGbmIntegration::platformFunction(const QByteArray &function) const -{ - auto returnValue = QEglFSKmsIntegration::platformFunction(function); - if (returnValue) - return returnValue; - - if (function == Aurora::PlatformSupport::EglFSFunctions::testScreenChangesIdentifier()) - return QFunctionPointer(testScreenChangesStatic); - else if (function == Aurora::PlatformSupport::EglFSFunctions::applyScreenChangesIdentifier()) - return QFunctionPointer(applyScreenChangesStatic); - - return nullptr; -} - -KmsDevice *QEglFSKmsGbmIntegration::createDevice() -{ - QString path = screenConfig()->devicePath(); - if (!path.isEmpty()) { - qCDebug(qLcEglfsKmsDebug) << "GBM: Using DRM device" << path << "specified in config file"; - } else { - Aurora::PlatformSupport::UdevEnumerate enumerate(Aurora::PlatformSupport::UdevDevice::PrimaryVideoDevice | Aurora::PlatformSupport::UdevDevice::GenericVideoDevice, m_udev); - QList devices = enumerate.scan(); - qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:"; - for (auto device : qAsConst(devices)) - qCDebug(qLcEglfsKmsDebug) << '\t' << device->deviceNode().toLocal8Bit().constData(); - - if (Q_UNLIKELY(devices.isEmpty())) - qFatal("Could not find DRM device!"); - - path = devices.first()->deviceNode(); - qCDebug(qLcEglfsKmsDebug) << "Using" << path; - } - - return new QEglFSKmsGbmDevice(screenConfig(), path); -} - -bool QEglFSKmsGbmIntegration::testScreenChangesStatic(const QVector &changes) -{ - Q_UNUSED(changes) - return true; -} - -bool QEglFSKmsGbmIntegration::applyScreenChangesStatic(const QVector &changes) -{ - for (auto &change : qAsConst(changes)) { - if (!change.screen || !change.enabled) - continue; - - auto *gbmScreen = static_cast(change.screen->handle()); - if (!gbmScreen) - continue; - - qCDebug(qLcEglfsKmsDebug) << "Apply screen changes to" << gbmScreen->name(); - - gbmScreen->setModeChangeRequested(true); - - bool modeChanged = gbmScreen->setMode(change.resolution, qCeil(change.refreshRate / 1000.0f)); - if (!modeChanged) { - gbmScreen->setModeChangeRequested(false); - continue; - } - - gbmScreen->setVirtualPosition(change.position); - gbmScreen->setScaleFactor(change.scale); - - const auto windows = QGuiApplication::topLevelWindows(); - for (auto *window : windows) { - if (window->screen() == change.screen) { - auto *gbmWindow = static_cast(window->handle()); - gbmWindow->resizeSurface(gbmScreen->rawGeometry().size()); - gbmWindow->setGeometry(QRect()); - } - } - - QWindowSystemInterface::handleScreenGeometryChange(change.screen, gbmScreen->geometry(), gbmScreen->availableGeometry()); - - gbmScreen->setModeChangeRequested(false); - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h deleted file mode 100644 index b4ce8733..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include -#include - -#include - -namespace Aurora { -namespace PlatformSupport { -class Udev; -class ScreenChange; -} -} - -QT_BEGIN_NAMESPACE - -class QEglFSKmsDevice; - -class QEglFSKmsGbmIntegration : public QEglFSKmsIntegration -{ -public: - QEglFSKmsGbmIntegration(); - ~QEglFSKmsGbmIntegration(); - - EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) override; - EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) override; - EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) override; - void destroyNativeWindow(EGLNativeWindowType window) override; - - QPlatformCursor *createCursor(QPlatformScreen *screen) const override; - void presentBuffer(QPlatformSurface *surface) override; - QEglFSWindow *createWindow(QWindow *window) const override; - - QFunctionPointer platformFunction(const QByteArray &function) const override; - -protected: - Aurora::PlatformSupport::KmsDevice *createDevice() override; - -private: - Aurora::PlatformSupport::Udev *m_udev; - - static bool testScreenChangesStatic(const QVector &changes); - static bool applyScreenChangesStatic(const QVector &changes); -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp deleted file mode 100644 index 9e9a6882..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfsdeviceintegration_p.h" -#include "qeglfskmsgbmintegration.h" - -QT_BEGIN_NAMESPACE - -class QEglFSKmsGbmIntegrationPlugin : public QEglFSDeviceIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms.json") - -public: - QEglFSDeviceIntegration *create() override { return new QEglFSKmsGbmIntegration; } -}; - -QT_END_NAMESPACE - -#include "qeglfskmsgbmmain.moc" diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp deleted file mode 100644 index 9b34659d..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ /dev/null @@ -1,499 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsgbmscreen.h" -#include "qeglfskmsgbmdevice.h" -#include "qeglfskmsgbmcursor.h" -#include "qeglfsintegration_p.h" - -#include - -#include -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -static inline uint32_t drmFormatToGbmFormat(uint32_t drmFormat) -{ - Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888); - return drmFormat; -} - -static inline uint32_t gbmFormatToDrmFormat(uint32_t gbmFormat) -{ - Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888); - return gbmFormat; -} - -void QEglFSKmsGbmScreen::bufferDestroyedHandler(gbm_bo *bo, void *data) -{ - FrameBuffer *fb = static_cast(data); - - if (fb->fb) { - gbm_device *device = gbm_bo_get_device(bo); - drmModeRmFB(gbm_device_get_fd(device), fb->fb); - } - - delete fb; -} - -QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject(gbm_bo *bo) -{ - { - FrameBuffer *fb = static_cast(gbm_bo_get_user_data(bo)); - if (fb) - return fb; - } - - uint32_t width = gbm_bo_get_width(bo); - uint32_t height = gbm_bo_get_height(bo); - uint32_t handles[4] = { gbm_bo_get_handle(bo).u32 }; - uint32_t strides[4] = { gbm_bo_get_stride(bo) }; - uint32_t offsets[4] = { 0 }; - uint32_t pixelFormat = gbmFormatToDrmFormat(gbm_bo_get_format(bo)); - - QScopedPointer fb(new FrameBuffer); - qCDebug(qLcEglfsKmsDebug, "Adding FB, size %ux%u, DRM format 0x%x", width, height, pixelFormat); - - int ret = drmModeAddFB2(device()->fd(), width, height, pixelFormat, - handles, strides, offsets, &fb->fb, 0); - - if (ret) { - qWarning("Failed to create KMS FB!"); - return nullptr; - } - - gbm_bo_set_user_data(bo, fb.data(), bufferDestroyedHandler); - return fb.take(); -} - -QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const KmsOutput &output, bool headless) - : QEglFSKmsScreen(device, output, headless) - , m_gbm_surface(nullptr) - , m_gbm_bo_current(nullptr) - , m_gbm_bo_next(nullptr) - , m_flipPending(false) - , m_cursor(nullptr) - , m_cloneSource(nullptr) -{ -} - -QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen() -{ - const int remainingScreenCount = qGuiApp->screens().count(); - qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); - if (!remainingScreenCount && !device()->screenConfig()->separateScreens()) - static_cast(device())->destroyGlobalCursor(); -} - -QPlatformCursor *QEglFSKmsGbmScreen::cursor() const -{ - KmsScreenConfig *config = device()->screenConfig(); - if (config->headless()) - return nullptr; - if (config->hwCursor()) { - if (!config->separateScreens()) - return static_cast(device())->globalCursor(); - - if (m_cursor.isNull()) { - QEglFSKmsGbmScreen *that = const_cast(this); - that->m_cursor.reset(new QEglFSKmsGbmCursor(that)); - } - - return m_cursor.data(); - } else { - return QEglFSScreen::cursor(); - } -} - -gbm_surface *QEglFSKmsGbmScreen::createGbmSurface(EGLConfig eglConfig, const QSize &size) -{ - qCDebug(qLcEglfsKmsDebug, "Creating gbm_surface for screen %s", qPrintable(name())); - - const auto gbmDevice = static_cast(device())->gbmDevice(); - EGLint native_format = -1; - EGLBoolean success = eglGetConfigAttrib(display(), eglConfig, EGL_NATIVE_VISUAL_ID, &native_format); - qCDebug(qLcEglfsKmsDebug) << "Got native format" << Qt::hex << native_format << Qt::dec << "from eglGetConfigAttrib() with return code" << bool(success); - gbm_surface *gbmSurface = nullptr; - - if (success) - gbmSurface = gbm_surface_create(gbmDevice, - size.width(), - size.height(), - native_format, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - - if (!gbmSurface) { // fallback for older drivers - uint32_t gbmFormat = drmFormatToGbmFormat(m_output.drm_format); - qCDebug(qLcEglfsKmsDebug, "Could not create surface with EGL_NATIVE_VISUAL_ID, falling back to format %x", gbmFormat); - gbmSurface = gbm_surface_create(gbmDevice, - size.width(), - size.height(), - gbmFormat, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); - } - - return gbmSurface; // not owned, gets destroyed by the caller -} - -gbm_surface *QEglFSKmsGbmScreen::createSurface(EGLConfig eglConfig) -{ - if (!m_gbm_surface) - m_gbm_surface = createGbmSurface(eglConfig, rawGeometry().size()); - return m_gbm_surface; // not owned, gets destroyed in QEglFSKmsGbmIntegration::destroyNativeWindow() via QEglFSKmsGbmWindow::invalidateSurface() -} - -void QEglFSKmsGbmScreen::resetSurface() -{ - m_gbm_surface = nullptr; -} - -void QEglFSKmsGbmScreen::setSurface(gbm_surface *surface) -{ - if (m_gbm_bo_current) { - gbm_surface_release_buffer(m_gbm_surface, - m_gbm_bo_current); - m_gbm_bo_current = nullptr; - } - if (m_gbm_bo_next) { - gbm_surface_release_buffer(m_gbm_surface, - m_gbm_bo_next); - m_gbm_bo_next = nullptr; - } - - m_gbm_surface = surface; -} - -void QEglFSKmsGbmScreen::initCloning(QPlatformScreen *screenThisScreenClones, - const QVector &screensCloningThisScreen) -{ - // clone destinations need to know the clone source - const bool clonesAnother = screenThisScreenClones != nullptr; - if (clonesAnother && !screensCloningThisScreen.isEmpty()) { - qWarning("QEglFSKmsGbmScreen %s cannot be clone source and destination at the same time", qPrintable(name())); - return; - } - if (clonesAnother) - m_cloneSource = static_cast(screenThisScreenClones); - - // clone sources need to know their additional destinations - for (QPlatformScreen *s : screensCloningThisScreen) { - CloneDestination d; - d.screen = static_cast(s); - m_cloneDests.append(d); - } -} - -void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb) -{ - KmsOutput &op(output()); - const int fd = device()->fd(); - - if (!op.mode_set) { - op.mode_set = true; - - bool doModeSet = true; - drmModeCrtcPtr currentMode = drmModeGetCrtc(fd, op.crtc_id); - const bool alreadySet = currentMode && currentMode->buffer_id == fb && !memcmp(¤tMode->mode, &op.modes[op.mode], sizeof(drmModeModeInfo)); - if (currentMode) - drmModeFreeCrtc(currentMode); - if (alreadySet) - doModeSet = false; - - if (doModeSet) { - qCDebug(qLcEglfsKmsDebug, "Setting mode for screen %s", qPrintable(name())); - - if (device()->hasAtomicSupport()) { -#ifdef EGLFS_ENABLE_DRM_ATOMIC - drmModeAtomicReq *request = device()->threadLocalAtomicRequest(); - if (request) { - drmModeAtomicAddProperty(request, op.connector_id, op.crtcIdPropertyId, op.crtc_id); - drmModeAtomicAddProperty(request, op.crtc_id, op.modeIdPropertyId, op.mode_blob_id); - drmModeAtomicAddProperty(request, op.crtc_id, op.activePropertyId, 1); - } -#endif - } else { - int ret = drmModeSetCrtc(fd, - op.crtc_id, - fb, - 0, 0, - &op.connector_id, 1, - &op.modes[op.mode]); - - if (ret == 0) - setPowerState(PowerStateOn); - else - qErrnoWarning(errno, "Could not set DRM mode for screen %s", qPrintable(name())); - } - } - } -} - -void QEglFSKmsGbmScreen::waitForFlip() -{ - if (m_headless || m_cloneSource || modeChangeRequested()) - return; - - // Avoid permission denied error when session is not active - if (!Aurora::PlatformSupport::Logind::instance()->isSessionActive()) - return; - - // Don't lock the mutex unless we actually need to - if (!m_gbm_bo_next) - return; - - m_flipMutex.lock(); - device()->eventReader()->startWaitFlip(this, &m_flipMutex, &m_flipCond); - m_flipCond.wait(&m_flipMutex); - m_flipMutex.unlock(); - - flipFinished(); - -#if EGLFS_ENABLE_DRM_ATOMIC - device()->threadLocalAtomicReset(); -#endif -} - -void QEglFSKmsGbmScreen::flip() -{ - // For headless screen just return silently. It is not necessarily an error - // to end up here, so show no warnings. - if (m_headless) - return; - - if (m_cloneSource) { - qWarning("Screen %s clones another screen. swapBuffers() not allowed.", qPrintable(name())); - return; - } - - if (modeChangeRequested()) - return; - - if (!m_gbm_surface) { - qWarning("Cannot sync before platform init!"); - return; - } - - m_gbm_bo_next = gbm_surface_lock_front_buffer(m_gbm_surface); - if (!m_gbm_bo_next) { - qWarning("Could not lock GBM surface front buffer!"); - return; - } - - FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next); - ensureModeSet(fb->fb); - - KmsOutput &op(output()); - const int fd = device()->fd(); - m_flipPending = true; - - if (device()->hasAtomicSupport()) { -#ifdef EGLFS_ENABLE_DRM_ATOMIC - drmModeAtomicReq *request = device()->threadLocalAtomicRequest(); - if (request) { - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->framebufferPropertyId, fb->fb); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcPropertyId, op.crtc_id); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcwidthPropertyId, - op.size.width() << 16); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcXPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcYPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcheightPropertyId, - op.size.height() << 16); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcXPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcYPropertyId, 0); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcwidthPropertyId, - m_output.modes[m_output.mode].hdisplay); - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcheightPropertyId, - m_output.modes[m_output.mode].vdisplay); - - static int zpos = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ZPOS"); - if (zpos) - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->zposPropertyId, zpos); - static uint blendOp = uint(qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_BLEND_OP")); - if (blendOp) - drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->blendOpPropertyId, blendOp); - } -#endif - } else { - int ret = drmModePageFlip(fd, - op.crtc_id, - fb->fb, - DRM_MODE_PAGE_FLIP_EVENT, - this); - if (ret) { - qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name())); - m_flipPending = false; - gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); - m_gbm_bo_next = nullptr; - return; - } - } - - for (CloneDestination &d : m_cloneDests) { - if (d.screen != this) { - d.screen->ensureModeSet(fb->fb); - d.cloneFlipPending = true; - - if (device()->hasAtomicSupport()) { -#ifdef EGLFS_ENABLE_DRM_ATOMIC - drmModeAtomicReq *request = device()->threadLocalAtomicRequest(); - if (request) { - drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id, - d.screen->output().eglfs_plane->framebufferPropertyId, fb->fb); - drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id, - d.screen->output().eglfs_plane->crtcPropertyId, op.crtc_id); - } -#endif - } else { - int ret = drmModePageFlip(fd, - d.screen->output().crtc_id, - fb->fb, - DRM_MODE_PAGE_FLIP_EVENT, - d.screen); - if (ret) { - qErrnoWarning("Could not queue DRM page flip for clone screen %s", qPrintable(name())); - d.cloneFlipPending = false; - } - } - } - } - -#ifdef EGLFS_ENABLE_DRM_ATOMIC - device()->threadLocalAtomicCommit(this); -#endif -} - -void QEglFSKmsGbmScreen::setCursorTheme(const QString &name, int size) -{ - if (!m_cursor.isNull()) - m_cursor->setCursorTheme(name, size); -} - -void QEglFSKmsGbmScreen::setModeChangeRequested(bool enabled) -{ - m_modeChangeRequested = enabled; -} - -void QEglFSKmsGbmScreen::flipFinished() -{ - if (m_cloneSource) { - m_cloneSource->cloneDestFlipFinished(this); - return; - } - - m_flipPending = false; - updateFlipStatus(); -} - -void QEglFSKmsGbmScreen::cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen) -{ - for (CloneDestination &d : m_cloneDests) { - if (d.screen == cloneDestScreen) { - d.cloneFlipPending = false; - break; - } - } - updateFlipStatus(); -} - -void QEglFSKmsGbmScreen::updateFlipStatus() -{ - Q_ASSERT(!m_cloneSource); - - if (m_flipPending) - return; - - for (const CloneDestination &d : qAsConst(m_cloneDests)) { - if (d.cloneFlipPending) - return; - } - - if (m_gbm_bo_current) - gbm_surface_release_buffer(m_gbm_surface, - m_gbm_bo_current); - - m_gbm_bo_current = m_gbm_bo_next; - m_gbm_bo_next = nullptr; -} - -void QEglFSKmsGbmScreen::recordFrame(unsigned int tv_sec, unsigned int tv_usec) -{ - if (!isRecordingEnabled()) - return; - - // We don't want to be called every flip - setRecordingEnabled(false); - - auto *bo = m_gbm_bo_current; - - auto *frameEvent = new Aurora::PlatformSupport::ScreenCastFrameEvent(); - frameEvent->screen = screen(); - frameEvent->offset = rawGeometry().topLeft(); - frameEvent->size = QSize(gbm_bo_get_width(bo), gbm_bo_get_height(bo)); - frameEvent->drmFormat = gbmFormatToDrmFormat(gbm_bo_get_format(bo)); - frameEvent->modifier = gbm_bo_get_modifier(bo); - frameEvent->numObjects = 1; - QCoreApplication::postEvent(QCoreApplication::instance(), frameEvent); - - auto *objectEvent = new Aurora::PlatformSupport::ScreenCastObjectEvent(); - objectEvent->screen = screen(); - objectEvent->index = 0; - objectEvent->fd = gbm_bo_get_fd(bo); - objectEvent->stride = gbm_bo_get_stride(bo); - objectEvent->size = gbm_bo_get_width(bo) * gbm_bo_get_height(bo) * objectEvent->stride; - objectEvent->planeIndex = 0; - QCoreApplication::postEvent(QCoreApplication::instance(), objectEvent); - - auto *readyEvent = new Aurora::PlatformSupport::ScreenCastReadyEvent(); - readyEvent->screen = screen(); - readyEvent->tv_sec = tv_sec; - readyEvent->tv_nsec = tv_usec * 1000; - QCoreApplication::postEvent(QCoreApplication::instance(), readyEvent); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h deleted file mode 100644 index 6885d70c..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -class QEglFSKmsGbmCursor; - -class QEglFSKmsGbmScreen : public QEglFSKmsScreen -{ -public: - QEglFSKmsGbmScreen(QEglFSKmsDevice *device, const KmsOutput &output, bool headless); - ~QEglFSKmsGbmScreen(); - - QPlatformCursor *cursor() const override; - - gbm_surface *createGbmSurface(EGLConfig eglConfig, const QSize &size); - gbm_surface *createSurface(EGLConfig eglConfig); - void resetSurface(); - void setSurface(gbm_surface *surface); - - void initCloning(QPlatformScreen *screenThisScreenClones, - const QVector &screensCloningThisScreen); - - void waitForFlip() override; - - void flip(); - - void setCursorTheme(const QString &name, int size) override; - - void setModeChangeRequested(bool enabled) override; - -private: - void flipFinished(); - void ensureModeSet(uint32_t fb); - void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen); - void updateFlipStatus(); - void recordFrame(unsigned int tv_sec, unsigned int tv_usec); - - gbm_surface *m_gbm_surface; - - gbm_bo *m_gbm_bo_current; - gbm_bo *m_gbm_bo_next; - bool m_flipPending; - - QMutex m_flipMutex; - QWaitCondition m_flipCond; - - QScopedPointer m_cursor; - - struct FrameBuffer { - uint32_t fb = 0; - }; - static void bufferDestroyedHandler(gbm_bo *bo, void *data); - FrameBuffer *framebufferForBufferObject(gbm_bo *bo); - - QEglFSKmsGbmScreen *m_cloneSource; - struct CloneDestination { - QEglFSKmsGbmScreen *screen = nullptr; - bool cloneFlipPending = false; - }; - QVector m_cloneDests; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp deleted file mode 100644 index d9a5259f..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsgbmwindow.h" -#include "qeglfskmsgbmintegration.h" -#include "qeglfskmsgbmscreen.h" - -#include - -QT_BEGIN_NAMESPACE - -#ifndef EGL_EXT_platform_base -typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); -#endif - -void QEglFSKmsGbmWindow::resetSurface() -{ - QEglFSKmsGbmScreen *gbmScreen = static_cast(screen()); - EGLDisplay display = gbmScreen->display(); - QSurfaceFormat platformFormat = m_integration->surfaceFormatFor(window()->requestedFormat()); - m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); - m_format = q_glFormatFromConfig(display, m_config, platformFormat); - // One fullscreen window per screen -> the native window is simply the gbm_surface the screen created. - m_window = reinterpret_cast(gbmScreen->createSurface(m_config)); - - PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC createPlatformWindowSurface = nullptr; - const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) { - createPlatformWindowSurface = reinterpret_cast( - eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT")); - } - - if (createPlatformWindowSurface) { - m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast(m_window), nullptr); - } else { - qCDebug(qLcEglfsKmsDebug, "No eglCreatePlatformWindowSurface for GBM, falling back to eglCreateWindowSurface"); - m_surface = eglCreateWindowSurface(display, m_config, m_window, nullptr); - } -} - -void QEglFSKmsGbmWindow::invalidateSurface() -{ - QEglFSKmsGbmScreen *gbmScreen = static_cast(screen()); - QEglFSWindow::invalidateSurface(); - gbmScreen->resetSurface(); -} - -bool QEglFSKmsGbmWindow::resizeSurface(const QSize &size) -{ - QEglFSKmsGbmIntegration *integration = const_cast(m_integration); - - QEglFSKmsGbmScreen *gbmScreen = static_cast(screen()); - EGLDisplay display = gbmScreen->display(); - QSurfaceFormat platformFormat = m_integration->surfaceFormatFor(window()->requestedFormat()); - m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); - m_format = q_glFormatFromConfig(display, m_config, platformFormat); - // One fullscreen window per screen -> the native window is simply the gbm_surface the screen created. - EGLNativeWindowType window = reinterpret_cast(gbmScreen->createGbmSurface(m_config, size)); - - PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC createPlatformWindowSurface = nullptr; - const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) { - createPlatformWindowSurface = reinterpret_cast( - eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT")); - } - - EGLSurface surface = EGL_NO_SURFACE; - - if (createPlatformWindowSurface) { - surface = createPlatformWindowSurface(display, m_config, reinterpret_cast(window), nullptr); - } else { - qCDebug(qLcEglfsKmsDebug, "No eglCreatePlatformWindowSurface for GBM, falling back to eglCreateWindowSurface"); - surface = eglCreateWindowSurface(display, m_config, window, nullptr); - } - - if (Q_UNLIKELY(surface == EGL_NO_SURFACE)) { - integration->destroyNativeWindow(window); - return false; - } - - gbmScreen->setSurface(reinterpret_cast(window)); - - // Keep track of the old surface - EGLSurface oldSurface = m_surface; - EGLNativeWindowType oldWindow = m_window; - - // Switch to the new one - m_window = window; - m_surface = surface; - - // New surface created: destroy the old one - if (oldSurface != EGL_NO_SURFACE) - eglDestroySurface(display, oldSurface); - if (oldWindow) - integration->destroyNativeWindow(oldWindow); - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h deleted file mode 100644 index 5d9335c1..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "private/qeglfswindow_p.h" - -QT_BEGIN_NAMESPACE - -class QEglFSKmsGbmIntegration; - -class QEglFSKmsGbmWindow : public QEglFSWindow -{ -public: - QEglFSKmsGbmWindow(QWindow *w, const QEglFSKmsGbmIntegration *integration) - : QEglFSWindow(w), - m_integration(integration) - { } - - ~QEglFSKmsGbmWindow() { destroy(); } - - void resetSurface() override; - void invalidateSurface() override; - bool resizeSurface(const QSize &size) override; - -private: - const QEglFSKmsGbmIntegration *m_integration; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/CMakeLists.txt b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/CMakeLists.txt deleted file mode 100644 index 064d25b7..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_plugin(eglfs-kms-egldevice-integration - TYPE - liri/egldeviceintegrations - SOURCES - qeglfskmsegldevice.cpp - qeglfskmsegldevice.h - qeglfskmsegldeviceintegration.cpp - qeglfskmsegldeviceintegration.h - qeglfskmsegldevicemain.cpp - qeglfskmsegldevicescreen.cpp - qeglfskmsegldevicescreen.h - DEFINES - ${DEFINES} - PUBLIC_DEFINES - QT_EGL_NO_X11 - LIBRARIES - Liri::EglFSDeviceIntegration - Liri::EglFSDeviceIntegrationPrivate - Liri::EglFSKmsSupport - Liri::EglFSKmsSupportPrivate - PkgConfig::EGL -) - -liri_extend_target(eglfs-kms-egldevice-integration CONDITION FEATURE_aurora_drm_atomic - DEFINES - EGLFS_ENABLE_DRM_ATOMIC -) - -liri_finalize_plugin(eglfs-kms-egldevice-integration) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.json deleted file mode 100644 index 169ba1eb..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "eglfs_kms_egldevice" ] -} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp deleted file mode 100644 index cdbd2a6e..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsegldevice.h" -#include "qeglfskmsegldevicescreen.h" -#include "qeglfskmsegldeviceintegration.h" -#include "private/qeglfsintegration_p.h" -#include "private/qeglfscursor_p.h" - -#include - -#include - -using namespace Liri; - -QT_BEGIN_NAMESPACE - -QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path) - : QEglFSKmsDevice(screenConfig, path), - m_devInt(devInt), - m_globalCursor(nullptr) -{ -} - -bool QEglFSKmsEglDevice::open() -{ - Q_ASSERT(fd() == -1); - - Logind *logind = Logind::instance(); - - if (!logind->isConnected()) { - qCWarning(qLcEglfsKmsDebug, "Cannot open DRM device %s: logind connection was not established", - qPrintable(devicePath())); - return false; - } - if (!logind->hasSessionControl()) { - qCWarning(qLcEglfsKmsDebug, "Cannot open DRM device %s: session control not acquired", - qPrintable(devicePath())); - return false; - } - - int fd = logind->takeDevice(devicePath()); - if (Q_UNLIKELY(fd < 0)) - qFatal("Could not open DRM (NV) device"); - - setFd(fd); - - return true; -} - -void QEglFSKmsEglDevice::close() -{ - // Note: screens are gone at this stage. - - if (fd() != -1) { - Logind::instance()->releaseDevice(fd()); - setFd(-1); - } -} - -void *QEglFSKmsEglDevice::nativeDisplay() const -{ - return m_devInt->eglDevice(); -} - -QPlatformScreen *QEglFSKmsEglDevice::createScreen(const QKmsOutput &output) -{ - QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(this, output); -#if QT_CONFIG(opengl) - if (!m_globalCursor && !screenConfig()->separateScreens()) { - qCDebug(qLcEglfsKmsDebug, "Creating new global mouse cursor"); - m_globalCursor = new QEglFSCursor(screen); - } -#endif - return screen; -} - -void QEglFSKmsEglDevice::destroyGlobalCursor() -{ - if (m_globalCursor) { - qCDebug(qLcEglfsKmsDebug, "Destroying global mouse cursor"); - delete m_globalCursor; - m_globalCursor = nullptr; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h deleted file mode 100644 index 7b269d28..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -QT_BEGIN_NAMESPACE - -class QPlatformCursor; -class QEglFSKmsEglDeviceIntegration; - -class QEglFSKmsEglDevice: public QEglFSKmsDevice -{ -public: - QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path); - - bool open() override; - void close() override; - - void *nativeDisplay() const override; - - QPlatformScreen *createScreen(const QKmsOutput &output) override; - - QPlatformCursor *globalCursor() { return m_globalCursor; } - void destroyGlobalCursor(); - -private: - QEglFSKmsEglDeviceIntegration *m_devInt; - QPlatformCursor *m_globalCursor; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp deleted file mode 100644 index 3e781962..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsegldeviceintegration.h" -#include "qeglfskmsegldevice.h" -#include "qeglfskmsegldevicescreen.h" -#include -#include "private/qeglfswindow_p.h" -#include "private/qeglfscursor_p.h" -#include -#include - -QT_BEGIN_NAMESPACE - -QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration() - : m_egl_device(EGL_NO_DEVICE_EXT) - , m_funcs(nullptr) -{ - qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created"); -} - -QSurfaceFormat QEglFSKmsEglDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const -{ - QSurfaceFormat format = QEglFSKmsIntegration::surfaceFormatFor(inputFormat); - format.setAlphaBufferSize(8); - return format; -} - -EGLint QEglFSKmsEglDeviceIntegration::surfaceType() const -{ - return EGL_STREAM_BIT_KHR; -} - -EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) -{ - qCDebug(qLcEglfsKmsDebug, "Creating display"); - - EGLDisplay display; - - if (m_funcs->has_egl_platform_device) { - display = m_funcs->get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, nullptr); - } else { - qWarning("EGL_EXT_platform_device not available, falling back to legacy path!"); - display = eglGetDisplay(nativeDisplay); - } - - if (Q_UNLIKELY(display == EGL_NO_DISPLAY)) - qFatal("Could not get EGL display"); - - EGLint major, minor; - if (Q_UNLIKELY(!eglInitialize(display, &major, &minor))) - qFatal("Could not initialize egl display"); - - if (Q_UNLIKELY(!eglBindAPI(EGL_OPENGL_ES_API))) - qFatal("Failed to bind EGL_OPENGL_ES_API\n"); - - return display; -} - -bool QEglFSKmsEglDeviceIntegration::supportsSurfacelessContexts() const -{ - // Returning false disables the usage of EGL_KHR_surfaceless_context even when the - // extension is available. This is just what we need since, at least with NVIDIA - // 352.00 making a null surface current with a context breaks. - return false; -} - -bool QEglFSKmsEglDeviceIntegration::supportsPBuffers() const -{ - return true; -} - -class QEglFSKmsEglDeviceWindow : public QEglFSWindow -{ -public: - QEglFSKmsEglDeviceWindow(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration) - : QEglFSWindow(w) - , m_integration(integration) - , m_egl_stream(EGL_NO_STREAM_KHR) - { } - - ~QEglFSKmsEglDeviceWindow() { destroy(); } - - void invalidateSurface() override; - void resetSurface() override; - - const QEglFSKmsEglDeviceIntegration *m_integration; - EGLStreamKHR m_egl_stream; - EGLint m_latency; -}; - -void QEglFSKmsEglDeviceWindow::invalidateSurface() -{ - QEglFSWindow::invalidateSurface(); - m_integration->m_funcs->destroy_stream(screen()->display(), m_egl_stream); -} - -void QEglFSKmsEglDeviceWindow::resetSurface() -{ - qCDebug(qLcEglfsKmsDebug, "Creating stream"); - - EGLDisplay display = screen()->display(); - EGLint streamAttribs[3]; - int streamAttribCount = 0; - int fifoLength = qEnvironmentVariableIntValue("QT_QPA_EGLFS_STREAM_FIFO_LENGTH"); - if (fifoLength > 0) { - streamAttribs[streamAttribCount++] = EGL_STREAM_FIFO_LENGTH_KHR; - streamAttribs[streamAttribCount++] = fifoLength; - } - streamAttribs[streamAttribCount++] = EGL_NONE; - - m_egl_stream = m_integration->m_funcs->create_stream(display, streamAttribs); - if (m_egl_stream == EGL_NO_STREAM_KHR) { - qWarning("resetSurface: Couldn't create EGLStream for native window"); - return; - } - - qCDebug(qLcEglfsKmsDebug, "Created stream %p on display %p", m_egl_stream, display); - - EGLint count; - if (m_integration->m_funcs->query_stream(display, m_egl_stream, EGL_STREAM_FIFO_LENGTH_KHR, &count)) { - if (count > 0) - qCDebug(qLcEglfsKmsDebug, "Using EGLStream FIFO mode with %d frames", count); - else - qCDebug(qLcEglfsKmsDebug, "Using EGLStream mailbox mode"); - } else { - qCDebug(qLcEglfsKmsDebug, "Could not query number of EGLStream FIFO frames"); - } - - if (!m_integration->m_funcs->get_output_layers(display, nullptr, nullptr, 0, &count) || count == 0) { - qWarning("No output layers found"); - return; - } - - qCDebug(qLcEglfsKmsDebug, "Output has %d layers", count); - - QVector layers; - layers.resize(count); - EGLint actualCount; - if (!m_integration->m_funcs->get_output_layers(display, nullptr, layers.data(), count, &actualCount)) { - qWarning("Failed to get layers"); - return; - } - - QEglFSKmsEglDeviceScreen *cur_screen = static_cast(screen()); - Q_ASSERT(cur_screen); - QKmsOutput &output(cur_screen->output()); - const uint32_t wantedId = !output.wants_forced_plane ? output.crtc_id : output.forced_plane_id; - qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", wantedId); - - EGLOutputLayerEXT layer = EGL_NO_OUTPUT_LAYER_EXT; - for (int i = 0; i < actualCount; ++i) { - EGLAttrib id; - if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) { - qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], (int) id); - if (id == EGLAttrib(wantedId)) - layer = layers[i]; - } else if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) { - qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], (int) id); - if (id == EGLAttrib(wantedId)) - layer = layers[i]; - } else { - qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - unknown", i, layers[i]); - } - } - - QByteArray reqLayerIndex = qgetenv("QT_QPA_EGLFS_LAYER_INDEX"); - if (!reqLayerIndex.isEmpty()) { - int idx = reqLayerIndex.toInt(); - if (idx >= 0 && idx < layers.count()) { - qCDebug(qLcEglfsKmsDebug, "EGLOutput layer index override = %d", idx); - layer = layers[idx]; - } - } - - if (layer == EGL_NO_OUTPUT_LAYER_EXT) { - qWarning("resetSurface: Couldn't get EGLOutputLayer for native window"); - return; - } - - qCDebug(qLcEglfsKmsDebug, "Using layer %p", layer); - - if (!m_integration->m_funcs->stream_consumer_output(display, m_egl_stream, layer)) - qWarning("resetSurface: Unable to connect stream"); - - m_config = QEglFSDeviceIntegration::chooseConfig(display, m_integration->surfaceFormatFor(window()->requestedFormat())); - m_format = q_glFormatFromConfig(display, m_config); - qCDebug(qLcEglfsKmsDebug) << "Stream producer format is" << m_format; - - const int w = cur_screen->rawGeometry().width(); - const int h = cur_screen->rawGeometry().height(); - qCDebug(qLcEglfsKmsDebug, "Creating stream producer surface of size %dx%d", w, h); - - const EGLint stream_producer_attribs[] = { - EGL_WIDTH, w, - EGL_HEIGHT, h, - EGL_NONE - }; - - m_surface = m_integration->m_funcs->create_stream_producer_surface(display, m_config, m_egl_stream, stream_producer_attribs); - if (m_surface == EGL_NO_SURFACE) - return; - - qCDebug(qLcEglfsKmsDebug, "Created stream producer surface %p", m_surface); -} - -QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const -{ - QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this); - - m_funcs->initialize(eglWindow->screen()->display()); - if (Q_UNLIKELY(!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream && - m_funcs->has_egl_stream_producer_eglsurface && m_funcs->has_egl_stream_consumer_egloutput))) - qFatal("Required extensions missing!"); - - return eglWindow; -} - -QKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice() -{ - if (Q_UNLIKELY(!query_egl_device())) - qFatal("Could not set up EGL device!"); - - const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT); - if (Q_UNLIKELY(!deviceName)) - qFatal("Failed to query device name from EGLDevice"); - - return new QEglFSKmsEglDevice(this, screenConfig(), QLatin1String(deviceName)); -} - -bool QEglFSKmsEglDeviceIntegration::query_egl_device() -{ - m_funcs = new QEGLStreamConvenience; - if (Q_UNLIKELY(!m_funcs->has_egl_device_base)) - qFatal("EGL_EXT_device_base missing"); - - EGLint num_devices = 0; - if (m_funcs->query_devices(1, &m_egl_device, &num_devices) != EGL_TRUE) { - qWarning("eglQueryDevicesEXT failed: eglError: %x", eglGetError()); - return false; - } - - qCDebug(qLcEglfsKmsDebug, "Found %d EGL devices", num_devices); - - if (num_devices < 1 || m_egl_device == EGL_NO_DEVICE_EXT) { - qWarning("eglQueryDevicesEXT could not find any EGL devices"); - return false; - } - - return true; -} - -QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *screen) const -{ -#if QT_CONFIG(opengl) - if (screenConfig()->separateScreens()) - return new QEglFSCursor(screen); -#else - Q_UNUSED(screen); -#endif - return nullptr; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h deleted file mode 100644 index ad954696..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QEglFSKmsEglDeviceIntegration : public QEglFSKmsIntegration -{ -public: - QEglFSKmsEglDeviceIntegration(); - - QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const override; - EGLint surfaceType() const override; - EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) override; - bool supportsSurfacelessContexts() const override; - bool supportsPBuffers() const override; - QEglFSWindow *createWindow(QWindow *window) const override; - - EGLDeviceEXT eglDevice() const { return m_egl_device; } - -protected: - QKmsDevice *createDevice() override; - QPlatformCursor *createCursor(QPlatformScreen *screen) const override; - -private: - bool setup_kms(); - bool query_egl_device(); - - EGLDeviceEXT m_egl_device; - QEGLStreamConvenience *m_funcs; - - friend class QEglFSKmsEglDeviceWindow; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp deleted file mode 100644 index 5763ab45..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsegldeviceintegration.h" - -QT_BEGIN_NAMESPACE - -class QEglFSKmsEglDeviceIntegrationPlugin : public QEglFSDeviceIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms_egldevice.json") - -public: - QEglFSDeviceIntegration *create() override { return new QEglFSKmsEglDeviceIntegration; } -}; - -QT_END_NAMESPACE - -#include "qeglfskmsegldevicemain.moc" diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp deleted file mode 100644 index 5a62e437..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsegldevicescreen.h" -#include "qeglfskmsegldevice.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsDevice *device, const QKmsOutput &output) - : QEglFSKmsScreen(device, output) -{ -} - -QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen() -{ - const int remainingScreenCount = qGuiApp->screens().count(); - qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); - if (!remainingScreenCount && !device()->screenConfig()->separateScreens()) - static_cast(device())->destroyGlobalCursor(); -} - -QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const -{ - // The base class creates a cursor via integration->createCursor() - // in its ctor. With separateScreens just use that. Otherwise - // there's a virtual desktop and the device has a global cursor - // and the base class has no dedicated cursor at all. - // config->hwCursor() is ignored for now, just use the standard OpenGL cursor. - return device()->screenConfig()->separateScreens() - ? QEglFSScreen::cursor() - : static_cast(device())->globalCursor(); -} - -void QEglFSKmsEglDeviceScreen::waitForFlip() -{ - QKmsOutput &op(output()); - const int fd = device()->fd(); - const uint32_t w = op.modes[op.mode].hdisplay; - const uint32_t h = op.modes[op.mode].vdisplay; - - if (!op.mode_set) { - op.mode_set = true; - - drmModeCrtcPtr currentMode = drmModeGetCrtc(fd, op.crtc_id); - const bool alreadySet = currentMode && currentMode->width == w && currentMode->height == h; - if (currentMode) - drmModeFreeCrtc(currentMode); - if (alreadySet) { - // Maybe detecting the DPMS mode could help here, but there are no properties - // exposed on the connector apparently. So rely on an env var for now. - static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); - if (!alwaysDoSet) { - qCDebug(qLcEglfsKmsDebug, "Mode already set"); - return; - } - } - - qCDebug(qLcEglfsKmsDebug, "Setting mode"); - int ret = drmModeSetCrtc(fd, op.crtc_id, - uint32_t(-1), 0, 0, - &op.connector_id, 1, - &op.modes[op.mode]); - if (ret) - qErrnoWarning(errno, "drmModeSetCrtc failed"); - } - - if (!op.forced_plane_set) { - op.forced_plane_set = true; - - if (op.wants_forced_plane) { - qCDebug(qLcEglfsKmsDebug, "Setting plane %u", op.forced_plane_id); - int ret = drmModeSetPlane(fd, op.forced_plane_id, op.crtc_id, uint32_t(-1), 0, - 0, 0, w, h, - 0 << 16, 0 << 16, op.size.width() << 16, op.size.height() << 16); - if (ret == -1) - qErrnoWarning(errno, "drmModeSetPlane failed"); - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h deleted file mode 100644 index 38a54794..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -QT_BEGIN_NAMESPACE - -class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen -{ -public: - QEglFSKmsEglDeviceScreen(QEglFSKmsDevice *device, const QKmsOutput &output); - ~QEglFSKmsEglDeviceScreen(); - - QPlatformCursor *cursor() const override; - - void waitForFlip() override; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/CMakeLists.txt b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/CMakeLists.txt deleted file mode 100644 index 0920fdda..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_module(EglFSKmsSupport - DESCRIPTION - "KMS support for EGL device integration" - SOURCES - qeglfskmsdevice.cpp - qeglfskmsdevice.h - qeglfskmseventreader.cpp qeglfskmseventreader.h - qeglfskmshelpers.h - qeglfskmsintegration.cpp - qeglfskmsintegration.h - qeglfskmsscreen.cpp - qeglfskmsscreen.h - INSTALL_HEADERS - qeglfskmsdevice.h - qeglfskmshelpers.h - qeglfskmsintegration.h - qeglfskmsscreen.h - DEFINES - QT_NO_CAST_FROM_ASCII - QT_NO_FOREACH - ${DEFINES} - PUBLIC_DEFINES - QT_EGL_NO_X11 - PUBLIC_LIBRARIES - Qt5::Core - Qt5::CorePrivate - Qt5::Gui - Qt5::GuiPrivate - Liri::EglFSDeviceIntegration - Liri::EglFSDeviceIntegrationPrivate - Liri::AuroraEdidSupport - Liri::AuroraEdidSupportPrivate - Liri::AuroraKmsSupport - Liri::AuroraKmsSupportPrivate - PkgConfig::Libdrm - PkgConfig::Gbm - PkgConfig::EGL - NO_CMAKE - NO_PKGCONFIG -) - -liri_extend_target(EglFSKmsSupport CONDITION FEATURE_aurora_drm_atomic - DEFINES - EGLFS_ENABLE_DRM_ATOMIC -) - -liri_finalize_module(EglFSKmsSupport) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp deleted file mode 100644 index 7c56c040..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsdevice.h" -#include "qeglfskmsintegration.h" -#include "qeglfskmsscreen.h" -#include "private/qeglfsintegration_p.h" -#include - -QT_BEGIN_NAMESPACE - -QEglFSKmsDevice::QEglFSKmsDevice(KmsScreenConfig *screenConfig, const QString &path) - : KmsDevice(screenConfig, path) -{ -} - -void QEglFSKmsDevice::registerScreen(QPlatformScreen *screen, - bool isPrimary, - const QPoint &virtualPos, - const QList &virtualSiblings) -{ - QEglFSKmsScreen *s = static_cast(screen); - s->setVirtualPosition(virtualPos); - s->setVirtualSiblings(virtualSiblings); -#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 3) - QWindowSystemInterface::handleScreenAdded(s, isPrimary); -#else - static_cast(QGuiApplicationPrivate::platformIntegration())->addScreen(s, isPrimary); -#endif - -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h deleted file mode 100644 index c5519a0c..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -#include "qeglfsglobal_p.h" -#include "qeglfskmseventreader.h" - -QT_BEGIN_NAMESPACE - -using namespace Aurora::PlatformSupport; - -class Q_EGLFS_EXPORT QEglFSKmsDevice : public KmsDevice -{ -public: - QEglFSKmsDevice(KmsScreenConfig *screenConfig, const QString &path); - - void registerScreen(QPlatformScreen *screen, - bool isPrimary, - const QPoint &virtualPos, - const QList &virtualSiblings) override; - - QEglFSKmsEventReader *eventReader() { return &m_eventReader; } - -protected: - QEglFSKmsEventReader m_eventReader; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp deleted file mode 100644 index 645a0ae2..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmseventreader.h" -#include "qeglfskmsdevice.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) -{ - Q_UNUSED(fd); - Q_UNUSED(sequence); - Q_UNUSED(tv_sec); - Q_UNUSED(tv_usec); - - QEglFSKmsEventReaderThread *t = static_cast(QThread::currentThread()); - t->eventHost()->handlePageFlipCompleted(user_data); -} - -class RegisterWaitFlipEvent : public QEvent -{ -public: - static const QEvent::Type TYPE = QEvent::Type(QEvent::User + 1); - RegisterWaitFlipEvent(void *key, QMutex *mutex, QWaitCondition *cond) - : QEvent(TYPE), key(key), mutex(mutex), cond(cond) - { } - void *key; - QMutex *mutex; - QWaitCondition *cond; -}; - -bool QEglFSKmsEventHost::event(QEvent *event) -{ - if (event->type() == RegisterWaitFlipEvent::TYPE) { - RegisterWaitFlipEvent *e = static_cast(event); - PendingFlipWait *p = &pendingFlipWaits[0]; - PendingFlipWait *end = p + MAX_FLIPS; - while (p < end) { - if (!p->key) { - p->key = e->key; - p->mutex = e->mutex; - p->cond = e->cond; - updateStatus(); - return true; - } - ++p; - } - qWarning("Cannot queue page flip wait (more than %d screens?)", MAX_FLIPS); - e->mutex->lock(); - e->cond->wakeOne(); - e->mutex->unlock(); - return true; - } - return QObject::event(event); -} - -void QEglFSKmsEventHost::updateStatus() -{ - void **begin = &completedFlips[0]; - void **end = begin + MAX_FLIPS; - - for (int i = 0; i < MAX_FLIPS; ++i) { - PendingFlipWait *w = pendingFlipWaits + i; - if (!w->key) - continue; - - void **p = begin; - while (p < end) { - if (*p == w->key) { - *p = nullptr; - w->key = nullptr; - w->mutex->lock(); - w->cond->wakeOne(); - w->mutex->unlock(); - return; - } - ++p; - } - } -} - -void QEglFSKmsEventHost::handlePageFlipCompleted(void *key) -{ - void **begin = &completedFlips[0]; - void **end = begin + MAX_FLIPS; - void **p = begin; - while (p < end) { - if (*p == key) { - updateStatus(); - return; - } - ++p; - } - p = begin; - while (p < end) { - if (!*p) { - *p = key; - updateStatus(); - return; - } - ++p; - } - qWarning("Cannot store page flip status (more than %d screens?)", MAX_FLIPS); -} - -void QEglFSKmsEventReaderThread::run() -{ - qCDebug(qLcEglfsKmsDebug, "Event reader thread: entering event loop"); - - QSocketNotifier notifier(m_fd, QSocketNotifier::Read); - QObject::connect(¬ifier, &QSocketNotifier::activated, ¬ifier, [this] { - drmEventContext drmEvent; - memset(&drmEvent, 0, sizeof(drmEvent)); - drmEvent.version = 2; - drmEvent.vblank_handler = nullptr; - drmEvent.page_flip_handler = pageFlipHandler; - drmHandleEvent(m_fd, &drmEvent); - }); - - exec(); - - m_ev.moveToThread(thread()); // move back to the thread where m_ev was created - - qCDebug(qLcEglfsKmsDebug, "Event reader thread: event loop stopped"); -} - -QEglFSKmsEventReader::~QEglFSKmsEventReader() -{ - destroy(); -} - -void QEglFSKmsEventReader::create(QEglFSKmsDevice *device) -{ - destroy(); - - if (!device) - return; - - m_device = device; - - qCDebug(qLcEglfsKmsDebug, "Initalizing event reader for device %p fd %d", - m_device, m_device->fd()); - - m_thread = new QEglFSKmsEventReaderThread(m_device->fd()); - m_thread->start(); - - // Change thread affinity for the event host, so that postEvent() - // goes through the event reader thread's event loop for that object. - m_thread->eventHost()->moveToThread(m_thread); -} - -void QEglFSKmsEventReader::destroy() -{ - if (!m_device) - return; - - qCDebug(qLcEglfsKmsDebug, "Stopping event reader for device %p", m_device); - - if (m_thread) { - m_thread->quit(); - m_thread->wait(); - delete m_thread; - m_thread = nullptr; - } - - m_device = nullptr; -} - -void QEglFSKmsEventReader::startWaitFlip(void *key, QMutex *mutex, QWaitCondition *cond) -{ - if (m_thread) { - QCoreApplication::postEvent(m_thread->eventHost(), - new RegisterWaitFlipEvent(key, mutex, cond)); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h deleted file mode 100644 index 3b6eb13f..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmseventreader.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "qeglfsglobal_p.h" -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QEglFSKmsDevice; - -struct QEglFSKmsEventHost : public QObject -{ - struct PendingFlipWait { - void *key; - QMutex *mutex; - QWaitCondition *cond; - }; - - static const int MAX_FLIPS = 32; - void *completedFlips[MAX_FLIPS] = {}; - QEglFSKmsEventHost::PendingFlipWait pendingFlipWaits[MAX_FLIPS] = {}; - - bool event(QEvent *event) override; - void updateStatus(); - void handlePageFlipCompleted(void *key); -}; - -class QEglFSKmsEventReaderThread : public QThread -{ -public: - QEglFSKmsEventReaderThread(int fd) : m_fd(fd) { } - void run() override; - QEglFSKmsEventHost *eventHost() { return &m_ev; } - -private: - int m_fd; - QEglFSKmsEventHost m_ev; -}; - -class Q_EGLFS_EXPORT QEglFSKmsEventReader -{ -public: - ~QEglFSKmsEventReader(); - - void create(QEglFSKmsDevice *device); - void destroy(); - - void startWaitFlip(void *key, QMutex *mutex, QWaitCondition *cond); - -private: - QEglFSKmsDevice *m_device = nullptr; - QEglFSKmsEventReaderThread *m_thread = nullptr; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmshelpers.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmshelpers.h deleted file mode 100644 index 347f87ca..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmshelpers.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include - -QT_BEGIN_NAMESPACE - -inline QString q_fourccToString(uint code) -{ - QString s; - s.reserve(4); - s.append(code & 0xff); - s.append((code >> 8) & 0xff); - s.append((code >> 16) & 0xff); - s.append((code >> 24) & 0xff); - return s; -} - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp deleted file mode 100644 index 967331e2..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsintegration.h" -#include "qeglfskmsscreen.h" - -#include - -#include -#include -#include - -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "aurora.eglfs.kms", QtInfoMsg) - -using namespace Aurora::PlatformSupport; - -QEglFSKmsIntegration::QEglFSKmsIntegration() - : m_device(nullptr), - m_screenConfig(new KmsScreenConfig) -{ -} - -QEglFSKmsIntegration::~QEglFSKmsIntegration() -{ - delete m_screenConfig; -} - -void QEglFSKmsIntegration::platformInit() -{ - qCDebug(qLcEglfsKmsDebug, "platformInit: Opening DRM device"); - m_device = createDevice(); - if (Q_UNLIKELY(!m_device->open())) - qFatal("Could not open DRM device"); - - // Redraw all toplevel windows as soon as the session is reactivated - QObject::connect(Logind::instance(), &Logind::sessionActiveChanged, [this](bool active) { - if (active) { - const auto windows = qGuiApp->topLevelWindows(); - for (QWindow *window : windows) - QWindowSystemInterface::handleExposeEvent(window, QRegion(QRect(QPoint(0, 0), window->size()))); - } - }); -} - -void QEglFSKmsIntegration::platformDestroy() -{ - qCDebug(qLcEglfsKmsDebug, "platformDestroy: Closing DRM device"); - m_device->close(); - delete m_device; - m_device = nullptr; -} - -EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const -{ - Q_ASSERT(m_device); - return (EGLNativeDisplayType) m_device->nativeDisplay(); -} - -bool QEglFSKmsIntegration::usesDefaultScreen() -{ - return false; -} - -void QEglFSKmsIntegration::screenInit() -{ - m_device->createScreens(); -} - -QSurfaceFormat QEglFSKmsIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const -{ - QSurfaceFormat format(inputFormat); - format.setRenderableType(QSurfaceFormat::OpenGLES); - format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - format.setRedBufferSize(8); - format.setGreenBufferSize(8); - format.setBlueBufferSize(8); - return format; -} - -bool QEglFSKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - switch (cap) { - case QPlatformIntegration::ThreadedPixmaps: - case QPlatformIntegration::OpenGL: - case QPlatformIntegration::ThreadedOpenGL: - return true; - default: - return false; - } -} - -void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const -{ - QWindow *window = static_cast(surface->surface()); - QEglFSKmsScreen *screen = static_cast(window->screen()->handle()); - - screen->waitForFlip(); -} - -bool QEglFSKmsIntegration::supportsPBuffers() const -{ - return m_screenConfig->supportsPBuffers(); -} - -void *QEglFSKmsIntegration::nativeResourceForIntegration(const QByteArray &name) -{ - if (name == QByteArrayLiteral("dri_fd") && m_device) - return (void *) (qintptr) m_device->fd(); - -#ifdef EGLFS_ENABLE_DRM_ATOMIC - if (name == QByteArrayLiteral("dri_atomic_request") && m_device) - return (void *) (qintptr) m_device->threadLocalAtomicRequest(); -#endif - return nullptr; -} - -void *QEglFSKmsIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) -{ - QEglFSKmsScreen *s = static_cast(screen->handle()); - if (s) { - if (resource == QByteArrayLiteral("dri_crtcid")) - return (void *) (qintptr) s->output().crtc_id; - if (resource == QByteArrayLiteral("dri_connectorid")) - return (void *) (qintptr) s->output().connector_id; - } - return nullptr; -} - -KmsDevice *QEglFSKmsIntegration::device() const -{ - return m_device; -} - -KmsScreenConfig *QEglFSKmsIntegration::screenConfig() const -{ - return m_screenConfig; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h deleted file mode 100644 index 9e8119ab..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "private/qeglfsdeviceintegration_p.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -namespace Aurora { -namespace PlatformSupport { -class KmsDevice; -class KmsScreenConfig; -} -} - -Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEglFSDeviceIntegration -{ -public: - QEglFSKmsIntegration(); - ~QEglFSKmsIntegration(); - - void platformInit() override; - void platformDestroy() override; - EGLNativeDisplayType platformDisplay() const override; - bool usesDefaultScreen() override; - void screenInit() override; - QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const override; - bool hasCapability(QPlatformIntegration::Capability cap) const override; - void waitForVSync(QPlatformSurface *surface) const override; - bool supportsPBuffers() const override; - void *nativeResourceForIntegration(const QByteArray &name) override; - void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override; - - Aurora::PlatformSupport::KmsDevice *device() const; - Aurora::PlatformSupport::KmsScreenConfig *screenConfig() const; - -protected: - virtual Aurora::PlatformSupport::KmsDevice *createDevice() = 0; - - Aurora::PlatformSupport::KmsDevice *m_device; - Aurora::PlatformSupport::KmsScreenConfig *m_screenConfig; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp deleted file mode 100644 index cd2ba2f3..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Copyright (C) 2018 Pier Luigi Fiorini -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfskmsscreen.h" -#include "qeglfskmsdevice.h" -#include "qeglfsintegration_p.h" -#include "vthandler.h" - -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) - -class QEglFSKmsInterruptHandler : public QObject -{ -public: - QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) { - m_vtHandler = static_cast(QGuiApplicationPrivate::platformIntegration())->vtHandler(); - connect(m_vtHandler, &Aurora::PlatformSupport::VtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode); - connect(m_vtHandler, &Aurora::PlatformSupport::VtHandler::aboutToSuspend, this, &QEglFSKmsInterruptHandler::restoreVideoMode); - } - -public slots: - void restoreVideoMode() { m_screen->restoreMode(); } - -private: - Aurora::PlatformSupport::VtHandler *m_vtHandler; - QEglFSKmsScreen *m_screen; -}; - -QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsDevice *device, const KmsOutput &output, bool headless) - : QEglFSScreen(static_cast(QGuiApplicationPrivate::platformIntegration())->display()) - , m_device(device) - , m_output(output) - , m_cursorOutOfRange(false) - , m_powerState(PowerStateOn) - , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) - , m_headless(headless) -{ - m_siblings << this; // gets overridden later - - if (m_output.edid_blob) { - QByteArray edid(reinterpret_cast(m_output.edid_blob->data), m_output.edid_blob->length); - if (m_edid.parse(edid)) - qCDebug(qLcEglfsKmsDebug, "EDID data for output \"%s\": identifier '%s', manufacturer '%s', model '%s', serial '%s', physical size: %.2fx%.2f", - name().toLatin1().constData(), - m_edid.identifier.toLatin1().constData(), - m_edid.manufacturer.toLatin1().constData(), - m_edid.model.toLatin1().constData(), - m_edid.serialNumber.toLatin1().constData(), - m_edid.physicalSize.width(), m_edid.physicalSize.height()); - else - qCDebug(qLcEglfsKmsDebug) << "Failed to parse EDID data for output" << name(); // keep this debug, not warning - } else { - qCDebug(qLcEglfsKmsDebug) << "No EDID data for output" << name(); - } -} - -QEglFSKmsScreen::~QEglFSKmsScreen() -{ - m_output.cleanup(m_device); - delete m_interruptHandler; -} - -void QEglFSKmsScreen::setVirtualPosition(const QPoint &pos) -{ - m_pos = pos; -} - -// Reimplement rawGeometry(), not geometry(). The base class implementation of -// geometry() calls rawGeometry() and may apply additional transforms. -QRect QEglFSKmsScreen::rawGeometry() const -{ - if (m_headless) - return QRect(QPoint(0, 0), m_device->screenConfig()->headlessSize()); - - return QRect(m_pos.x(), m_pos.y(), - m_output.size.width(), - m_output.size.height()); -} - -int QEglFSKmsScreen::depth() const -{ - return format() == QImage::Format_RGB16 ? 16 : 32; -} - -QImage::Format QEglFSKmsScreen::format() const -{ - // the result can be slightly incorrect, it won't matter in practice - switch (m_output.drm_format) { - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_ABGR8888: - return QImage::Format_ARGB32; - case DRM_FORMAT_RGB565: - case DRM_FORMAT_BGR565: - return QImage::Format_RGB16; - case DRM_FORMAT_XRGB2101010: - return QImage::Format_RGB30; - case DRM_FORMAT_XBGR2101010: - return QImage::Format_BGR30; - case DRM_FORMAT_ARGB2101010: - return QImage::Format_A2RGB30_Premultiplied; - case DRM_FORMAT_ABGR2101010: - return QImage::Format_A2BGR30_Premultiplied; - default: - return QImage::Format_RGB32; - } -} - -QSizeF QEglFSKmsScreen::physicalSize() const -{ - if (!m_output.physical_size.isEmpty()) { - return m_output.physical_size; - } else { - const QSize s = geometry().size(); - return QSizeF(0.254 * s.width(), 0.254 * s.height()); - } -} - -QDpi QEglFSKmsScreen::logicalDpi() const -{ - const QSizeF ps = physicalSize(); - const QSize s = geometry().size(); - - if (!ps.isEmpty() && !s.isEmpty()) - return QDpi(25.4 * s.width() / ps.width(), - 25.4 * s.height() / ps.height()); - else - return QDpi(100, 100); -} - -Qt::ScreenOrientation QEglFSKmsScreen::nativeOrientation() const -{ - return Qt::PrimaryOrientation; -} - -Qt::ScreenOrientation QEglFSKmsScreen::orientation() const -{ - return Qt::PrimaryOrientation; -} - -QString QEglFSKmsScreen::name() const -{ - return !m_headless ? m_output.name : QStringLiteral("qt_Headless"); -} - -QString QEglFSKmsScreen::manufacturer() const -{ - return m_edid.manufacturer; -} - -QString QEglFSKmsScreen::model() const -{ - return m_edid.model.isEmpty() ? m_edid.identifier : m_edid.model; -} - -QString QEglFSKmsScreen::serialNumber() const -{ - return m_edid.serialNumber; -} - -void QEglFSKmsScreen::waitForFlip() -{ -} - -void QEglFSKmsScreen::restoreMode() -{ - m_output.restoreMode(m_device); -} - -qreal QEglFSKmsScreen::refreshRate() const -{ - if (m_headless) - return 60; - - quint32 refresh = m_output.modes[m_output.mode].vrefresh; - return refresh > 0 ? refresh : 60; -} - -QVector QEglFSKmsScreen::modes() const -{ - QVector list; - list.reserve(m_output.modes.size()); - - for (const drmModeModeInfo &info : qAsConst(m_output.modes)) - list.append({QSize(info.hdisplay, info.vdisplay), - qreal(info.vrefresh > 0 ? info.vrefresh : 60)}); - - return list; -} - -int QEglFSKmsScreen::currentMode() const -{ - return m_output.mode; -} - -int QEglFSKmsScreen::preferredMode() const -{ - return m_output.preferred_mode; -} - -QPlatformScreen::SubpixelAntialiasingType QEglFSKmsScreen::subpixelAntialiasingTypeHint() const -{ - return m_output.subpixelAntialiasingTypeHint(); -} - -QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const -{ - return m_powerState; -} - -void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state) -{ - m_output.setPowerState(m_device, state); - m_powerState = state; -} - -bool QEglFSKmsScreen::setMode(const QSize &size, qreal refreshRate) -{ - int modeIndex = m_output.mode; - - int i = 0; - for (const drmModeModeInfo &mode : qAsConst(m_output.modes)) { - if (size.width() == mode.hdisplay && size.height() == mode.vdisplay) { - // Ignore interlaced modes - if (mode.flags & DRM_MODE_FLAG_INTERLACE) - continue; - - // Verify refresh rate - if (mode.vrefresh != refreshRate) - continue; - - modeIndex = i; - break; - } - i++; - } - - if (m_output.mode == modeIndex) { - qCDebug(qLcEglfsKmsDebug, "Won't change mode because it's already set to %ux%u at %.2f Hz", size.width(), size.height(), refreshRate); - return false; - } - - qCInfo(qLcEglfsKmsDebug, "Changing mode to %ux%u at %.2f Hz", size.width(), size.height(), refreshRate); - - // Mode will be changed next flip - m_output.mode = modeIndex; - m_output.size = size; - m_output.mode_set = false; - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h deleted file mode 100644 index f42fad81..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Pier Luigi Fiorini -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include "private/qeglfsscreen_p.h" -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -using namespace Aurora::PlatformSupport; - -class QEglFSKmsDevice; -class QEglFSKmsInterruptHandler; - -class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen -{ -public: - QEglFSKmsScreen(QEglFSKmsDevice *device, const KmsOutput &output, bool headless = false); - ~QEglFSKmsScreen(); - - void setVirtualPosition(const QPoint &pos); - - QRect rawGeometry() const override; - - int depth() const override; - QImage::Format format() const override; - - QSizeF physicalSize() const override; - QDpi logicalDpi() const override; - Qt::ScreenOrientation nativeOrientation() const override; - Qt::ScreenOrientation orientation() const override; - - QString name() const override; - - QString manufacturer() const override; - QString model() const override; - QString serialNumber() const override; - - qreal refreshRate() const override; - - QList virtualSiblings() const override { return m_siblings; } - void setVirtualSiblings(QList sl) { m_siblings = sl; } - - QVector modes() const override; - - int currentMode() const override; - int preferredMode() const override; - - QEglFSKmsDevice *device() const { return m_device; } - - virtual void waitForFlip(); - - KmsOutput &output() { return m_output; } - void restoreMode(); - - SubpixelAntialiasingType subpixelAntialiasingTypeHint() const override; - - QPlatformScreen::PowerState powerState() const override; - void setPowerState(QPlatformScreen::PowerState state) override; - - bool setMode(const QSize &size, qreal refreshRate); - - bool isCursorOutOfRange() const { return m_cursorOutOfRange; } - void setCursorOutOfRange(bool b) { m_cursorOutOfRange = b; } - -protected: - QEglFSKmsDevice *m_device; - - KmsOutput m_output; - EdidParser m_edid; - QPoint m_pos; - bool m_cursorOutOfRange; - - QList m_siblings; - - PowerState m_powerState; - - QEglFSKmsInterruptHandler *m_interruptHandler; - - bool m_headless; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/CMakeLists.txt b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/CMakeLists.txt deleted file mode 100644 index 27d26644..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini -# -# SPDX-License-Identifier: BSD-3-Clause - -liri_add_plugin(eglfs-x11-integration - TYPE - liri/egldeviceintegrations - SOURCES - qeglfsx11integration.cpp qeglfsx11integration.h - qeglfsx11main.cpp - DEFINES - QT_EGL_NO_X11 - INCLUDE_DIRECTORIES - ../../api - LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Gui - Qt::GuiPrivate - Liri::EglFSDeviceIntegration - Liri::EglFSDeviceIntegrationPrivate - X11::X11 - X11::xcb - X11::X11_xcb - XCB::XCB -) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.json deleted file mode 100644 index 84625278..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "eglfs_x11" ] -} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp deleted file mode 100644 index e0b1caf2..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#include "qeglfsx11integration.h" -#include - -#include -#include - -/* Make no mistake: This is not a replacement for the xcb platform plugin. - This here is barely an extremely useful tool for developing eglfs itself because - it allows to do so without any requirements for devices or drivers. */ - -QT_BEGIN_NAMESPACE - -class EventReader : public QThread -{ -public: - EventReader(QEglFSX11Integration *integration) - : m_integration(integration) { } - - void run() override; - -private: - QEglFSX11Integration *m_integration; -}; - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -Q_CONSTINIT static QBasicAtomicInt running = Q_BASIC_ATOMIC_INITIALIZER(0); -#else -static QBasicAtomicInt running; -#endif - -void EventReader::run() -{ - xcb_generic_event_t *event = nullptr; - while (running.loadRelaxed() && (event = xcb_wait_for_event(m_integration->connection()))) { - uint response_type = event->response_type & ~0x80; - switch (response_type) { - case XCB_CLIENT_MESSAGE: { - xcb_client_message_event_t *client = (xcb_client_message_event_t *) event; - const xcb_atom_t *atoms = m_integration->atoms(); - if (client->format == 32 - && client->type == atoms[Atoms::WM_PROTOCOLS] - && client->data.data32[0] == atoms[Atoms::WM_DELETE_WINDOW]) { - QWindow *window = m_integration->platformWindow() ? m_integration->platformWindow()->window() : nullptr; - if (window) - QWindowSystemInterface::handleCloseEvent(window); - } - break; - } - default: - break; - } - } -} - -void QEglFSX11Integration::sendConnectionEvent(xcb_atom_t a) -{ - xcb_client_message_event_t event; - memset(&event, 0, sizeof(event)); - - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.sequence = 0; - event.window = m_connectionEventListener; - event.type = a; - - xcb_send_event(m_connection, false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event); - xcb_flush(m_connection); -} - -#define DISPLAY ((Display *) m_display) - -void QEglFSX11Integration::platformInit() -{ - m_display = XOpenDisplay(nullptr); - if (Q_UNLIKELY(!m_display)) - qFatal("Could not open display"); - - XSetEventQueueOwner(DISPLAY, XCBOwnsEventQueue); - m_connection = XGetXCBConnection(DISPLAY); - - running.ref(); - - xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(m_connection)); - - m_connectionEventListener = xcb_generate_id(m_connection); - xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, - m_connectionEventListener, it.data->root, - 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, - it.data->root_visual, 0, nullptr); - - m_eventReader = new EventReader(this); - m_eventReader->start(); -} - -void QEglFSX11Integration::platformDestroy() -{ - running.deref(); - - sendConnectionEvent(XCB_ATOM_NONE); - - m_eventReader->wait(); - delete m_eventReader; - m_eventReader = nullptr; - - XCloseDisplay(DISPLAY); - m_display = nullptr; - m_connection = nullptr; -} - -EGLNativeDisplayType QEglFSX11Integration::platformDisplay() const -{ - return DISPLAY; -} - -QSize QEglFSX11Integration::screenSize() const -{ - if (m_screenSize.isEmpty()) { - QList env = qgetenv("EGLFS_X11_SIZE").split('x'); - if (env.size() == 2) { - m_screenSize = QSize(env.at(0).toInt(), env.at(1).toInt()); - } else { - XWindowAttributes a; - if (XGetWindowAttributes(DISPLAY, DefaultRootWindow(DISPLAY), &a)) - m_screenSize = QSize(a.width, a.height); - } - } - return m_screenSize; -} - -EGLNativeWindowType QEglFSX11Integration::createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) -{ - Q_UNUSED(format); - - m_platformWindow = platformWindow; - - xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(m_connection)); - m_window = xcb_generate_id(m_connection); - xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, m_window, it.data->root, - 0, 0, size.width(), size.height(), 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, it.data->root_visual, - 0, nullptr); - - xcb_intern_atom_cookie_t cookies[Atoms::N_ATOMS]; - static const char *atomNames[Atoms::N_ATOMS] = { - "_NET_WM_NAME", - "UTF8_STRING", - "WM_PROTOCOLS", - "WM_DELETE_WINDOW", - "_NET_WM_STATE", - "_NET_WM_STATE_FULLSCREEN" - }; - - for (int i = 0; i < Atoms::N_ATOMS; ++i) { - cookies[i] = xcb_intern_atom(m_connection, false, strlen(atomNames[i]), atomNames[i]); - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_connection, cookies[i], nullptr); - m_atoms[i] = reply->atom; - free(reply); - } - - // Set window title - xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_window, - m_atoms[Atoms::_NET_WM_NAME], m_atoms[Atoms::UTF8_STRING], 8, 5, "EGLFS"); - - // Enable WM_DELETE_WINDOW - xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_window, - m_atoms[Atoms::WM_PROTOCOLS], XCB_ATOM_ATOM, 32, 1, &m_atoms[Atoms::WM_DELETE_WINDOW]); - - // Go fullscreen. - xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE, m_window, - m_atoms[Atoms::_NET_WM_STATE], XCB_ATOM_ATOM, 32, 1, &m_atoms[Atoms::_NET_WM_STATE_FULLSCREEN]); - - xcb_map_window(m_connection, m_window); - - xcb_flush(m_connection); - - return qt_egl_cast(m_window); -} - -void QEglFSX11Integration::destroyNativeWindow(EGLNativeWindowType window) -{ - xcb_destroy_window(m_connection, qt_egl_cast(window)); -} - -bool QEglFSX11Integration::hasCapability(QPlatformIntegration::Capability cap) const -{ - Q_UNUSED(cap); - return false; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h deleted file mode 100644 index 02f7424e..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#pragma once - -#include "private/qeglfsdeviceintegration_p.h" - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -namespace Atoms { - enum { - _NET_WM_NAME = 0, - UTF8_STRING, - WM_PROTOCOLS, - WM_DELETE_WINDOW, - _NET_WM_STATE, - _NET_WM_STATE_FULLSCREEN, - - N_ATOMS - }; -} - -class EventReader; - -class QEglFSX11Integration : public QEglFSDeviceIntegration -{ -public: - QEglFSX11Integration() : m_connection(nullptr), m_window(0), m_eventReader(nullptr) {} - - void platformInit() override; - void platformDestroy() override; - EGLNativeDisplayType platformDisplay() const override; - QSize screenSize() const override; - EGLNativeWindowType createNativeWindow(QPlatformWindow *window, - const QSize &size, - const QSurfaceFormat &format) override; - void destroyNativeWindow(EGLNativeWindowType window) override; - bool hasCapability(QPlatformIntegration::Capability cap) const override; - - xcb_connection_t *connection() { return m_connection; } - const xcb_atom_t *atoms() const { return m_atoms; } - QPlatformWindow *platformWindow() { return m_platformWindow; } - -private: - void sendConnectionEvent(xcb_atom_t a); - - void *m_display; - xcb_connection_t *m_connection; - xcb_atom_t m_atoms[Atoms::N_ATOMS]; - xcb_window_t m_window; - EventReader *m_eventReader; - xcb_window_t m_connectionEventListener; - QPlatformWindow *m_platformWindow; - mutable QSize m_screenSize; -}; - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp deleted file mode 100644 index b46e8884..00000000 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#include "private/qeglfsdeviceintegration_p.h" -#include "qeglfsx11integration.h" - -QT_BEGIN_NAMESPACE - -class QEglFSX11IntegrationPlugin : public QEglFSDeviceIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_x11.json") - -public: - QEglFSDeviceIntegration *create() override { return new QEglFSX11Integration; } -}; - -QT_END_NAMESPACE - -#include "qeglfsx11main.moc" diff --git a/src/plugins/platforms/eglfs/qeglfsmain.cpp b/src/plugins/platforms/eglfs/qeglfsmain.cpp deleted file mode 100644 index f673b220..00000000 --- a/src/plugins/platforms/eglfs/qeglfsmain.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "qeglfsintegration_p.h" - -QT_BEGIN_NAMESPACE - -class QEglFSIntegrationPlugin : public QPlatformIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "aurora-eglfs.json") -public: - QPlatformIntegration *create(const QString&, const QStringList&) override; -}; - -QPlatformIntegration* QEglFSIntegrationPlugin::create(const QString& system, const QStringList& paramList) -{ - Q_UNUSED(paramList); - if (!system.compare(QLatin1String("aurora-eglfs"), Qt::CaseInsensitive)) - return new QEglFSIntegration; - - return 0; - return nullptr; -} - -QT_END_NAMESPACE - -#include "qeglfsmain.moc" diff --git a/tests/auto/logind/CMakeLists.txt b/tests/auto/logind/CMakeLists.txt deleted file mode 100644 index c4fd9fc8..00000000 --- a/tests/auto/logind/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2024 Pier Luigi Fiorini -# SPDX-License-Identifier: BSD-3-Clause - -add_executable(tst_liri_logind - fakelogind.cpp fakelogind.h - tst_logind.cpp -) -target_link_libraries(tst_liri_logind PRIVATE Liri::AuroraLogind) - -add_test(NAME tst_liri_logind - COMMAND tst_liri_logind) diff --git a/tests/auto/logind/fakelogind.cpp b/tests/auto/logind/fakelogind.cpp deleted file mode 100644 index 06d9f8c7..00000000 --- a/tests/auto/logind/fakelogind.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:GPL3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include "fakelogind.h" - -/* - * FakeLogindSession - */ - -FakeLogindSession::FakeLogindSession(const QString &path, QObject *parent) - : QObject(parent) - , m_path(path) -{ - QDBusConnection::sessionBus().registerObject( - m_path, this, QDBusConnection::ExportScriptableContents); -} - -FakeLogindSession::~FakeLogindSession() -{ - QDBusConnection::sessionBus().unregisterObject(m_path); -} - -const QString &FakeLogindSession::path() -{ - return m_path; -} - -bool FakeLogindSession::isActive() const -{ - return true; -} - -quint32 FakeLogindSession::vtNumber() const -{ - return 1; -} - -void FakeLogindSession::TakeControl(bool force) -{ - Q_UNUSED(force); -} - -void FakeLogindSession::ReleaseControl() -{ -} - -/* - * FakeLogind - */ - -FakeLogind::FakeLogind(QObject *parent) - : QObject(parent) - , m_session(new FakeLogindSession(QStringLiteral("/org/freedesktop/login1/session/_1"), this)) -{ - QDBusConnection::sessionBus().registerObject( - QStringLiteral("/org/freedesktop/login1"), this, - QDBusConnection::ExportScriptableContents); - QDBusConnection::sessionBus().registerService( - QStringLiteral("org.freedesktop.login1")); -} - -FakeLogind::~FakeLogind() -{ - QDBusConnection::sessionBus().unregisterObject( - QStringLiteral("/org/freedesktop/login1")); - QDBusConnection::sessionBus().unregisterService( - QStringLiteral("org.freedesktop.login1")); -} - -void FakeLogind::doLock() -{ - Q_EMIT m_session->Lock(); -} - -void FakeLogind::doUnlock() -{ - Q_EMIT m_session->Unlock(); -} - -void FakeLogind::doPrepareForSleep(bool before) -{ - Q_EMIT PrepareForSleep(before); -} - -void FakeLogind::doPrepareForShutdown(bool before) -{ - Q_EMIT PrepareForShutdown(before); -} - -QDBusObjectPath FakeLogind::GetSessionByPID(quint32 pid) -{ - Q_UNUSED(pid); - return QDBusObjectPath(m_session->path()); -} - -int FakeLogind::TakeDevice(int maj, int min) -{ - Q_UNUSED(maj); - Q_UNUSED(min); - return -1; -} - -void FakeLogind::ReleaseDevice(int maj, int min) -{ - Q_UNUSED(maj); - Q_UNUSED(min); -} diff --git a/tests/auto/logind/fakelogind.h b/tests/auto/logind/fakelogind.h deleted file mode 100644 index a217d693..00000000 --- a/tests/auto/logind/fakelogind.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:GPL3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include -#include - -class FakeLogindSession : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool Active READ isActive CONSTANT) - Q_PROPERTY(uint VTNr READ vtNumber CONSTANT) - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.login1.Session") -public: - explicit FakeLogindSession(const QString &path, QObject *parent = nullptr); - virtual ~FakeLogindSession(); - - const QString &path(); - - bool isActive() const; - quint32 vtNumber() const; - -public Q_SLOTS: - Q_SCRIPTABLE void TakeControl(bool force); - Q_SCRIPTABLE void ReleaseControl(); - -Q_SIGNALS: - Q_SCRIPTABLE void Lock(); - Q_SCRIPTABLE void Unlock(); - -private: - QString m_path; -}; - -class FakeLogind : public QObject -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.login1.Manager") -public: - explicit FakeLogind(QObject *parent = nullptr); - virtual ~FakeLogind(); - - // Methods to trigger signals - void doLock(); - void doUnlock(); - void doPrepareForSleep(bool before); - void doPrepareForShutdown(bool before); - -public Q_SLOTS: - Q_SCRIPTABLE QDBusObjectPath GetSessionByPID(quint32 pid); - Q_SCRIPTABLE int TakeDevice(int maj, int min); - Q_SCRIPTABLE void ReleaseDevice(int maj, int min); - -Q_SIGNALS: - Q_SCRIPTABLE void PrepareForSleep(bool before); - Q_SCRIPTABLE void PrepareForShutdown(bool before); - -private: - FakeLogindSession *m_session; -}; diff --git a/tests/auto/logind/tst_logind.cpp b/tests/auto/logind/tst_logind.cpp deleted file mode 100644 index 0054a52e..00000000 --- a/tests/auto/logind/tst_logind.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:GPL3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include - -#include "fakelogind.h" - -using namespace Aurora::PlatformSupport; - -class CustomLogind : public Logind -{ - Q_OBJECT -public: - CustomLogind(QObject *parent = nullptr) - : Logind(QDBusConnection::sessionBus(), parent) - { - } -}; - -class TestLogind : public QObject -{ - Q_OBJECT -public: - TestLogind(QObject *parent = nullptr) - : QObject(parent) - { - } - -private Q_SLOTS: - void initTestCase() - { - qunsetenv("XDG_SESSION_ID"); - } - - void testConnection() - { - // Integration is initially disconnected - CustomLogind *logind = new CustomLogind; - QVERIFY(!logind->isConnected()); - - // Spy on connectedChanged(bool) and create the service - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - QVERIFY(logind->isConnected()); - - // Delete - fakeLogind->deleteLater(); - QVERIFY(spyConnected.wait()); - QVERIFY(!logind->isConnected()); - logind->deleteLater(); - } - - void testRegistration() - { - // Integration is initially disconnected - CustomLogind *logind = new CustomLogind; - QVERIFY(!logind->isConnected()); - - // Spy on connectedChanged(bool) and create the service - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QScopedPointer fakeLogind(new FakeLogind); - QVERIFY(spyConnected.wait()); - QVERIFY(logind->isConnected()); - spyConnected.clear(); - - // Now the service goes away - fakeLogind.reset(); - - // And the integration should no longer be connected - QVERIFY(spyConnected.wait()); - QVERIFY(!logind->isConnected()); - spyConnected.clear(); - - // Now the service is brought up again - fakeLogind.reset(new FakeLogind); - - // And the integration should connect again - QVERIFY(spyConnected.wait()); - QVERIFY(logind->isConnected()); - - // Delete - fakeLogind.reset(); - logind->deleteLater(); - } - - void testPropertySessionActive() - { - CustomLogind *logind = new CustomLogind; - - // Spy on sessionActiveChanged(bool) - QSignalSpy spySessionActive(logind, SIGNAL(sessionActiveChanged(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spySessionActive.wait()); - QVERIFY(logind->isSessionActive()); - - fakeLogind->deleteLater(); - logind->deleteLater(); - - QTest::qWait(1000); - } - - void testPropertyVtNumber() - { - CustomLogind *logind = new CustomLogind; - QCOMPARE(logind->vtNumber(), -1); - - // Spy on vtNumberChanged(int) - QSignalSpy spyVtNumber(logind, SIGNAL(vtNumberChanged(int))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyVtNumber.wait()); - QCOMPARE(logind->vtNumber(), 1); - - fakeLogind->deleteLater(); - logind->deleteLater(); - - QTest::qWait(1000); - } - - void testSessionControl() - { - // Connect to a fake logind service and wait for the signal - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyTakeControl(logind, SIGNAL(hasSessionControlChanged(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Take control as soon as we are connected to logind and - // then release control, we should have received two signals - logind->takeControl(); - spyTakeControl.wait(); - logind->releaseControl(); - spyTakeControl.wait(); - QCOMPARE(spyTakeControl.count(), 2); - - fakeLogind->deleteLater(); - logind->deleteLater(); - - QTest::qWait(1000); - } - - void testLockUnlock() - { - // Connect and spy on lockSessionRequested() and unlockSessionRequested() - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyLock(logind, SIGNAL(lockSessionRequested())); - QSignalSpy spyUnlock(logind, SIGNAL(unlockSessionRequested())); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Lock - fakeLogind->doLock(); - QVERIFY(spyLock.wait()); - - // Unlock - fakeLogind->doUnlock(); - QVERIFY(spyUnlock.wait()); - - logind->deleteLater(); - fakeLogind->deleteLater(); - - QTest::qWait(1000); - } - - void testPrepareForSleep() - { - // Connect and spy on prepareForSleep(bool) - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyPrepare(logind, SIGNAL(prepareForSleep(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Prepare for sleep before - fakeLogind->doPrepareForSleep(true); - QVERIFY(spyPrepare.wait()); - - // Prepare for sleep after - fakeLogind->doPrepareForSleep(false); - QVERIFY(spyPrepare.wait()); - - logind->deleteLater(); - fakeLogind->deleteLater(); - - QTest::qWait(1000); - } - - void testPrepareForShutdown() - { - // Connect and spy on prepareForShutdown(bool) - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyPrepare(logind, SIGNAL(prepareForShutdown(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Prepare for shutdown before - fakeLogind->doPrepareForShutdown(true); - QVERIFY(spyPrepare.wait()); - - // Prepare for shutdown after - fakeLogind->doPrepareForShutdown(false); - QVERIFY(spyPrepare.wait()); - - logind->deleteLater(); - fakeLogind->deleteLater(); - - QTest::qWait(1000); - } -}; - -QTEST_MAIN(TestLogind) - -#include "tst_logind.moc" diff --git a/tests/auto/udev/CMakeLists.txt b/tests/auto/udev/CMakeLists.txt deleted file mode 100644 index 2b49e5f7..00000000 --- a/tests/auto/udev/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2024 Pier Luigi Fiorini -# SPDX-License-Identifier: BSD-3-Clause - -find_package(Umockdev REQUIRED) - -add_executable(tst_qtudev tst_udev.cpp) - -target_link_libraries(tst_qtudev - PRIVATE - Liri::AuroraUdev - PkgConfig::Umockdev -) - -add_test(NAME tst_qtudev - COMMAND tst_qtudev) diff --git a/tests/auto/udev/test.umockdev b/tests/auto/udev/test.umockdev deleted file mode 100644 index b2e1f830..00000000 --- a/tests/auto/udev/test.umockdev +++ /dev/null @@ -1,2139 +0,0 @@ -P: /devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda -N: sda -S: disk/by-id/ata-TOSHIBA_MQ01ABD100_Y49DSZAOS -S: disk/by-id/wwn-0x50000395e5c02a10 -S: disk/by-path/pci-0000:00:1f.2-ata-1 -E: DEVLINKS=/dev/disk/by-path/pci-0000:00:1f.2-ata-1 /dev/disk/by-id/ata-TOSHIBA_MQ01ABD100_Y49DSZAOS /dev/disk/by-id/wwn-0x50000395e5c02a10 -E: DEVNAME=/dev/sda -E: DEVTYPE=disk -E: ID_ATA=1 -E: ID_ATA_DOWNLOAD_MICROCODE=1 -E: ID_ATA_FEATURE_SET_APM=1 -E: ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=128 -E: ID_ATA_FEATURE_SET_APM_ENABLED=1 -E: ID_ATA_FEATURE_SET_HPA=1 -E: ID_ATA_FEATURE_SET_HPA_ENABLED=1 -E: ID_ATA_FEATURE_SET_PM=1 -E: ID_ATA_FEATURE_SET_PM_ENABLED=1 -E: ID_ATA_FEATURE_SET_SECURITY=1 -E: ID_ATA_FEATURE_SET_SECURITY_ENABLED=0 -E: ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=224 -E: ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=224 -E: ID_ATA_FEATURE_SET_SECURITY_FROZEN=1 -E: ID_ATA_FEATURE_SET_SMART=1 -E: ID_ATA_FEATURE_SET_SMART_ENABLED=1 -E: ID_ATA_ROTATION_RATE_RPM=5400 -E: ID_ATA_SATA=1 -E: ID_ATA_SATA_SIGNAL_RATE_GEN1=1 -E: ID_ATA_SATA_SIGNAL_RATE_GEN2=1 -E: ID_ATA_WRITE_CACHE=1 -E: ID_ATA_WRITE_CACHE_ENABLED=1 -E: ID_BUS=ata -E: ID_MODEL=TOSHIBA_MQ01ABD100 -E: ID_MODEL_ENC=TOSHIBA\x20MQ01ABD100\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 -E: ID_PART_TABLE_TYPE=gpt -E: ID_PART_TABLE_UUID=d23e23f6-f908-40ff-a350-43fd812e104e -E: ID_PATH=pci-0000:00:1f.2-ata-1 -E: ID_PATH_TAG=pci-0000_00_1f_2-ata-1 -E: ID_REVISION=AX001U -E: ID_SERIAL=TOSHIBA_MQ01ABD100_Y49DSZAOS -E: ID_SERIAL_SHORT=Y49DSZAOS -E: ID_TYPE=disk -E: ID_WWN=0x50000395e5c02a10 -E: ID_WWN_WITH_EXTENSION=0x50000395e5c02a10 -E: MAJOR=8 -E: MINOR=0 -E: SUBSYSTEM=block -E: TAGS=:systemd: -A: alignment_offset=0 -L: bdi=../../../../../../../../virtual/bdi/8:0 -A: capability=50 -A: dev=8:0 -L: device=../../../0:0:0:0 -A: discard_alignment=0 -A: events= -A: events_async= -A: events_poll_msecs=-1 -A: ext_range=256 -A: hidden=0 -A: inflight= 0 0 -A: integrity/device_is_integrity_capable=0 -A: integrity/format=none -A: integrity/protection_interval_bytes=0 -A: integrity/read_verify=0 -A: integrity/tag_size=0 -A: integrity/write_generate=0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: queue/add_random=1 -A: queue/chunk_sectors=0 -A: queue/dax=0 -A: queue/discard_granularity=0 -A: queue/discard_max_bytes=0 -A: queue/discard_max_hw_bytes=0 -A: queue/discard_zeroes_data=0 -A: queue/hw_sector_size=512 -A: queue/io_poll=0 -A: queue/io_poll_delay=0 -A: queue/iostats=1 -A: queue/logical_block_size=512 -A: queue/max_discard_segments=1 -A: queue/max_hw_sectors_kb=32767 -A: queue/max_integrity_segments=0 -A: queue/max_sectors_kb=1280 -A: queue/max_segment_size=65536 -A: queue/max_segments=168 -A: queue/minimum_io_size=4096 -A: queue/nomerges=0 -A: queue/nr_requests=128 -A: queue/optimal_io_size=0 -A: queue/physical_block_size=4096 -A: queue/read_ahead_kb=128 -A: queue/rotational=1 -A: queue/rq_affinity=1 -A: queue/scheduler=noop deadline [cfq] -A: queue/write_cache=write back -A: queue/write_same_max_bytes=0 -A: queue/write_zeroes_max_bytes=0 -A: queue/zoned=none -A: range=16 -A: removable=0 -A: ro=0 -A: size=1953525168 -A: stat= 67814 16612 2621625 756732 106843 407838 16775037 16454374 0 748962 17294725 -A: trace/act_mask=disabled -A: trace/enable=0 -A: trace/end_lba=disabled -A: trace/pid=disabled -A: trace/start_lba=disabled - -P: /devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0 -E: DEVTYPE=scsi_device -E: DRIVER=sd -E: MODALIAS=scsi:t-0x00 -E: SUBSYSTEM=scsi -A: blacklist= -A: device_blocked=0 -A: device_busy=0 -A: dh_state=detached -L: driver=../../../../../../../bus/scsi/drivers/sd -A: eh_timeout=10 -A: evt_capacity_change_reported=0 -A: evt_inquiry_change_reported=0 -A: evt_lun_change_reported=0 -A: evt_media_change=0 -A: evt_mode_parameter_change_reported=0 -A: evt_soft_threshold_reached=0 -L: generic=scsi_generic/sg0 -H: inquiry=000005025B0000024154412020202020544F5348494241204D5130314142443131552020000000000000000000000000000000000000000000000060032003000000000000000000000000000000000000000000000000000000000000000000 -A: iocounterbits=32 -A: iodone_cnt=0x2c080 -A: ioerr_cnt=0x90 -A: iorequest_cnt=0x2ccc8 -A: modalias=scsi:t-0x00 -A: model=TOSHIBA MQ01ABD1 -A: ncq_prio_enable=0 -A: power/autosuspend_delay_ms=-1 -A: power/control=on -A: power/runtime_active_time=16246511 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: queue_depth=31 -A: queue_ramp_up_period=120000 -A: queue_type=simple -A: rev=1U -A: scsi_level=6 -A: state=running -A: timeout=30 -A: type=0 -A: unload_heads=0 -A: vendor=ATA -H: vpd_pg80=00800014202020202020202020202059343944535A414F53 -H: vpd_pg83=0083006C02000014202020202020202020202059343944535A414F53020100444154412020202020544F5348494241204D51303141424431303020202020202020202020202020202020202020202020202020202020202020202059343944535A414F530103000850000395E5C02A10 -A: wwid=t10.ATA TOSHIBA MQ01ABD100 Y49DSZAOS - -P: /devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0 -E: DEVTYPE=scsi_target -E: SUBSYSTEM=scsi -A: power/control=auto -A: power/runtime_active_time=16246523 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:1f.2/ata1/host0 -E: DEVTYPE=scsi_host -E: SUBSYSTEM=scsi -A: power/control=auto -A: power/runtime_active_time=16246534 -A: power/runtime_status=active -A: power/runtime_suspended_time=344 - -P: /devices/pci0000:00/0000:00:1f.2 -E: DRIVER=ahci -E: ID_MODEL_FROM_DATABASE=Wildcat Point-LP SATA Controller [AHCI Mode] -E: ID_PCI_CLASS_FROM_DATABASE=Mass storage controller -E: ID_PCI_INTERFACE_FROM_DATABASE=AHCI 1.0 -E: ID_PCI_SUBCLASS_FROM_DATABASE=SATA controller -E: ID_VENDOR_FROM_DATABASE=Intel Corporation -E: MODALIAS=pci:v00008086d00009C83sv00008086sd00002057bc01sc06i01 -E: PCI_CLASS=10601 -E: PCI_ID=8086:9C83 -E: PCI_SLOT_NAME=0000:00:1f.2 -E: PCI_SUBSYS_ID=8086:2057 -E: SUBSYSTEM=pci -A: ari_enabled=0 -A: broken_parity_status=0 -A: class=0x010601 -H: config=8680839C0704B0020301060100000000D1F00000C1F00000B1F00000A1F0000061F00000009013F70000000086805720000000008000000000000000FF020000 -A: consistent_dma_mask_bits=64 -A: d3cold_allowed=1 -A: device=0x9c83 -A: dma_mask_bits=64 -L: driver=../../../bus/pci/drivers/ahci -A: driver_override=(null) -A: enable=1 -A: irq=44 -A: local_cpulist=0-3 -A: local_cpus=f -A: modalias=pci:v00008086d00009C83sv00008086sd00002057bc01sc06i01 -A: msi_bus=1 -A: msi_irqs/44=msi -A: numa_node=-1 -A: power/control=on -A: power/runtime_active_time=16247312 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=disabled -A: power/wakeup_abort_count= -A: power/wakeup_active= -A: power/wakeup_active_count= -A: power/wakeup_count= -A: power/wakeup_expire_count= -A: power/wakeup_last_time_ms= -A: power/wakeup_max_time_ms= -A: power/wakeup_total_time_ms= -A: resource=0x000000000000f0d0 0x000000000000f0d7 0x0000000000040101\n0x000000000000f0c0 0x000000000000f0c3 0x0000000000040101\n0x000000000000f0b0 0x000000000000f0b7 0x0000000000040101\n0x000000000000f0a0 0x000000000000f0a3 0x0000000000040101\n0x000000000000f060 0x000000000000f07f 0x0000000000040101\n0x00000000f7139000 0x00000000f71397ff 0x0000000000040200\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000 -A: revision=0x03 -A: subsystem_device=0x2057 -A: subsystem_vendor=0x8086 -A: vendor=0x8086 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0E:00/input/input0/event0 -N: input/event0 -E: DEVNAME=/dev/input/event0 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-PNP0C0E:00 -E: ID_PATH_TAG=acpi-PNP0C0E_00 -E: LIBINPUT_DEVICE_GROUP=19/0/3:PNP0C0E/button -E: MAJOR=13 -E: MINOR=64 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:64 -L: device=../../input0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0E:00/input/input0 -E: EV=3 -E: ID_FOR_SEAT=input-acpi-PNP0C0E_00 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-PNP0C0E:00 -E: ID_PATH_TAG=acpi-PNP0C0E_00 -E: KEY=4000 0 0 -E: MODALIAS=input:b0019v0000p0003e0000-e0,1,k8E,ramlsfw -E: NAME="Sleep Button" -E: PHYS="PNP0C0E/button/input0" -E: PRODUCT=19/0/3/0 -E: PROP=0 -E: SUBSYSTEM=input -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=3 -A: capabilities/ff=0 -A: capabilities/key=4000 0 0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../PNP0C0E:00 -A: id/bustype=0019 -A: id/product=0003 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0019v0000p0003e0000-e0,1,k8E,ramlsfw -A: name=Sleep Button -A: phys=PNP0C0E/button/input0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0E:00 -E: DRIVER=button -E: ID_VENDOR_FROM_DATABASE=The Linux Foundation -E: MODALIAS=acpi:PNP0C0E: -E: SUBSYSTEM=acpi -L: driver=../../../../bus/acpi/drivers/button -A: hid=PNP0C0E -A: modalias=acpi:PNP0C0E: -A: path=\\_SB_.SLPB -L: physical_node=../../../platform/PNP0C0E:00 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: power/wakeup=enabled -A: power/wakeup_abort_count=0 -A: power/wakeup_active=0 -A: power/wakeup_active_count=0 -A: power/wakeup_count=0 -A: power/wakeup_expire_count=0 -A: power/wakeup_last_time_ms=456 -A: power/wakeup_max_time_ms=0 -A: power/wakeup_total_time_ms=0 -A: status=11 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00 -E: ID_VENDOR_FROM_DATABASE=The Linux Foundation -E: MODALIAS=acpi:LNXSYBUS: -E: SUBSYSTEM=acpi -A: hid=LNXSYBUS -A: modalias=acpi:LNXSYBUS: -A: path=\\_SB_ -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/LNXSYSTM:00 -E: ID_VENDOR_FROM_DATABASE=The Linux Foundation -E: MODALIAS=acpi:LNXSYSTM: -E: SUBSYSTEM=acpi -A: hid=LNXSYSTM -A: modalias=acpi:LNXSYSTM: -A: path=\\ -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input1/event1 -N: input/event1 -E: DEVNAME=/dev/input/event1 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-PNP0C0C:00 -E: ID_PATH_TAG=acpi-PNP0C0C_00 -E: LIBINPUT_DEVICE_GROUP=19/0/1:PNP0C0C/button -E: MAJOR=13 -E: MINOR=65 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:65 -L: device=../../input1 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input1 -E: EV=3 -E: ID_FOR_SEAT=input-acpi-PNP0C0C_00 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-PNP0C0C:00 -E: ID_PATH_TAG=acpi-PNP0C0C_00 -E: KEY=10000000000000 0 -E: MODALIAS=input:b0019v0000p0001e0000-e0,1,k74,ramlsfw -E: NAME="Power Button" -E: PHYS="PNP0C0C/button/input0" -E: PRODUCT=19/0/1/0 -E: PROP=0 -E: SUBSYSTEM=input -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=3 -A: capabilities/ff=0 -A: capabilities/key=10000000000000 0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../PNP0C0C:00 -A: id/bustype=0019 -A: id/product=0001 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0019v0000p0001e0000-e0,1,k74,ramlsfw -A: name=Power Button -A: phys=PNP0C0C/button/input0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00 -E: DRIVER=button -E: ID_VENDOR_FROM_DATABASE=The Linux Foundation -E: MODALIAS=acpi:PNP0C0C: -E: SUBSYSTEM=acpi -L: driver=../../../../bus/acpi/drivers/button -A: hid=PNP0C0C -A: modalias=acpi:PNP0C0C: -A: path=\\_SB_.PWRB -L: physical_node=../../../platform/PNP0C0C:00 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: power/wakeup=enabled -A: power/wakeup_abort_count=0 -A: power/wakeup_active=0 -A: power/wakeup_active_count=0 -A: power/wakeup_count=0 -A: power/wakeup_expire_count=0 -A: power/wakeup_last_time_ms=456 -A: power/wakeup_max_time_ms=0 -A: power/wakeup_total_time_ms=0 -A: status=15 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input11/event10 -N: input/event10 -E: DEVNAME=/dev/input/event10 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: LIBINPUT_DEVICE_GROUP=0/0/0:ALSA -E: MAJOR=13 -E: MINOR=74 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:74 -L: device=../../input11 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input11 -E: EV=21 -E: ID_FOR_SEAT=input-pci-0000_00_03_0 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: MODALIAS=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -E: NAME="HDA Intel HDMI HDMI/DP,pcm=8" -E: PHYS="ALSA" -E: PRODUCT=0/0/0/0 -E: PROP=0 -E: SUBSYSTEM=input -E: SW=140 -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=21 -A: capabilities/ff=0 -A: capabilities/key=0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=140 -L: device=../../card0 -A: id/bustype=0000 -A: id/product=0000 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -A: name=HDA Intel HDMI HDMI/DP,pcm=8 -A: phys=ALSA -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:03.0/sound/card0 -E: ID_BUS=pci -E: ID_FOR_SEAT=sound-pci-0000_00_03_0 -E: ID_MODEL_FROM_DATABASE=Broadwell-U Audio Controller -E: ID_MODEL_ID=0x160c -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: ID_PCI_CLASS_FROM_DATABASE=Multimedia controller -E: ID_PCI_SUBCLASS_FROM_DATABASE=Audio device -E: ID_VENDOR_FROM_DATABASE=Intel Corporation -E: ID_VENDOR_ID=0x8086 -E: SOUND_FORM_FACTOR=internal -E: SOUND_INITIALIZED=1 -E: SUBSYSTEM=sound -E: SYSTEMD_WANTS=sound.target -E: TAGS=:systemd:seat: -L: device=../../../0000:00:03.0 -A: id=HDMI -A: number=0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:03.0 -E: DRIVER=snd_hda_intel -E: ID_MODEL_FROM_DATABASE=Broadwell-U Audio Controller -E: ID_PCI_CLASS_FROM_DATABASE=Multimedia controller -E: ID_PCI_SUBCLASS_FROM_DATABASE=Audio device -E: ID_VENDOR_FROM_DATABASE=Intel Corporation -E: MODALIAS=pci:v00008086d0000160Csv00008086sd00002057bc04sc03i00 -E: PCI_CLASS=40300 -E: PCI_ID=8086:160C -E: PCI_SLOT_NAME=0000:00:03.0 -E: PCI_SUBSYS_ID=8086:2057 -E: SUBSYSTEM=pci -A: ari_enabled=0 -A: broken_parity_status=0 -A: class=0x040300 -H: config=86800C16060410000900030410000000044013F700000000000000000000000000000000000000000000000086805720000000005000000000000000FF010000 -A: consistent_dma_mask_bits=64 -A: current_link_speed=Unknown speed -A: current_link_width=0 -A: d3cold_allowed=1 -A: device=0x160c -A: dma_mask_bits=64 -L: driver=../../../bus/pci/drivers/snd_hda_intel -A: driver_override=(null) -A: enable=1 -A: irq=50 -A: local_cpulist=0-3 -A: local_cpus=f -A: max_link_speed=Unknown speed -A: max_link_width=0 -A: modalias=pci:v00008086d0000160Csv00008086sd00002057bc04sc03i00 -A: msi_bus=1 -A: msi_irqs/50=msi -A: numa_node=-1 -A: power/control=on -A: power/runtime_active_time=16247383 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: resource=0x00000000f7134000 0x00000000f7137fff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000 -A: revision=0x09 -A: subsystem_device=0x2057 -A: subsystem_vendor=0x8086 -A: vendor=0x8086 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input12/event11 -N: input/event11 -E: DEVNAME=/dev/input/event11 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: LIBINPUT_DEVICE_GROUP=0/0/0:ALSA -E: MAJOR=13 -E: MINOR=75 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:75 -L: device=../../input12 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input12 -E: EV=21 -E: ID_FOR_SEAT=input-pci-0000_00_03_0 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: MODALIAS=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -E: NAME="HDA Intel HDMI HDMI/DP,pcm=9" -E: PHYS="ALSA" -E: PRODUCT=0/0/0/0 -E: PROP=0 -E: SUBSYSTEM=input -E: SW=140 -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=21 -A: capabilities/ff=0 -A: capabilities/key=0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=140 -L: device=../../card0 -A: id/bustype=0000 -A: id/product=0000 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -A: name=HDA Intel HDMI HDMI/DP,pcm=9 -A: phys=ALSA -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input13/event12 -N: input/event12 -E: DEVNAME=/dev/input/event12 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: LIBINPUT_DEVICE_GROUP=0/0/0:ALSA -E: MAJOR=13 -E: MINOR=76 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:76 -L: device=../../input13 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input13 -E: EV=21 -E: ID_FOR_SEAT=input-pci-0000_00_03_0 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: MODALIAS=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -E: NAME="HDA Intel HDMI HDMI/DP,pcm=10" -E: PHYS="ALSA" -E: PRODUCT=0/0/0/0 -E: PROP=0 -E: SUBSYSTEM=input -E: SW=140 -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=21 -A: capabilities/ff=0 -A: capabilities/key=0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=140 -L: device=../../card0 -A: id/bustype=0000 -A: id/product=0000 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -A: name=HDA Intel HDMI HDMI/DP,pcm=10 -A: phys=ALSA -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:1b.0/sound/card1/input14/event13 -N: input/event13 -E: DEVNAME=/dev/input/event13 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:1b.0 -E: ID_PATH_TAG=pci-0000_00_1b_0 -E: LIBINPUT_DEVICE_GROUP=0/0/0:ALSA -E: MAJOR=13 -E: MINOR=77 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:77 -L: device=../../input14 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:1b.0/sound/card1/input14 -E: EV=21 -E: ID_FOR_SEAT=input-pci-0000_00_1b_0 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:1b.0 -E: ID_PATH_TAG=pci-0000_00_1b_0 -E: MODALIAS=input:b0000v0000p0000e0000-e0,5,kramlsfw4, -E: NAME="HDA Intel PCH Mic" -E: PHYS="ALSA" -E: PRODUCT=0/0/0/0 -E: PROP=0 -E: SUBSYSTEM=input -E: SW=10 -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=21 -A: capabilities/ff=0 -A: capabilities/key=0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=10 -L: device=../../card1 -A: id/bustype=0000 -A: id/product=0000 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0000v0000p0000e0000-e0,5,kramlsfw4, -A: name=HDA Intel PCH Mic -A: phys=ALSA -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:1b.0/sound/card1 -E: ID_BUS=pci -E: ID_FOR_SEAT=sound-pci-0000_00_1b_0 -E: ID_MODEL_FROM_DATABASE=Wildcat Point-LP High Definition Audio Controller -E: ID_MODEL_ID=0x9ca0 -E: ID_PATH=pci-0000:00:1b.0 -E: ID_PATH_TAG=pci-0000_00_1b_0 -E: ID_PCI_CLASS_FROM_DATABASE=Multimedia controller -E: ID_PCI_SUBCLASS_FROM_DATABASE=Audio device -E: ID_VENDOR_FROM_DATABASE=Intel Corporation -E: ID_VENDOR_ID=0x8086 -E: SOUND_FORM_FACTOR=internal -E: SOUND_INITIALIZED=1 -E: SUBSYSTEM=sound -E: SYSTEMD_WANTS=sound.target -E: TAGS=:systemd:seat: -L: device=../../../0000:00:1b.0 -A: id=PCH -A: number=1 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:1b.0 -E: DRIVER=snd_hda_intel -E: ID_MODEL_FROM_DATABASE=Wildcat Point-LP High Definition Audio Controller -E: ID_PCI_CLASS_FROM_DATABASE=Multimedia controller -E: ID_PCI_SUBCLASS_FROM_DATABASE=Audio device -E: ID_VENDOR_FROM_DATABASE=Intel Corporation -E: MODALIAS=pci:v00008086d00009CA0sv00008086sd00002057bc04sc03i00 -E: PCI_CLASS=40300 -E: PCI_ID=8086:9CA0 -E: PCI_SLOT_NAME=0000:00:1b.0 -E: PCI_SUBSYS_ID=8086:2057 -E: SUBSYSTEM=pci -A: ari_enabled=0 -A: broken_parity_status=0 -A: class=0x040300 -H: config=8680A09C060410000300030410200000040013F700000000000000000000000000000000000000000000000086805720000000005000000000000000FF010000 -A: consistent_dma_mask_bits=64 -A: d3cold_allowed=1 -A: device=0x9ca0 -A: dma_mask_bits=64 -L: driver=../../../bus/pci/drivers/snd_hda_intel -A: driver_override=(null) -A: enable=1 -A: index=1 -A: irq=49 -A: label= CIR Device -A: local_cpulist=0-3 -A: local_cpus=f -A: modalias=pci:v00008086d00009CA0sv00008086sd00002057bc04sc03i00 -A: msi_bus=1 -A: msi_irqs/49=msi -A: numa_node=-1 -A: power/control=on -A: power/runtime_active_time=16247428 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=disabled -A: power/wakeup_abort_count= -A: power/wakeup_active= -A: power/wakeup_active_count= -A: power/wakeup_count= -A: power/wakeup_expire_count= -A: power/wakeup_last_time_ms= -A: power/wakeup_max_time_ms= -A: power/wakeup_total_time_ms= -A: resource=0x00000000f7130000 0x00000000f7133fff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000 -A: revision=0x03 -A: subsystem_device=0x2057 -A: subsystem_vendor=0x8086 -A: vendor=0x8086 - -P: /devices/pci0000:00/0000:00:1b.0/sound/card1/input15/event14 -N: input/event14 -E: DEVNAME=/dev/input/event14 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:1b.0 -E: ID_PATH_TAG=pci-0000_00_1b_0 -E: LIBINPUT_DEVICE_GROUP=0/0/0:ALSA -E: MAJOR=13 -E: MINOR=78 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:78 -L: device=../../input15 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:1b.0/sound/card1/input15 -E: EV=21 -E: ID_FOR_SEAT=input-pci-0000_00_1b_0 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:1b.0 -E: ID_PATH_TAG=pci-0000_00_1b_0 -E: MODALIAS=input:b0000v0000p0000e0000-e0,5,kramlsfw2, -E: NAME="HDA Intel PCH Headphone" -E: PHYS="ALSA" -E: PRODUCT=0/0/0/0 -E: PROP=0 -E: SUBSYSTEM=input -E: SW=4 -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=21 -A: capabilities/ff=0 -A: capabilities/key=0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=4 -L: device=../../card1 -A: id/bustype=0000 -A: id/product=0000 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0000v0000p0000e0000-e0,5,kramlsfw2, -A: name=HDA Intel PCH Headphone -A: phys=ALSA -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input2/event2 -N: input/event2 -E: DEVNAME=/dev/input/event2 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-LNXPWRBN:00 -E: ID_PATH_TAG=acpi-LNXPWRBN_00 -E: LIBINPUT_DEVICE_GROUP=19/0/1:LNXPWRBN/button -E: MAJOR=13 -E: MINOR=66 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:66 -L: device=../../input2 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input2 -E: EV=3 -E: ID_FOR_SEAT=input-acpi-LNXPWRBN_00 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-LNXPWRBN:00 -E: ID_PATH_TAG=acpi-LNXPWRBN_00 -E: KEY=10000000000000 0 -E: MODALIAS=input:b0019v0000p0001e0000-e0,1,k74,ramlsfw -E: NAME="Power Button" -E: PHYS="LNXPWRBN/button/input0" -E: PRODUCT=19/0/1/0 -E: PROP=0 -E: SUBSYSTEM=input -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=3 -A: capabilities/ff=0 -A: capabilities/key=10000000000000 0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../LNXPWRBN:00 -A: id/bustype=0019 -A: id/product=0001 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0019v0000p0001e0000-e0,1,k74,ramlsfw -A: name=Power Button -A: phys=LNXPWRBN/button/input0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/LNXSYSTM:00/LNXPWRBN:00 -E: DRIVER=button -E: ID_VENDOR_FROM_DATABASE=The Linux Foundation -E: MODALIAS=acpi:LNXPWRBN: -E: SUBSYSTEM=acpi -L: driver=../../../bus/acpi/drivers/button -A: hid=LNXPWRBN -A: modalias=acpi:LNXPWRBN: -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: power/wakeup=enabled -A: power/wakeup_abort_count=0 -A: power/wakeup_active=0 -A: power/wakeup_active_count=0 -A: power/wakeup_count=0 -A: power/wakeup_expire_count=0 -A: power/wakeup_last_time_ms=46 -A: power/wakeup_max_time_ms=0 -A: power/wakeup_total_time_ms=0 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:00/input/input3/event3 -N: input/event3 -E: DEVNAME=/dev/input/event3 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-LNXVIDEO:00 -E: ID_PATH_TAG=acpi-LNXVIDEO_00 -E: LIBINPUT_DEVICE_GROUP=19/0/6:LNXVIDEO/video -E: MAJOR=13 -E: MINOR=67 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:67 -L: device=../../input3 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:00/input/input3 -E: EV=3 -E: ID_FOR_SEAT=input-acpi-LNXVIDEO_00 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_PATH=acpi-LNXVIDEO:00 -E: ID_PATH_TAG=acpi-LNXVIDEO_00 -E: KEY=3e000b00000000 0 0 0 -E: MODALIAS=input:b0019v0000p0006e0000-e0,1,kE0,E1,E3,F1,F2,F3,F4,F5,ramlsfw -E: NAME="Video Bus" -E: PHYS="LNXVIDEO/video/input0" -E: PRODUCT=19/0/6/0 -E: PROP=0 -E: SUBSYSTEM=input -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=3 -A: capabilities/ff=0 -A: capabilities/key=3e000b00000000 0 0 0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../LNXVIDEO:00 -A: id/bustype=0019 -A: id/product=0006 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0019v0000p0006e0000-e0,1,kE0,E1,E3,F1,F2,F3,F4,F5,ramlsfw -A: name=Video Bus -A: phys=LNXVIDEO/video/input0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/LNXVIDEO:00 -E: DRIVER=video -E: ID_VENDOR_FROM_DATABASE=The Linux Foundation -E: MODALIAS=acpi:LNXVIDEO: -E: SUBSYSTEM=acpi -A: adr=0x00020000 -L: driver=../../../../../bus/acpi/drivers/video -A: hid=LNXVIDEO -A: modalias=acpi:LNXVIDEO: -A: path=\\_SB_.PCI0.GFX0 -L: physical_node=../../../../pci0000:00/0000:00:02.0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00 -E: ID_VENDOR_FROM_DATABASE=The Linux Foundation -E: MODALIAS=acpi:PNP0A08:PNP0A03: -E: SUBSYSTEM=acpi -A: adr=0x00000000 -A: hid=PNP0A08 -A: modalias=acpi:PNP0A08:PNP0A03: -A: path=\\_SB_.PCI0 -L: physical_node=../../../pci0000:00 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: uid=0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.2/2-2.2:1.0/0003:093A:2521.0001/input/input4/event4 -N: input/event4 -S: input/by-id/usb-093a_USB_OPTICAL_MOUSE-event-mouse -S: input/by-path/pci-0000:00:14.0-usb-0:2.2:1.0-event-mouse -E: DEVLINKS=/dev/input/by-path/pci-0000:00:14.0-usb-0:2.2:1.0-event-mouse /dev/input/by-id/usb-093a_USB_OPTICAL_MOUSE-event-mouse -E: DEVNAME=/dev/input/event4 -E: ID_BUS=usb -E: ID_INPUT=1 -E: ID_INPUT_MOUSE=1 -E: ID_MODEL=USB_OPTICAL_MOUSE -E: ID_MODEL_ENC=USB\x20OPTICAL\x20MOUSE -E: ID_MODEL_ID=2521 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.2:1.0 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_2_1_0 -E: ID_REVISION=0100 -E: ID_SERIAL=093a_USB_OPTICAL_MOUSE -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:030102: -E: ID_USB_INTERFACE_NUM=00 -E: ID_VENDOR=093a -E: ID_VENDOR_ENC=093a -E: ID_VENDOR_ID=093a -E: LIBINPUT_DEVICE_GROUP=3/93a/2521:usb-0000:00:14.0-2 -E: MAJOR=13 -E: MINOR=68 -E: MOUSE_DPI=*1000@125 1600@125 600@125 -E: SUBSYSTEM=input -A: dev=13:68 -L: device=../../input4 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.2/2-2.2:1.0/0003:093A:2521.0001/input/input4 -E: EV=17 -E: ID_BUS=usb -E: ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_2_2_1_0 -E: ID_INPUT=1 -E: ID_INPUT_MOUSE=1 -E: ID_MODEL=USB_OPTICAL_MOUSE -E: ID_MODEL_ENC=USB\x20OPTICAL\x20MOUSE -E: ID_MODEL_ID=2521 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.2:1.0 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_2_1_0 -E: ID_REVISION=0100 -E: ID_SERIAL=093a_USB_OPTICAL_MOUSE -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:030102: -E: ID_USB_INTERFACE_NUM=00 -E: ID_VENDOR=093a -E: ID_VENDOR_ENC=093a -E: ID_VENDOR_ID=093a -E: KEY=1f0000 0 0 0 0 -E: MODALIAS=input:b0003v093Ap2521e0111-e0,1,2,4,k110,111,112,113,114,r0,1,6,8,am4,lsfw -E: MSC=10 -E: NAME="USB OPTICAL MOUSE" -E: PHYS="usb-0000:00:14.0-2.2/input0" -E: PRODUCT=3/93a/2521/111 -E: PROP=0 -E: REL=143 -E: SUBSYSTEM=input -E: TAGS=:seat: -E: UNIQ="" -A: capabilities/abs=0 -A: capabilities/ev=17 -A: capabilities/ff=0 -A: capabilities/key=1f0000 0 0 0 0 -A: capabilities/led=0 -A: capabilities/msc=10 -A: capabilities/rel=143 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../0003:093A:2521.0001 -A: id/bustype=0003 -A: id/product=2521 -A: id/vendor=093a -A: id/version=0111 -A: modalias=input:b0003v093Ap2521e0111-e0,1,2,4,k110,111,112,113,114,r0,1,6,8,am4,lsfw -A: name=USB OPTICAL MOUSE -A: phys=usb-0000:00:14.0-2.2/input0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.2/2-2.2:1.0/0003:093A:2521.0001 -E: DRIVER=hid-generic -E: HID_ID=0003:0000093A:00002521 -E: HID_NAME=USB OPTICAL MOUSE -E: HID_PHYS=usb-0000:00:14.0-2.2/input0 -E: HID_UNIQ= -E: MODALIAS=hid:b0003g0001v0000093Ap00002521 -E: SUBSYSTEM=hid -A: country=00 -L: driver=../../../../../../../../bus/hid/drivers/hid-generic -A: modalias=hid:b0003g0001v0000093Ap00002521 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -H: report_descriptor=05010902A1010509190129051500250195057501810295017503810305010901A1000930093116018026FF7F751095028106C009381581257F750895018106050C0A38021581257F950175088106C0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.2/2-2.2:1.0 -E: DEVTYPE=usb_interface -E: DRIVER=usbhid -E: ID_MODEL_FROM_DATABASE=Optical Mouse -E: ID_VENDOR_FROM_DATABASE=Pixart Imaging, Inc. -E: INTERFACE=3/1/2 -E: MODALIAS=usb:v093Ap2521d0100dc00dsc00dp00ic03isc01ip02in00 -E: PRODUCT=93a/2521/100 -E: SUBSYSTEM=usb -E: TYPE=0/0/0 -A: authorized=1 -A: bAlternateSetting= 0 -A: bInterfaceClass=03 -A: bInterfaceNumber=00 -A: bInterfaceProtocol=02 -A: bInterfaceSubClass=01 -A: bNumEndpoints=01 -L: driver=../../../../../../../bus/usb/drivers/usbhid -A: modalias=usb:v093Ap2521d0100dc00dsc00dp00ic03isc01ip02in00 -A: supports_autosuspend=1 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.2 -N: bus/usb/002/005=12011001000000083A09212500010002000109022200010104A032090400000103010200092111010001224F000705810307000A -E: BUSNUM=002 -E: DEVNAME=/dev/bus/usb/002/005 -E: DEVNUM=005 -E: DEVTYPE=usb_device -E: DRIVER=usb -E: ID_BUS=usb -E: ID_MODEL=USB_OPTICAL_MOUSE -E: ID_MODEL_ENC=USB\x20OPTICAL\x20MOUSE -E: ID_MODEL_FROM_DATABASE=Optical Mouse -E: ID_MODEL_ID=2521 -E: ID_REVISION=0100 -E: ID_SERIAL=093a_USB_OPTICAL_MOUSE -E: ID_USB_INTERFACES=:030102: -E: ID_VENDOR=093a -E: ID_VENDOR_ENC=093a -E: ID_VENDOR_FROM_DATABASE=Pixart Imaging, Inc. -E: ID_VENDOR_ID=093a -E: MAJOR=189 -E: MINOR=132 -E: PRODUCT=93a/2521/100 -E: SUBSYSTEM=usb -E: TYPE=0/0/0 -A: authorized=1 -A: avoid_reset_quirk=0 -A: bConfigurationValue=1 -A: bDeviceClass=00 -A: bDeviceProtocol=00 -A: bDeviceSubClass=00 -A: bMaxPacketSize0=8 -A: bMaxPower=100mA -A: bNumConfigurations=1 -A: bNumInterfaces= 1 -A: bcdDevice=0100 -A: bmAttributes=a0 -A: busnum=2 -A: configuration=HID-compliant MOUSE -H: descriptors=12011001000000083A09212500010002000109022200010104A032090400000103010200092111010001224F000705810307000A -A: dev=189:132 -A: devnum=5 -A: devpath=2.2 -L: driver=../../../../../../bus/usb/drivers/usb -A: idProduct=2521 -A: idVendor=093a -A: ltm_capable=no -A: maxchild=0 -L: port=../2-2:1.0/2-2-port2 -A: power/active_duration=16246228 -A: power/autosuspend=2 -A: power/autosuspend_delay_ms=2000 -A: power/connected_duration=16246228 -A: power/control=on -A: power/level=on -A: power/persist=1 -A: power/runtime_active_time=16246082 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=disabled -A: power/wakeup_abort_count= -A: power/wakeup_active= -A: power/wakeup_active_count= -A: power/wakeup_count= -A: power/wakeup_expire_count= -A: power/wakeup_last_time_ms= -A: power/wakeup_max_time_ms= -A: power/wakeup_total_time_ms= -A: product=USB OPTICAL MOUSE -A: quirks=0x0 -A: removable=unknown -A: speed=1.5 -A: urbnum=179715 -A: version= 1.10 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2 -N: bus/usb/002/002=1201000209000140E305080637850001000109021900010100E0320904000001090000000705810301000C -E: BUSNUM=002 -E: DEVNAME=/dev/bus/usb/002/002 -E: DEVNUM=002 -E: DEVTYPE=usb_device -E: DRIVER=usb -E: ID_BUS=usb -E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_2 -E: ID_MODEL=USB2.0_Hub -E: ID_MODEL_ENC=USB2.0\x20Hub -E: ID_MODEL_FROM_DATABASE=Hub -E: ID_MODEL_ID=0608 -E: ID_PATH=pci-0000:00:14.0-usb-0:2 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2 -E: ID_REVISION=8537 -E: ID_SERIAL=05e3_USB2.0_Hub -E: ID_USB_INTERFACES=:090000: -E: ID_VENDOR=05e3 -E: ID_VENDOR_ENC=05e3 -E: ID_VENDOR_FROM_DATABASE=Genesys Logic, Inc. -E: ID_VENDOR_ID=05e3 -E: MAJOR=189 -E: MINOR=129 -E: PRODUCT=5e3/608/8537 -E: SUBSYSTEM=usb -E: TAGS=:seat: -E: TYPE=9/0/1 -A: authorized=1 -A: avoid_reset_quirk=0 -A: bConfigurationValue=1 -A: bDeviceClass=09 -A: bDeviceProtocol=01 -A: bDeviceSubClass=00 -A: bMaxPacketSize0=64 -A: bMaxPower=100mA -A: bNumConfigurations=1 -A: bNumInterfaces= 1 -A: bcdDevice=8537 -A: bmAttributes=e0 -A: busnum=2 -A: configuration= -H: descriptors=1201000209000140E305080637850001000109021900010100E0320904000001090000000705810301000C -A: dev=189:129 -A: devnum=2 -A: devpath=2 -L: driver=../../../../../bus/usb/drivers/usb -A: idProduct=0608 -A: idVendor=05e3 -A: ltm_capable=no -A: maxchild=4 -L: port=../2-0:1.0/usb2-port2 -A: power/active_duration=16246866 -A: power/autosuspend=0 -A: power/autosuspend_delay_ms=0 -A: power/connected_duration=16246866 -A: power/control=auto -A: power/level=auto -A: power/runtime_active_time=16246626 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=disabled -A: power/wakeup_abort_count= -A: power/wakeup_active= -A: power/wakeup_active_count= -A: power/wakeup_count= -A: power/wakeup_expire_count= -A: power/wakeup_last_time_ms= -A: power/wakeup_max_time_ms= -A: power/wakeup_total_time_ms= -A: product=USB2.0 Hub -A: quirks=0x0 -A: removable=removable -A: speed=480 -A: urbnum=46 -A: version= 2.00 - -P: /devices/pci0000:00/0000:00:14.0/usb2 -N: bus/usb/002/001=12010002090001406B1D020016040302010109021900010100E0000904000001090000000705810304000C -E: BUSNUM=002 -E: DEVNAME=/dev/bus/usb/002/001 -E: DEVNUM=001 -E: DEVTYPE=usb_device -E: DRIVER=usb -E: ID_BUS=usb -E: ID_FOR_SEAT=usb-pci-0000_00_14_0 -E: ID_MODEL=xHCI_Host_Controller -E: ID_MODEL_ENC=xHCI\x20Host\x20Controller -E: ID_MODEL_FROM_DATABASE=2.0 root hub -E: ID_MODEL_ID=0002 -E: ID_PATH=pci-0000:00:14.0 -E: ID_PATH_TAG=pci-0000_00_14_0 -E: ID_REVISION=0416 -E: ID_SERIAL=Linux_4.16.3-300.fc28.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 -E: ID_SERIAL_SHORT=0000:00:14.0 -E: ID_USB_INTERFACES=:090000: -E: ID_VENDOR=Linux_4.16.3-300.fc28.x86_64_xhci-hcd -E: ID_VENDOR_ENC=Linux\x204.16.3-300.fc28.x86_64\x20xhci-hcd -E: ID_VENDOR_FROM_DATABASE=Linux Foundation -E: ID_VENDOR_ID=1d6b -E: MAJOR=189 -E: MINOR=128 -E: PRODUCT=1d6b/2/416 -E: SUBSYSTEM=usb -E: TAGS=:seat: -E: TYPE=9/0/1 -A: authorized=1 -A: authorized_default=1 -A: avoid_reset_quirk=0 -A: bConfigurationValue=1 -A: bDeviceClass=09 -A: bDeviceProtocol=01 -A: bDeviceSubClass=00 -A: bMaxPacketSize0=64 -A: bMaxPower=0mA -A: bNumConfigurations=1 -A: bNumInterfaces= 1 -A: bcdDevice=0416 -A: bmAttributes=e0 -A: busnum=2 -A: configuration= -H: descriptors=12010002090001406B1D020016040302010109021900010100E0000904000001090000000705810304000C -A: dev=189:128 -A: devnum=1 -A: devpath=0 -L: driver=../../../../bus/usb/drivers/usb -A: idProduct=0002 -A: idVendor=1d6b -A: interface_authorized_default=1 -A: ltm_capable=no -A: manufacturer=Linux 4.16.3-300.fc28.x86_64 xhci-hcd -A: maxchild=11 -A: power/active_duration=16247082 -A: power/autosuspend=0 -A: power/autosuspend_delay_ms=0 -A: power/connected_duration=16247083 -A: power/control=auto -A: power/level=auto -A: power/runtime_active_time=16247082 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=disabled -A: power/wakeup_abort_count= -A: power/wakeup_active= -A: power/wakeup_active_count= -A: power/wakeup_count= -A: power/wakeup_expire_count= -A: power/wakeup_last_time_ms= -A: power/wakeup_max_time_ms= -A: power/wakeup_total_time_ms= -A: product=xHCI Host Controller -A: quirks=0x0 -A: removable=unknown -A: serial=0000:00:14.0 -A: speed=480 -A: urbnum=79 -A: version= 2.00 - -P: /devices/pci0000:00/0000:00:14.0 -E: DRIVER=xhci_hcd -E: ID_MODEL_FROM_DATABASE=Wildcat Point-LP USB xHCI Controller -E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller -E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI -E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller -E: ID_VENDOR_FROM_DATABASE=Intel Corporation -E: MODALIAS=pci:v00008086d00009CB1sv00008086sd00002057bc0Csc03i30 -E: PCI_CLASS=C0330 -E: PCI_ID=8086:9CB1 -E: PCI_SLOT_NAME=0000:00:14.0 -E: PCI_SUBSYS_ID=8086:2057 -E: SUBSYSTEM=pci -A: ari_enabled=0 -A: broken_parity_status=0 -A: class=0x0c0330 -H: config=8680B19C060490020330030C00000000040012F700000000000000000000000000000000000000000000000086805720000000007000000000000000FF010000 -A: consistent_dma_mask_bits=64 -A: d3cold_allowed=1 -A: dbc=disabled -A: device=0x9cb1 -A: dma_mask_bits=64 -L: driver=../../../bus/pci/drivers/xhci_hcd -A: driver_override=(null) -A: enable=1 -A: irq=45 -A: local_cpulist=0-3 -A: local_cpus=f -A: modalias=pci:v00008086d00009CB1sv00008086sd00002057bc0Csc03i30 -A: msi_bus=1 -A: msi_irqs/45=msi -A: numa_node=-1 -A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 13 13 2112 13\nxHCI ring segments 42 44 4096 44\nbuffer-2048 3 6 2048 3\nbuffer-512 12 16 512 2\nbuffer-128 15 32 128 1\nbuffer-32 0 0 32 0 -A: power/control=on -A: power/runtime_active_time=16247530 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=enabled -A: power/wakeup_abort_count=0 -A: power/wakeup_active=0 -A: power/wakeup_active_count=0 -A: power/wakeup_count=0 -A: power/wakeup_expire_count=0 -A: power/wakeup_last_time_ms=504 -A: power/wakeup_max_time_ms=0 -A: power/wakeup_total_time_ms=0 -A: resource=0x00000000f7120000 0x00000000f712ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000 -A: revision=0x03 -A: subsystem_device=0x2057 -A: subsystem_vendor=0x8086 -A: vendor=0x8086 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.0/0003:04D9:0112.0002/input/input5/event5 -N: input/event5 -S: input/by-id/usb-04d9_USB-HID_Keyboard-event-kbd -S: input/by-path/pci-0000:00:14.0-usb-0:2.3:1.0-event-kbd -E: DEVLINKS=/dev/input/by-id/usb-04d9_USB-HID_Keyboard-event-kbd /dev/input/by-path/pci-0000:00:14.0-usb-0:2.3:1.0-event-kbd -E: DEVNAME=/dev/input/event5 -E: ID_BUS=usb -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_INPUT_KEYBOARD=1 -E: ID_MODEL=USB-HID_Keyboard -E: ID_MODEL_ENC=USB-HID\x20Keyboard -E: ID_MODEL_ID=0112 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.3:1.0 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_3_1_0 -E: ID_REVISION=0107 -E: ID_SERIAL=04d9_USB-HID_Keyboard -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:030101:030000: -E: ID_USB_INTERFACE_NUM=00 -E: ID_VENDOR=04d9 -E: ID_VENDOR_ENC=04d9 -E: ID_VENDOR_ID=04d9 -E: LIBINPUT_DEVICE_GROUP=3/4d9/112:usb-0000:00:14.0-2 -E: MAJOR=13 -E: MINOR=69 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:69 -L: device=../../input5 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.0/0003:04D9:0112.0002/input/input5 -E: EV=120013 -E: ID_BUS=usb -E: ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_2_3_1_0 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_INPUT_KEYBOARD=1 -E: ID_MODEL=USB-HID_Keyboard -E: ID_MODEL_ENC=USB-HID\x20Keyboard -E: ID_MODEL_ID=0112 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.3:1.0 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_3_1_0 -E: ID_REVISION=0107 -E: ID_SERIAL=04d9_USB-HID_Keyboard -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:030101:030000: -E: ID_USB_INTERFACE_NUM=00 -E: ID_VENDOR=04d9 -E: ID_VENDOR_ENC=04d9 -E: ID_VENDOR_ID=04d9 -E: KEY=1000000000007 ff800000000007ff febeffdfffefffff fffffffffffffffe -E: LED=7 -E: MODALIAS=input:b0003v04D9p0112e0111-e0,1,4,11,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,F0,ram4,l0,1,2,sfw -E: MSC=10 -E: NAME="USB-HID Keyboard" -E: PHYS="usb-0000:00:14.0-2.3/input0" -E: PRODUCT=3/4d9/112/111 -E: PROP=0 -E: SUBSYSTEM=input -E: TAGS=:seat: -E: UNIQ="" -A: capabilities/abs=0 -A: capabilities/ev=120013 -A: capabilities/ff=0 -A: capabilities/key=1000000000007 ff800000000007ff febeffdfffefffff fffffffffffffffe -A: capabilities/led=7 -A: capabilities/msc=10 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../0003:04D9:0112.0002 -A: id/bustype=0003 -A: id/product=0112 -A: id/vendor=04d9 -A: id/version=0111 -A: modalias=input:b0003v04D9p0112e0111-e0,1,4,11,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,B7,B8,B9,BA,BB,BC,BD,BE,BF,C0,C1,C2,F0,ram4,l0,1,2,sfw -A: name=USB-HID Keyboard -A: phys=usb-0000:00:14.0-2.3/input0 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.0/0003:04D9:0112.0002 -E: DRIVER=hid-generic -E: HID_ID=0003:000004D9:00000112 -E: HID_NAME=USB-HID Keyboard -E: HID_PHYS=usb-0000:00:14.0-2.3/input0 -E: HID_UNIQ= -E: MODALIAS=hid:b0003g0001v000004D9p00000112 -E: SUBSYSTEM=hid -A: country=00 -L: driver=../../../../../../../../bus/hid/drivers/hid-generic -A: modalias=hid:b0003g0001v000004D9p00000112 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -H: report_descriptor=05010906A101050719E029E71500250175019508810295017508810395037501050819012903910295017505910395067508150026A4000507190029A48100C0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.0 -E: DEVTYPE=usb_interface -E: DRIVER=usbhid -E: ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. -E: INTERFACE=3/1/1 -E: MODALIAS=usb:v04D9p0112d0107dc00dsc00dp00ic03isc01ip01in00 -E: PRODUCT=4d9/112/107 -E: SUBSYSTEM=usb -E: TYPE=0/0/0 -A: authorized=1 -A: bAlternateSetting= 0 -A: bInterfaceClass=03 -A: bInterfaceNumber=00 -A: bInterfaceProtocol=01 -A: bInterfaceSubClass=01 -A: bNumEndpoints=01 -L: driver=../../../../../../../bus/usb/drivers/usbhid -A: modalias=usb:v04D9p0112d0107dc00dsc00dp00ic03isc01ip01in00 -A: supports_autosuspend=1 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3 -N: bus/usb/002/006=1201100100000040D904120107010002000109025B00030100A03209040000010301010009211101000122400007058103080001090401000103000000092111010001226500070582032000010904020002030000000921110100012222000705830340000107050403400001 -E: BUSNUM=002 -E: DEVNAME=/dev/bus/usb/002/006 -E: DEVNUM=006 -E: DEVTYPE=usb_device -E: DRIVER=usb -E: ID_BUS=usb -E: ID_MODEL=USB-HID_Keyboard -E: ID_MODEL_ENC=USB-HID\x20Keyboard -E: ID_MODEL_ID=0112 -E: ID_REVISION=0107 -E: ID_SERIAL=04d9_USB-HID_Keyboard -E: ID_USB_INTERFACES=:030101:030000: -E: ID_VENDOR=04d9 -E: ID_VENDOR_ENC=04d9 -E: ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. -E: ID_VENDOR_ID=04d9 -E: MAJOR=189 -E: MINOR=133 -E: PRODUCT=4d9/112/107 -E: SUBSYSTEM=usb -E: TYPE=0/0/0 -A: authorized=1 -A: avoid_reset_quirk=0 -A: bConfigurationValue=1 -A: bDeviceClass=00 -A: bDeviceProtocol=00 -A: bDeviceSubClass=00 -A: bMaxPacketSize0=64 -A: bMaxPower=100mA -A: bNumConfigurations=1 -A: bNumInterfaces= 3 -A: bcdDevice=0107 -A: bmAttributes=a0 -A: busnum=2 -A: configuration= -H: descriptors=1201100100000040D904120107010002000109025B00030100A03209040000010301010009211101000122400007058103080001090401000103000000092111010001226500070582032000010904020002030000000921110100012222000705830340000107050403400001 -A: dev=189:133 -A: devnum=6 -A: devpath=2.3 -L: driver=../../../../../../bus/usb/drivers/usb -A: idProduct=0112 -A: idVendor=04d9 -A: ltm_capable=no -A: maxchild=0 -L: port=../2-2:1.0/2-2-port3 -A: power/active_duration=16246123 -A: power/autosuspend=2 -A: power/autosuspend_delay_ms=2000 -A: power/connected_duration=16246123 -A: power/control=on -A: power/level=on -A: power/persist=1 -A: power/runtime_active_time=16245983 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=enabled -A: power/wakeup_abort_count=0 -A: power/wakeup_active=0 -A: power/wakeup_active_count=0 -A: power/wakeup_count=0 -A: power/wakeup_expire_count=0 -A: power/wakeup_last_time_ms=1616 -A: power/wakeup_max_time_ms=0 -A: power/wakeup_total_time_ms=0 -A: product=USB-HID Keyboard -A: quirks=0x0 -A: removable=unknown -A: speed=12 -A: urbnum=31507 -A: version= 1.10 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.1/0003:04D9:0112.0003/input/input6/event6 -N: input/event6 -S: input/by-id/usb-04d9_USB-HID_Keyboard-event-if01 -S: input/by-path/pci-0000:00:14.0-usb-0:2.3:1.1-event -E: DEVLINKS=/dev/input/by-id/usb-04d9_USB-HID_Keyboard-event-if01 /dev/input/by-path/pci-0000:00:14.0-usb-0:2.3:1.1-event -E: DEVNAME=/dev/input/event6 -E: ID_BUS=usb -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_MODEL=USB-HID_Keyboard -E: ID_MODEL_ENC=USB-HID\x20Keyboard -E: ID_MODEL_ID=0112 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.3:1.1 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_3_1_1 -E: ID_REVISION=0107 -E: ID_SERIAL=04d9_USB-HID_Keyboard -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:030101:030000: -E: ID_USB_INTERFACE_NUM=01 -E: ID_VENDOR=04d9 -E: ID_VENDOR_ENC=04d9 -E: ID_VENDOR_ID=04d9 -E: LIBINPUT_DEVICE_GROUP=3/4d9/112:usb-0000:00:14.0-2 -E: MAJOR=13 -E: MINOR=70 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:70 -L: device=../../input6 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.1/0003:04D9:0112.0003/input/input6 -E: EV=13 -E: ID_BUS=usb -E: ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_2_3_1_1 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_MODEL=USB-HID_Keyboard -E: ID_MODEL_ENC=USB-HID\x20Keyboard -E: ID_MODEL_ID=0112 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.3:1.1 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_3_1_1 -E: ID_REVISION=0107 -E: ID_SERIAL=04d9_USB-HID_Keyboard -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:030101:030000: -E: ID_USB_INTERFACE_NUM=01 -E: ID_VENDOR=04d9 -E: ID_VENDOR_ENC=04d9 -E: ID_VENDOR_ID=04d9 -E: KEY=2000000 3878d801d001 1e000000000000 0 -E: MODALIAS=input:b0003v04D9p0112e0111-e0,1,4,k71,72,73,74,80,8C,8E,8F,90,9B,9C,9E,9F,A3,A4,A5,A6,AB,AC,AD,D9,ram4,lsfw -E: MSC=10 -E: NAME="USB-HID Keyboard" -E: PHYS="usb-0000:00:14.0-2.3/input1" -E: PRODUCT=3/4d9/112/111 -E: PROP=0 -E: SUBSYSTEM=input -E: TAGS=:seat: -E: UNIQ="" -A: capabilities/abs=0 -A: capabilities/ev=13 -A: capabilities/ff=0 -A: capabilities/key=2000000 3878d801d001 1e000000000000 0 -A: capabilities/led=0 -A: capabilities/msc=10 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../0003:04D9:0112.0003 -A: id/bustype=0003 -A: id/product=0112 -A: id/vendor=04d9 -A: id/version=0111 -A: modalias=input:b0003v04D9p0112e0111-e0,1,4,k71,72,73,74,80,8C,8E,8F,90,9B,9C,9E,9F,A3,A4,A5,A6,AB,AC,AD,D9,ram4,lsfw -A: name=USB-HID Keyboard -A: phys=usb-0000:00:14.0-2.3/input1 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.1/0003:04D9:0112.0003 -E: DRIVER=hid-generic -E: HID_ID=0003:000004D9:00000112 -E: HID_NAME=USB-HID Keyboard -E: HID_PHYS=usb-0000:00:14.0-2.3/input1 -E: HID_UNIQ= -E: MODALIAS=hid:b0003g0001v000004D9p00000112 -E: SUBSYSTEM=hid -A: country=00 -L: driver=../../../../../../../../bus/hid/drivers/hid-generic -A: modalias=hid:b0003g0001v000004D9p00000112 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -H: report_descriptor=05010980A10185011981298315002501950375018102950175058101C0050C0901A101850215002501951275010A83010A8A010A92010A940109CD09B709B609B509E209EA09E90A21020A23020A24020A25020A26020A27020A2A0281029501750E8101C0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.3/2-2.3:1.1 -E: DEVTYPE=usb_interface -E: DRIVER=usbhid -E: ID_VENDOR_FROM_DATABASE=Holtek Semiconductor, Inc. -E: INTERFACE=3/0/0 -E: MODALIAS=usb:v04D9p0112d0107dc00dsc00dp00ic03isc00ip00in01 -E: PRODUCT=4d9/112/107 -E: SUBSYSTEM=usb -E: TYPE=0/0/0 -A: authorized=1 -A: bAlternateSetting= 0 -A: bInterfaceClass=03 -A: bInterfaceNumber=01 -A: bInterfaceProtocol=00 -A: bInterfaceSubClass=00 -A: bNumEndpoints=01 -L: driver=../../../../../../../bus/usb/drivers/usbhid -A: modalias=usb:v04D9p0112d0107dc00dsc00dp00ic03isc00ip00in01 -A: supports_autosuspend=1 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1/2-2.1.1/2-2.1.1:1.3/0003:0D8C:0102.0005/input/input7/event7 -N: input/event7 -S: input/by-id/usb-0d8c_USB_Sound_Device-event-if03 -S: input/by-path/pci-0000:00:14.0-usb-0:2.1.1:1.3-event -E: DEVLINKS=/dev/input/by-id/usb-0d8c_USB_Sound_Device-event-if03 /dev/input/by-path/pci-0000:00:14.0-usb-0:2.1.1:1.3-event -E: DEVNAME=/dev/input/event7 -E: ID_BUS=usb -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_MODEL=USB_Sound_Device -E: ID_MODEL_ENC=USB\x20Sound\x20Device\x20\x20\x20\x20\x20\x20\x20\x20 -E: ID_MODEL_ID=0102 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.1.1:1.3 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1_1_1_3 -E: ID_REVISION=0010 -E: ID_SERIAL=0d8c_USB_Sound_Device -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:010100:010200:030000: -E: ID_USB_INTERFACE_NUM=03 -E: ID_VENDOR=0d8c -E: ID_VENDOR_ENC=0d8c -E: ID_VENDOR_ID=0d8c -E: LIBINPUT_DEVICE_GROUP=3/d8c/102:usb-0000:00:14.0-2.1 -E: MAJOR=13 -E: MINOR=71 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:71 -L: device=../../input7 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1/2-2.1.1/2-2.1.1:1.3/0003:0D8C:0102.0005/input/input7 -E: EV=13 -E: ID_BUS=usb -E: ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_2_1_1_1_3 -E: ID_INPUT=1 -E: ID_INPUT_KEY=1 -E: ID_MODEL=USB_Sound_Device -E: ID_MODEL_ENC=USB\x20Sound\x20Device\x20\x20\x20\x20\x20\x20\x20\x20 -E: ID_MODEL_ID=0102 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.1.1:1.3 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1_1_1_3 -E: ID_REVISION=0010 -E: ID_SERIAL=0d8c_USB_Sound_Device -E: ID_TYPE=hid -E: ID_USB_DRIVER=usbhid -E: ID_USB_INTERFACES=:010100:010200:030000: -E: ID_USB_INTERFACE_NUM=03 -E: ID_VENDOR=0d8c -E: ID_VENDOR_ENC=0d8c -E: ID_VENDOR_ID=0d8c -E: KEY=e000000000000 0 -E: MODALIAS=input:b0003v0D8Cp0102e0100-e0,1,4,k71,72,73,ram4,lsfw -E: MSC=10 -E: NAME="USB Sound Device " -E: PHYS="usb-0000:00:14.0-2.1.1/input3" -E: PRODUCT=3/d8c/102/100 -E: PROP=0 -E: SUBSYSTEM=input -E: TAGS=:seat: -E: UNIQ="" -A: capabilities/abs=0 -A: capabilities/ev=13 -A: capabilities/ff=0 -A: capabilities/key=e000000000000 0 -A: capabilities/led=0 -A: capabilities/msc=10 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=0 -L: device=../../../0003:0D8C:0102.0005 -A: id/bustype=0003 -A: id/product=0102 -A: id/vendor=0d8c -A: id/version=0100 -A: modalias=input:b0003v0D8Cp0102e0100-e0,1,4,k71,72,73,ram4,lsfw -A: name=USB Sound Device -A: phys=usb-0000:00:14.0-2.1.1/input3 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1/2-2.1.1/2-2.1.1:1.3/0003:0D8C:0102.0005 -E: DRIVER=hid-generic -E: HID_ID=0003:00000D8C:00000102 -E: HID_NAME=USB Sound Device -E: HID_PHYS=usb-0000:00:14.0-2.1.1/input3 -E: HID_UNIQ= -E: MODALIAS=hid:b0003g0001v00000D8Cp00000102 -E: SUBSYSTEM=hid -A: country=00 -L: driver=../../../../../../../../../bus/hid/drivers/hid-generic -A: modalias=hid:b0003g0001v00000D8Cp00000102 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -H: report_descriptor=050C0901A1011500250109E909EA75019502814209E20900810609009504810226FF000900750895028102090095049102C0 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1/2-2.1.1/2-2.1.1:1.3 -E: DEVTYPE=usb_interface -E: DRIVER=usbhid -E: ID_MODEL_FROM_DATABASE=CM106 Like Sound Device -E: ID_VENDOR_FROM_DATABASE=C-Media Electronics, Inc. -E: INTERFACE=3/0/0 -E: MODALIAS=usb:v0D8Cp0102d0010dc00dsc00dp00ic03isc00ip00in03 -E: PRODUCT=d8c/102/10 -E: SUBSYSTEM=usb -E: TYPE=0/0/0 -A: authorized=1 -A: bAlternateSetting= 0 -A: bInterfaceClass=03 -A: bInterfaceNumber=03 -A: bInterfaceProtocol=00 -A: bInterfaceSubClass=00 -A: bNumEndpoints=01 -L: driver=../../../../../../../../bus/usb/drivers/usbhid -A: modalias=usb:v0D8Cp0102d0010dc00dsc00dp00ic03isc00ip00in03 -A: supports_autosuspend=1 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1/2-2.1.1 -N: bus/usb/002/007=12011001000000088C0D02011000000200010902160204010080FA0904000000010100000A24010001C8000201020C240201010100083F0600000C24020401020002030000000A2406080401010202000A2406090401010202001924040C0301090B083F0600000000000000000000000000001024060D0C0101020202020202020200092403030103000D000D24041102090B0203000000000924030A01010007000A24050704080F1002000C24020603060002030000000A24060F0601010202000A24060B0601010202000C24020505060002030000000A2406021101010202000A240610050101000000090401000001020000090401010101020000072401010101000E2402010802100244AC0080BB0009050609100301000007250101000000090401020101020000072401010101000E2402010202100244AC0080BB0009050609C40001000007250101000000090401030101020000072401010101000E2402010402100244AC0080BB0009050609880101000007250101000000090401040101020000072401010101000E2402010602100244AC0080BB0009050609480201000007250101000000090401050101020000072401010101000B2402010202100180BB00090506098801010000072501010000000904020000010200000904020101010200000724010A0101000E2402010202100244AC0080BB0009058505C8000100000725010100000009040300010300000009210001000122320007058103030001 -E: BUSNUM=002 -E: DEVNAME=/dev/bus/usb/002/007 -E: DEVNUM=007 -E: DEVTYPE=usb_device -E: DRIVER=usb -E: ID_BUS=usb -E: ID_MODEL=USB_Sound_Device -E: ID_MODEL_ENC=USB\x20Sound\x20Device\x20\x20\x20\x20\x20\x20\x20\x20 -E: ID_MODEL_FROM_DATABASE=CM106 Like Sound Device -E: ID_MODEL_ID=0102 -E: ID_REVISION=0010 -E: ID_SERIAL=0d8c_USB_Sound_Device -E: ID_USB_INTERFACES=:010100:010200:030000: -E: ID_VENDOR=0d8c -E: ID_VENDOR_ENC=0d8c -E: ID_VENDOR_FROM_DATABASE=C-Media Electronics, Inc. -E: ID_VENDOR_ID=0d8c -E: MAJOR=189 -E: MINOR=134 -E: PRODUCT=d8c/102/10 -E: SUBSYSTEM=usb -E: TYPE=0/0/0 -A: authorized=1 -A: avoid_reset_quirk=0 -A: bConfigurationValue=1 -A: bDeviceClass=00 -A: bDeviceProtocol=00 -A: bDeviceSubClass=00 -A: bMaxPacketSize0=8 -A: bMaxPower=500mA -A: bNumConfigurations=1 -A: bNumInterfaces= 4 -A: bcdDevice=0010 -A: bmAttributes=80 -A: busnum=2 -A: configuration= -H: descriptors=12011001000000088C0D02011000000200010902160204010080FA0904000000010100000A24010001C8000201020C240201010100083F0600000C24020401020002030000000A2406080401010202000A2406090401010202001924040C0301090B083F0600000000000000000000000000001024060D0C0101020202020202020200092403030103000D000D24041102090B0203000000000924030A01010007000A24050704080F1002000C24020603060002030000000A24060F0601010202000A24060B0601010202000C24020505060002030000000A2406021101010202000A240610050101000000090401000001020000090401010101020000072401010101000E2402010802100244AC0080BB0009050609100301000007250101000000090401020101020000072401010101000E2402010202100244AC0080BB0009050609C40001000007250101000000090401030101020000072401010101000E2402010402100244AC0080BB0009050609880101000007250101000000090401040101020000072401010101000E2402010602100244AC0080BB0009050609480201000007250101000000090401050101020000072401010101000B2402010202100180BB00090506098801010000072501010000000904020000010200000904020101010200000724010A0101000E2402010202100244AC0080BB0009058505C8000100000725010100000009040300010300000009210001000122320007058103030001 -A: dev=189:134 -A: devnum=7 -A: devpath=2.1.1 -L: driver=../../../../../../../bus/usb/drivers/usb -A: idProduct=0102 -A: idVendor=0d8c -A: ltm_capable=no -A: maxchild=0 -L: port=../2-2.1:1.0/2-2.1-port1 -A: power/active_duration=16246121 -A: power/autosuspend=2 -A: power/autosuspend_delay_ms=2000 -A: power/connected_duration=16246121 -A: power/control=on -A: power/level=on -A: power/persist=1 -A: power/runtime_active_time=16245894 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: product=USB Sound Device -A: quirks=0x0 -A: removable=unknown -A: speed=12 -A: urbnum=1507680 -A: version= 1.10 - -P: /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2.1 -N: bus/usb/002/004=1201000209000140E305080637850001000109021900010100E0320904000001090000000705810301000C -E: BUSNUM=002 -E: DEVNAME=/dev/bus/usb/002/004 -E: DEVNUM=004 -E: DEVTYPE=usb_device -E: DRIVER=usb -E: ID_BUS=usb -E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_2_1 -E: ID_MODEL=USB2.0_Hub -E: ID_MODEL_ENC=USB2.0\x20Hub -E: ID_MODEL_FROM_DATABASE=Hub -E: ID_MODEL_ID=0608 -E: ID_PATH=pci-0000:00:14.0-usb-0:2.1 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1 -E: ID_REVISION=8537 -E: ID_SERIAL=05e3_USB2.0_Hub -E: ID_USB_INTERFACES=:090000: -E: ID_VENDOR=05e3 -E: ID_VENDOR_ENC=05e3 -E: ID_VENDOR_FROM_DATABASE=Genesys Logic, Inc. -E: ID_VENDOR_ID=05e3 -E: MAJOR=189 -E: MINOR=131 -E: PRODUCT=5e3/608/8537 -E: SUBSYSTEM=usb -E: TAGS=:seat: -E: TYPE=9/0/1 -A: authorized=1 -A: avoid_reset_quirk=0 -A: bConfigurationValue=1 -A: bDeviceClass=09 -A: bDeviceProtocol=01 -A: bDeviceSubClass=00 -A: bMaxPacketSize0=64 -A: bMaxPower=100mA -A: bNumConfigurations=1 -A: bNumInterfaces= 1 -A: bcdDevice=8537 -A: bmAttributes=e0 -A: busnum=2 -A: configuration= -H: descriptors=1201000209000140E305080637850001000109021900010100E0320904000001090000000705810301000C -A: dev=189:131 -A: devnum=4 -A: devpath=2.1 -L: driver=../../../../../../bus/usb/drivers/usb -A: idProduct=0608 -A: idVendor=05e3 -A: ltm_capable=no -A: maxchild=4 -L: port=../2-2:1.0/2-2-port1 -A: power/active_duration=16246519 -A: power/autosuspend=0 -A: power/autosuspend_delay_ms=0 -A: power/connected_duration=16246519 -A: power/control=auto -A: power/level=auto -A: power/runtime_active_time=16246338 -A: power/runtime_status=active -A: power/runtime_suspended_time=0 -A: power/wakeup=disabled -A: power/wakeup_abort_count= -A: power/wakeup_active= -A: power/wakeup_active_count= -A: power/wakeup_count= -A: power/wakeup_expire_count= -A: power/wakeup_last_time_ms= -A: power/wakeup_max_time_ms= -A: power/wakeup_total_time_ms= -A: product=USB2.0 Hub -A: quirks=0x0 -A: removable=unknown -A: speed=480 -A: urbnum=28 -A: version= 2.00 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input9/event8 -N: input/event8 -E: DEVNAME=/dev/input/event8 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: LIBINPUT_DEVICE_GROUP=0/0/0:ALSA -E: MAJOR=13 -E: MINOR=72 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:72 -L: device=../../input9 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input9 -E: EV=21 -E: ID_FOR_SEAT=input-pci-0000_00_03_0 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: MODALIAS=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -E: NAME="HDA Intel HDMI HDMI/DP,pcm=3" -E: PHYS="ALSA" -E: PRODUCT=0/0/0/0 -E: PROP=0 -E: SUBSYSTEM=input -E: SW=140 -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=21 -A: capabilities/ff=0 -A: capabilities/key=0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=140 -L: device=../../card0 -A: id/bustype=0000 -A: id/product=0000 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -A: name=HDA Intel HDMI HDMI/DP,pcm=3 -A: phys=ALSA -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input10/event9 -N: input/event9 -E: DEVNAME=/dev/input/event9 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: LIBINPUT_DEVICE_GROUP=0/0/0:ALSA -E: MAJOR=13 -E: MINOR=73 -E: SUBSYSTEM=input -E: TAGS=:power-switch: -A: dev=13:73 -L: device=../../input10 -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 - -P: /devices/pci0000:00/0000:00:03.0/sound/card0/input10 -E: EV=21 -E: ID_FOR_SEAT=input-pci-0000_00_03_0 -E: ID_INPUT=1 -E: ID_INPUT_SWITCH=1 -E: ID_PATH=pci-0000:00:03.0 -E: ID_PATH_TAG=pci-0000_00_03_0 -E: MODALIAS=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -E: NAME="HDA Intel HDMI HDMI/DP,pcm=7" -E: PHYS="ALSA" -E: PRODUCT=0/0/0/0 -E: PROP=0 -E: SUBSYSTEM=input -E: SW=140 -E: TAGS=:seat: -A: capabilities/abs=0 -A: capabilities/ev=21 -A: capabilities/ff=0 -A: capabilities/key=0 -A: capabilities/led=0 -A: capabilities/msc=0 -A: capabilities/rel=0 -A: capabilities/snd=0 -A: capabilities/sw=140 -L: device=../../card0 -A: id/bustype=0000 -A: id/product=0000 -A: id/vendor=0000 -A: id/version=0000 -A: modalias=input:b0000v0000p0000e0000-e0,5,kramlsfw6,8, -A: name=HDA Intel HDMI HDMI/DP,pcm=7 -A: phys=ALSA -A: power/control=auto -A: power/runtime_active_time=0 -A: power/runtime_status=unsupported -A: power/runtime_suspended_time=0 -A: properties=0 -A: uniq= - diff --git a/tests/auto/udev/tst_udev.cpp b/tests/auto/udev/tst_udev.cpp deleted file mode 100644 index 47efe0ea..00000000 --- a/tests/auto/udev/tst_udev.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:GPL3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include -#include - -#include - -using namespace Aurora::PlatformSupport; - -class TestUdev : public QObject -{ - Q_OBJECT -public: - TestUdev(QObject *parent = nullptr) - : QObject(parent) - { - } - -private: - UMockdevTestbed *m_bed = nullptr; - -private Q_SLOTS: - void initTestCase() - { - m_bed = umockdev_testbed_new(); - QVERIFY(m_bed != nullptr); - QString path = QFINDTESTDATA("test.umockdev"); - QVERIFY(!path.isEmpty()); - qInfo() << "Using:" << path; - - g_autoptr(GError) error = nullptr; - umockdev_testbed_add_from_file(m_bed, path.toLatin1().constData(), &error); - if (error) - QFAIL(error->message); - umockdev_testbed_enable(m_bed); - - QVERIFY(umockdev_in_mock_environment()); - } - - void cleanupTestCase() - { - if (m_bed) - g_object_unref(m_bed); - } - - void testConnection() - { - Udev *udev = new Udev; - QVERIFY(udev->isValid()); - delete udev; - } - - void testDevice() - { - Udev *udev = new Udev; - QVERIFY(udev->isValid()); - - UdevDevice *dev = udev->deviceFromFileName(QStringLiteral("/dev/sda")); - QVERIFY(dev); - QCOMPARE(dev->deviceNode(), QStringLiteral("/dev/sda")); - QCOMPARE(dev->name(), QStringLiteral("sda")); - QVERIFY(dev->hasProperty(QStringLiteral("ID_SERIAL"))); - QCOMPARE(dev->property(QStringLiteral("ID_SERIAL")), QStringLiteral("TOSHIBA_MQ01ABD100_Y49DSZAOS")); - QCOMPARE(dev->property(QStringLiteral("ID_MODEL")), QStringLiteral("TOSHIBA_MQ01ABD100")); - - delete dev; - delete udev; - } - - void testEnumerate() - { - Udev *udev = new Udev; - QVERIFY(udev->isValid()); - - UdevEnumerate *enumerate = new UdevEnumerate(UdevDevice::InputDevice_Mask, udev); - QList devices = enumerate->scan(); - QVERIFY(devices.size() > 0); - - delete enumerate; - delete udev; - } -}; - -QTEST_MAIN(TestUdev) - -#include "tst_udev.moc"