diff --git a/Modules/about-distro/src/Module.cpp b/Modules/about-distro/src/Module.cpp index efa41ab..89070c6 100644 --- a/Modules/about-distro/src/Module.cpp +++ b/Modules/about-distro/src/Module.cpp @@ -1,315 +1,315 @@ /* Copyright (C) 2012-2014 Harald Sitter 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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 . */ #include "Module.h" #include "ui_Module.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_LINUX #include #elif defined(Q_OS_FREEBSD) #include #include #endif #include #include "Version.h" static qlonglong calculateTotalRam() { qlonglong ret = -1; #ifdef Q_OS_LINUX struct sysinfo info; if (sysinfo(&info) == 0) // manpage "sizes are given as multiples of mem_unit bytes" ret = qlonglong(info.totalram) * info.mem_unit; #elif defined(Q_OS_FREEBSD) /* Stuff for sysctl */ size_t len; unsigned long memory; len = sizeof(memory); sysctlbyname("hw.physmem", &memory, &len, NULL, 0); ret = memory; #endif return ret; } Module::Module(QWidget *parent, const QVariantList &args) : KCModule(parent, args), ui(new Ui::Module) { KAboutData *aboutData = new KAboutData(QStringLiteral("kcm-about-distro"), i18nc("@title", "About Distribution"), QString::fromLatin1(global_s_versionStringFull), QString(), KAboutLicense::LicenseKey::GPL_V3, i18nc("@info:credit", "Copyright 2012-2014 Harald Sitter")); aboutData->addAuthor(i18nc("@info:credit", "Harald Sitter"), i18nc("@info:credit", "Author"), QStringLiteral("apachelogger@kubuntu.org")); setAboutData(aboutData); ui->setupUi(this); QFont font = ui->nameVersionLabel->font(); font.setPixelSize(24); font.setBold(true); ui->nameVersionLabel->setFont(font); QFont fontVariant = ui->variantLabel->font(); fontVariant.setPixelSize(18); fontVariant.setBold(true); ui->variantLabel->setFont(fontVariant); ui->urlLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); // We have no help so remove the button from the buttons. setButtons(buttons() ^ KCModule::Help ^ KCModule::Default ^ KCModule::Apply); // Setup Copy to Clipboard button connect(ui->pushButtonCopyInfo, &QPushButton::clicked, this, &Module::copyToClipboard); connect(ui->pushButtonCopyInfoInEnglish, &QPushButton::clicked, this, &Module::copyToClipboardInEnglish); if (QLocale::system().language() == QLocale::English) { ui->pushButtonCopyInfoInEnglish->hide(); } ui->pushButtonCopyInfo->setShortcut(QKeySequence::Copy); // https://bugs.kde.org/show_bug.cgi?id=366158 // When a KCM loads fast enough do a blocking load via the constructor. // Otherwise there is a notciable rendering gap where dummy/no data is // shown. Makes it look bad. load(); } Module::~Module() { delete ui; } void Module::load() { labelsForClipboard.clear(); englishTextForClipboard = QStringLiteral(""); loadSoftware(); loadHardware(); } void Module::save() { } void Module::defaults() { } void Module::loadSoftware() { // NOTE: do not include globals, otherwise kdeglobals could provide values // even though we only explicitly want them from our own config. KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("kcm-about-distrorc"), KConfig::NoGlobals); KConfigGroup cg = KConfigGroup(config, "General"); KOSRelease os; QString logoPath = cg.readEntry("LogoPath", os.logo()); if (logoPath.isEmpty()) { logoPath = QStringLiteral("start-here-kde"); } const QPixmap logo = QIcon::fromTheme(logoPath).pixmap(128, 128); ui->logoLabel->setPixmap(logo); // We allow overriding of the OS name for branding purposes. // For example OS Ubuntu may be rebranded as Kubuntu. Also Kubuntu Active // as a product brand is different from Kubuntu. const QString distroName = cg.readEntry("Name", os.name()); const QString osrVersion = cg.readEntry("UseOSReleaseVersion", false) ? os.version() : os.versionId(); const QString versionId = cg.readEntry("Version", osrVersion); const QString distroNameVersion = QStringLiteral("%1 %2").arg(distroName, versionId); ui->nameVersionLabel->setText(distroNameVersion); const auto dummyDistroDescriptionLabel = new QLabel(i18nc("@title:row", "Operating System:"), this); dummyDistroDescriptionLabel->hide(); labelsForClipboard << qMakePair(dummyDistroDescriptionLabel, ui->nameVersionLabel); englishTextForClipboard += QStringLiteral("Operating System: %1\n").arg(distroNameVersion); const QString variant = cg.readEntry("Variant", os.variant()); if (variant.isEmpty()) { ui->variantLabel->hide(); } else { ui->variantLabel->setText(variant); } const QString url = cg.readEntry("Website", os.homeUrl()); if (url.isEmpty()) { ui->urlLabel->hide(); } else { ui->urlLabel->setText(QStringLiteral("%1").arg(url)); } // Since Plasma version detection isn't based on a library query it can fail // in weird cases; instead of admitting defeat we simply hide everything :P const QString plasma = plasmaVersion(); if (plasma.isEmpty()) { ui->plasma->hide(); ui->plasmaLabel->hide(); } else { ui->plasmaLabel->setText(plasma); labelsForClipboard << qMakePair(ui->plasma, ui->plasmaLabel); englishTextForClipboard += QStringLiteral("KDE Plasma Version: %1\n").arg(plasma); } const QString frameworksVersion = KCoreAddons::versionString(); ui->frameworksLabel->setText(frameworksVersion); labelsForClipboard << qMakePair(ui->frameworksLabelKey, ui->frameworksLabel); englishTextForClipboard += QStringLiteral("KDE Frameworks Version: %1\n").arg(frameworksVersion); const QString qversion = QString::fromLatin1(qVersion()); ui->qtLabel->setText(qversion); labelsForClipboard << qMakePair(ui->qt, ui->qtLabel); englishTextForClipboard += QStringLiteral("Qt Version: %1\n").arg(qversion); } void Module::loadHardware() { struct utsname utsName; if(uname(&utsName) != 0) { ui->kernel->hide(); ui->kernelLabel->hide(); } else { QString kernelVersion = QString::fromLatin1(utsName.release); ui->kernelLabel->setText(kernelVersion); labelsForClipboard << qMakePair(ui->kernel, ui->kernelLabel); englishTextForClipboard += QStringLiteral("Kernel Version: %1\n").arg(kernelVersion); } const int bits = QT_POINTER_SIZE == 8 ? 64 : 32; const QString bitsStr = QString::number(bits); ui->bitsLabel->setText(i18nc("@label %1 is the CPU bit width (e.g. 32 or 64)", "%1-bit", bitsStr)); labelsForClipboard << qMakePair(ui->bitsKey, ui->bitsLabel); englishTextForClipboard += QStringLiteral("OS Type: %1-bit\n").arg(bitsStr); const QList list = Solid::Device::listFromType(Solid::DeviceInterface::Processor); ui->processor->setText(i18np("Processor:", "Processors:", list.count())); // Format processor string // Group by processor name QMap processorMap; Q_FOREACH(const Solid::Device &device, list) { const QString name = device.product(); auto it = processorMap.find(name); if (it == processorMap.end()) { processorMap.insert(name, 1); } else { ++it.value(); } } // Create a formatted list of grouped processors QStringList names; names.reserve(processorMap.count()); for (auto it = processorMap.constBegin(); it != processorMap.constEnd(); ++it) { const int count = it.value(); QString name = it.key(); name.replace(QStringLiteral("(TM)"), QChar(8482)); name.replace(QStringLiteral("(R)"), QChar(174)); name = name.simplified(); names.append(QStringLiteral("%1 × %2").arg(count).arg(name)); } - const QString processorLabel = names.join(QStringLiteral(", ")); + const QString processorLabel = names.join(QLatin1String(", ")); ui->processorLabel->setText(processorLabel); if (ui->processorLabel->text().isEmpty()) { ui->processor->setHidden(true); ui->processorLabel->setHidden(true); } else { labelsForClipboard << qMakePair(ui->processor, ui->processorLabel); englishTextForClipboard += QStringLiteral("Processors: %1\n").arg(processorLabel); } const qlonglong totalRam = calculateTotalRam(); const QString memoryLabel = totalRam > 0 ? i18nc("@label %1 is the formatted amount of system memory (e.g. 7,7 GiB)", "%1 of RAM", KFormat().formatByteSize(totalRam)) : i18nc("Unknown amount of RAM", "Unknown"); ui->memoryLabel->setText(memoryLabel); labelsForClipboard << qMakePair(ui->memory, ui->memoryLabel); englishTextForClipboard += QStringLiteral("Memory: %1\n").arg(KFormat().formatByteSize(totalRam)); } void Module::copyToClipboard() { QString text; // note that this loop does not necessarily represent the same order as in the GUI for (auto labelPair : qAsConst(labelsForClipboard)) { const auto valueLabel = labelPair.second; if (!valueLabel->isHidden()) { const auto descriptionLabelText = labelPair.first->text(); const auto valueLabelText = valueLabel->text(); text += i18nc("%1 is a label already including a colon, %2 is the corresponding value", "%1 %2", descriptionLabelText, valueLabelText) + QStringLiteral("\n"); } } QGuiApplication::clipboard()->setText(text); } void Module::copyToClipboardInEnglish() { QGuiApplication::clipboard()->setText(englishTextForClipboard); } QString Module::plasmaVersion() const { const QStringList &filePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("xsessions/plasma.desktop")); if (filePaths.length() < 1) { return QString(); } // Despite the fact that there can be multiple desktop files we simply take // the first one as users usually don't have xsessions/ in their $HOME // data location, so the first match should (usually) be the only one and // reflect the plasma session run. KDesktopFile desktopFile(filePaths.first()); return desktopFile.desktopGroup().readEntry("X-KDE-PluginInfo-Version", QString()); } diff --git a/Modules/devinfo/soldevicetypes.cpp b/Modules/devinfo/soldevicetypes.cpp index 133edca..5ff1aa4 100644 --- a/Modules/devinfo/soldevicetypes.cpp +++ b/Modules/devinfo/soldevicetypes.cpp @@ -1,509 +1,509 @@ /* * soldevicetypes.cpp * * Copyright (C) 2009 David Hubner * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "soldevicetypes.h" #include #include #include // ---- Processor SolProcessorDevice::SolProcessorDevice(QTreeWidgetItem *parent, const Solid::Device &device) : SolDevice(parent, device) { deviceTypeHolder = Solid::DeviceInterface::Processor; setDefaultDeviceText(); } SolProcessorDevice::SolProcessorDevice(const Solid::DeviceInterface::Type &type) : SolDevice(type) { deviceTypeHolder = Solid::DeviceInterface::Processor; setDeviceIcon(QIcon::fromTheme(QStringLiteral("cpu"))); setDeviceText(i18n("Processors")); setDefaultListing(type); } void SolProcessorDevice::setDefaultListing(const Solid::DeviceInterface::Type &type) { createDeviceChildren(this, QString(), type); } void SolProcessorDevice::setDefaultDeviceText() { const Solid::Processor *prodev = interface(); if (!prodev) { return; } setText(0, i18n("Processor %1", QString::number(prodev->number()))); } QVListLayout *SolProcessorDevice::infoPanelLayout() { QStringList labels; const Solid::Processor *prodev = interface(); if (!prodev) { return nullptr; } deviceInfoLayout = new QVListLayout(); QStringList extensions; const Solid::Processor::InstructionSets insSets = prodev->instructionSets(); if (insSets & Solid::Processor::IntelMmx) { extensions << i18n("Intel MMX"); } if (insSets & Solid::Processor::IntelSse) { extensions << i18n("Intel SSE"); } if (insSets & Solid::Processor::IntelSse2) { extensions << i18n("Intel SSE2"); } if (insSets & Solid::Processor::IntelSse3) { extensions << i18n("Intel SSE3"); } if (insSets & Solid::Processor::IntelSse4) { extensions << i18n("Intel SSE4"); } if (insSets & Solid::Processor::Amd3DNow) { extensions << i18n("AMD 3DNow"); } if (insSets & Solid::Processor::AltiVec) { extensions << i18n("ATI IVEC"); } if (extensions.isEmpty()) { extensions << i18nc("no instruction set extensions", "None"); } labels << i18n("Processor Number: ") << InfoPanel::friendlyString(QString::number(prodev->number())) << i18n("Max Speed: ") << InfoPanel::friendlyString(QString::number(prodev->maxSpeed())) << i18n("Supported Instruction Sets: ") - << extensions.join(QStringLiteral("\n")); + << extensions.join(QLatin1String("\n")); deviceInfoLayout->applyQListToLayout(labels); return deviceInfoLayout; } // ---- Storage SolStorageDevice::SolStorageDevice(QTreeWidgetItem *parent, const Solid::Device &device, const storageChildren &c) : SolDevice(parent, device) { deviceTypeHolder = Solid::DeviceInterface::StorageDrive; setDefaultDeviceText(); if (c == CREATECHILDREN) { createDeviceChildren(this, device.udi(), Solid::DeviceInterface::StorageVolume); } } SolStorageDevice::SolStorageDevice(const Solid::DeviceInterface::Type &type) : SolDevice(type) { deviceTypeHolder = Solid::DeviceInterface::StorageDrive; setDeviceIcon(QIcon::fromTheme(QStringLiteral("drive-harddisk"))); setDeviceText(i18n("Storage Drives")); setDefaultListing(type); } void SolStorageDevice::setDefaultListing(const Solid::DeviceInterface::Type &type) { createDeviceChildren(this, QString(), type); } void SolStorageDevice::setDefaultDeviceText() { const Solid::StorageDrive *stodev = interface(); if (!stodev) { return; } QString storageType; switch (stodev->driveType()) { case Solid::StorageDrive::HardDisk: storageType = i18n("Hard Disk Drive"); break; case Solid::StorageDrive::CompactFlash: storageType = i18n("Compact Flash Reader"); break; case Solid::StorageDrive::SmartMedia: storageType = i18n("Smart Media Reader"); break; case Solid::StorageDrive::SdMmc: storageType = i18n("SD/MMC Reader"); break; case Solid::StorageDrive::CdromDrive: storageType = i18n("Optical Drive"); break; case Solid::StorageDrive::MemoryStick: storageType = i18n("Memory Stick Reader"); break; case Solid::StorageDrive::Xd: storageType = i18n("xD Reader"); break; default: storageType = i18n("Unknown Drive"); } QString deviceText = storageType; setDeviceText(deviceText); } QVListLayout *SolStorageDevice::infoPanelLayout() { QStringList labels; const Solid::StorageDrive *stodev = interface(); if (!stodev) { return nullptr; } deviceInfoLayout = new QVListLayout(); QString bus; switch (stodev->bus()) { case Solid::StorageDrive::Ide: bus = i18n("IDE"); break; case Solid::StorageDrive::Usb: bus = i18n("USB"); break; case Solid::StorageDrive::Ieee1394: bus = i18n("IEEE1394"); break; case Solid::StorageDrive::Scsi: bus = i18n("SCSI"); break; case Solid::StorageDrive::Sata: bus = i18n("SATA"); break; case Solid::StorageDrive::Platform: bus = i18nc("platform storage bus", "Platform"); break; default: bus = i18nc("unknown storage bus", "Unknown"); } labels << i18n("Bus: ") << bus << i18n("Hotpluggable?") << InfoPanel::convertTf(stodev->isHotpluggable()) << i18n("Removable?") << InfoPanel::convertTf(stodev->isRemovable()); deviceInfoLayout->applyQListToLayout(labels); return deviceInfoLayout; } // ---- Volume SolVolumeDevice::SolVolumeDevice(QTreeWidgetItem *parent, const Solid::Device &device) : SolDevice(parent, device) { deviceTypeHolder = Solid::DeviceInterface::StorageVolume; } SolVolumeDevice::SolVolumeDevice(const Solid::DeviceInterface::Type &type) : SolDevice(type) { deviceTypeHolder = Solid::DeviceInterface::StorageVolume; setDefaultListing(type); } void SolVolumeDevice::setDefaultListing(const Solid::DeviceInterface::Type &type) { createDeviceChildren(this, QString(), type); } QVListLayout *SolVolumeDevice::infoPanelLayout() { QStringList labels; KCapacityBar *usageBar = nullptr; const Solid::StorageVolume *voldev = interface(); const Solid::StorageAccess *accdev = interface(); if (!voldev) { return nullptr; } deviceInfoLayout = new QVListLayout(); QString usage; switch (voldev->usage()) { case Solid::StorageVolume::Unused: usage = i18n("Unused"); break; case Solid::StorageVolume::FileSystem: usage = i18n("File System"); break; case Solid::StorageVolume::PartitionTable: usage = i18n("Partition Table"); break; case Solid::StorageVolume::Raid: usage = i18n("Raid"); break; case Solid::StorageVolume::Encrypted: usage = i18n("Encrypted"); break; default: usage = i18nc("unknown volume usage", "Unknown"); } labels << i18n("File System Type: ") << InfoPanel::friendlyString(voldev->fsType()) << i18n("Label: ") << InfoPanel::friendlyString(voldev->label(), i18n("Not Set")) << i18n("Volume Usage: ") << usage << i18n("UUID: ") << InfoPanel::friendlyString(voldev->uuid()); if (accdev) { labels << QStringLiteral("--") << i18n("Mounted At: ") << InfoPanel::friendlyString(accdev->filePath(), i18n("Not Mounted")); if (!accdev->filePath().isEmpty()) { KDiskFreeSpaceInfo mountSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(accdev->filePath()); labels << i18n("Volume Space:"); usageBar = new KCapacityBar(); if (mountSpaceInfo.size() > 0) { usageBar->setValue(static_cast((mountSpaceInfo.used() * 100) / mountSpaceInfo.size())); usageBar->setText( i18nc("Available space out of total partition size (percent used)", "%1 free of %2 (%3% used)", KFormat().formatByteSize(mountSpaceInfo.available()), KFormat().formatByteSize(mountSpaceInfo.size()), usageBar->value())); } else { usageBar->setValue(0); usageBar->setText(i18n("No data available")); } } } deviceInfoLayout->applyQListToLayout(labels); if (usageBar) { deviceInfoLayout->addWidget(usageBar); } return deviceInfoLayout; } // Media Player SolMediaPlayerDevice::SolMediaPlayerDevice(QTreeWidgetItem *parent, const Solid::Device &device) : SolDevice(parent, device) { deviceTypeHolder = Solid::DeviceInterface::PortableMediaPlayer; } SolMediaPlayerDevice::SolMediaPlayerDevice(const Solid::DeviceInterface::Type &type) : SolDevice(type) { deviceTypeHolder = Solid::DeviceInterface::PortableMediaPlayer; setDeviceIcon(QIcon::fromTheme(QStringLiteral("multimedia-player"))); setDeviceText(i18n("Multimedia Players")); setDefaultListing(type); } void SolMediaPlayerDevice::setDefaultListing(const Solid::DeviceInterface::Type &type) { createDeviceChildren(this, QString(), type); } QVListLayout *SolMediaPlayerDevice::infoPanelLayout() { QStringList labels; const Solid::PortableMediaPlayer *mpdev = interface(); if (!mpdev) { return nullptr; } deviceInfoLayout = new QVListLayout(); labels << i18n("Supported Drivers: ") << mpdev->supportedDrivers() << i18n("Supported Protocols: ") << mpdev->supportedProtocols(); deviceInfoLayout->applyQListToLayout(labels); return deviceInfoLayout; } // Camera SolCameraDevice::SolCameraDevice(QTreeWidgetItem *parent, const Solid::Device &device) : SolDevice(parent, device) { deviceTypeHolder = Solid::DeviceInterface::Camera; } SolCameraDevice::SolCameraDevice(const Solid::DeviceInterface::Type &type) : SolDevice(type) { deviceTypeHolder = Solid::DeviceInterface::Camera; setDeviceIcon(QIcon::fromTheme(QStringLiteral("camera-web"))); setDeviceText(i18n("Cameras")); setDefaultListing(type); } void SolCameraDevice::setDefaultListing(const Solid::DeviceInterface::Type &type) { createDeviceChildren(this, QString(), type); } QVListLayout *SolCameraDevice::infoPanelLayout() { QStringList labels; const Solid::Camera *camdev = interface(); if (!camdev) { return nullptr; } deviceInfoLayout = new QVListLayout(); labels << i18n("Supported Drivers: ") << camdev->supportedDrivers() << i18n("Supported Protocols: ") << camdev->supportedProtocols(); deviceInfoLayout->applyQListToLayout(labels); return deviceInfoLayout; } // Battery SolBatteryDevice::SolBatteryDevice(QTreeWidgetItem *parent, const Solid::Device &device) : SolDevice(parent, device) { deviceTypeHolder = Solid::DeviceInterface::Battery; } SolBatteryDevice::SolBatteryDevice(const Solid::DeviceInterface::Type &type) : SolDevice(type) { deviceTypeHolder = Solid::DeviceInterface::Battery; setDeviceIcon(QIcon::fromTheme(QStringLiteral("battery"))); setDeviceText(i18n("Batteries")); setDefaultListing(type); } void SolBatteryDevice::setDefaultListing(const Solid::DeviceInterface::Type &type) { createDeviceChildren(this, QString(), type); } QVListLayout *SolBatteryDevice::infoPanelLayout() { QStringList labels; const Solid::Battery *batdev = interface(); if (!batdev) { return nullptr; } deviceInfoLayout = new QVListLayout(); QString type; switch (batdev->type()) { case Solid::Battery::PdaBattery: type = i18n("PDA"); break; case Solid::Battery::UpsBattery: type = i18n("UPS"); break; case Solid::Battery::PrimaryBattery: type = i18n("Primary"); break; case Solid::Battery::MouseBattery: type = i18n("Mouse"); break; case Solid::Battery::KeyboardBattery: type = i18n("Keyboard"); break; case Solid::Battery::KeyboardMouseBattery: type = i18n("Keyboard + Mouse"); break; case Solid::Battery::CameraBattery: type = i18n("Camera"); break; case Solid::Battery::PhoneBattery: type = i18n("Phone"); break; case Solid::Battery::MonitorBattery: type = i18nc("Screen", "Monitor"); break; case Solid::Battery::GamingInputBattery: type = i18nc("Wireless game pad or joystick battery", "Gaming Input"); break; default: type = i18nc("unknown battery type", "Unknown"); } QString state; switch (batdev->chargeState()) { case Solid::Battery::Charging: state = i18n("Charging"); break; case Solid::Battery::Discharging: state = i18n("Discharging"); break; case Solid::Battery::FullyCharged: state = i18n("Fully Charged"); break; default: state = i18n("No Charge"); } labels << i18n("Battery Type: ") << type << i18n("Charge Status: ") << state << i18n("Charge Percent: "); deviceInfoLayout->applyQListToLayout(labels); QProgressBar *chargePercent = new QProgressBar(); chargePercent->setMaximum(100); chargePercent->setValue(batdev->chargePercent()); chargePercent->setEnabled(batdev->isPresent()); deviceInfoLayout->addWidget(chargePercent); return deviceInfoLayout; } diff --git a/Modules/opengl/opengl.cpp b/Modules/opengl/opengl.cpp index 847e9c5..340af6d 100644 --- a/Modules/opengl/opengl.cpp +++ b/Modules/opengl/opengl.cpp @@ -1,1036 +1,1036 @@ /* * opengl.cpp * * Copyright (C) 2008 Ivo Anjo * Copyright (C) 2004 Ilya Korniyko * Adapted from Brian Paul's glxinfo from Mesa demos (http://www.mesa3d.org) * Copyright (C) 1999-2002 Brian Paul * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "opengl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include // X11 includes #include #include #include #if KCM_HAVE_EGL #include #endif #ifdef KCM_ENABLE_OPENGLES #include #endif #if KCM_HAVE_GLX // GLU includes #include // OpenGL includes #include #include #include #endif #if defined(Q_OS_LINUX) #include #include #include #endif K_PLUGIN_FACTORY(KCMOpenGLFactory, registerPlugin(); ) // FIXME: Temporary! bool GetInfo_OpenGL(QTreeWidget *treeWidget); KCMOpenGL::KCMOpenGL(QWidget *parent, const QVariantList &) : KCModule(parent) { setupUi(this); layout()->setContentsMargins(0, 0, 0, 0); GetInfo_OpenGL(glinfoTreeWidget); // Watch for expanded and collapsed events, to resize columns connect(glinfoTreeWidget, &QTreeWidget::expanded, this, &KCMOpenGL::treeWidgetChanged); connect(glinfoTreeWidget, &QTreeWidget::collapsed, this, &KCMOpenGL::treeWidgetChanged); KAboutData *about = new KAboutData(i18n("kcmopengl"), i18n("KCM OpenGL Information"), QString(), QString(), KAboutLicense::GPL, i18n("(c) 2008 Ivo Anjo\n(c) 2004 Ilya Korniyko\n(c) 1999-2002 Brian Paul")); about->addAuthor(i18n("Ivo Anjo"), QString(), QStringLiteral("knuckles@gmail.com")); about->addAuthor(i18n("Ilya Korniyko"), QString(), QStringLiteral("k_ilya@ukr.net")); about->addCredit(i18n("Helge Deller"), i18n("Original Maintainer"), QStringLiteral("deller@gmx.de")); about->addCredit(i18n("Brian Paul"), i18n("Author of glxinfo Mesa demos (http://www.mesa3d.org)")); setAboutData(about); } void KCMOpenGL::treeWidgetChanged() { glinfoTreeWidget->resizeColumnToContents(0); glinfoTreeWidget->resizeColumnToContents(1); } QTreeWidgetItem *newItem(QTreeWidgetItem *parent, QTreeWidgetItem *preceding, const QString &textCol1, const QString &textCol2 = QString()) { QTreeWidgetItem *newItem; if ((parent == nullptr) && (preceding == nullptr)) { newItem = new QTreeWidgetItem(); } else if (preceding == nullptr) { newItem = new QTreeWidgetItem(parent); } else { newItem = new QTreeWidgetItem(parent, preceding); } newItem->setText(0, textCol1); if (!textCol2.isNull()) { newItem->setText(1, textCol2); } newItem->setFlags(Qt::ItemIsEnabled); return newItem; } QTreeWidgetItem *newItem(QTreeWidgetItem *parent, const QString &textCol1, const QString &textCol2 = QString()) { return newItem(parent, NULL, textCol1, textCol2); } static bool IsDirect; static struct glinfo { #if KCM_HAVE_GLX const char *serverVendor; const char *serverVersion; const char *serverExtensions; const char *clientVendor; const char *clientVersion; const char *clientExtensions; const char *glxExtensions; #endif #if KCM_HAVE_EGL const char *eglVendor; const char *eglVersion; const char *eglExtensions; #endif const char *glVendor; const char *glRenderer; const char *glVersion; const char *glExtensions; #if KCM_HAVE_GLX const char *gluVersion; const char *gluExtensions; #endif char *displayName; } gli; static struct { QString module, pci, vendor, device, subvendor, rev; } dri_info; static int ReadPipe(const QString &FileName, QStringList &list) { QProcess pipe; pipe.start(FileName, QIODevice::ReadOnly); if (!pipe.waitForFinished()) { // something went wrong, f.e. command not found return 0; } QTextStream t(&pipe); while (!t.atEnd()) list.append(t.readLine()); return list.count(); } #if defined(Q_OS_LINUX) static QString get_sysfs_link_name(const QString& path) { const QString target = QFileInfo(path).symLinkTarget(); const int index = target.lastIndexOf(QChar('/')); if (index == -1) return QString(); return target.mid(index + 1); } static bool get_drm_device_sysfs() { struct stat fileInfo; if (::stat("/dev/dri/card0", &fileInfo) != 0) return false; if ((fileInfo.st_mode & S_IFCHR) != S_IFCHR) return false; const uint16_t devMajor = major(fileInfo.st_rdev); const uint16_t devMinor = minor(fileInfo.st_rdev); QString sysPath = QStringLiteral("/sys/dev/char/%1:%2/device").arg(devMajor).arg(devMinor); dri_info.pci = get_sysfs_link_name(sysPath); dri_info.module = get_sysfs_link_name(sysPath + QStringLiteral("/driver")); return (dri_info.pci.size() && dri_info.module.size()); } #define INFO_DRI QStringLiteral("/proc/dri/0/name") static bool get_dri_device_proc() { QFile file; file.setFileName(INFO_DRI); if (!file.exists() || !file.open(QIODevice::ReadOnly)) return false; QTextStream stream(&file); QString line = stream.readLine(); if (line.isEmpty()) return false; dri_info.module = line.mid(0, line.indexOf(0x20)); // possible formats, for regression testing // line = " PCI:01:00:0"; // line = " pci:0000:01:00.0" QRegExp rx = QRegExp("\\b[Pp][Cc][Ii][:]([0-9a-fA-F]+[:])?([0-9a-fA-F]+[:][0-9a-fA-F]+[:.][0-9a-fA-F]+)\\b"); if (rx.indexIn(line)>0) { dri_info.pci = rx.cap(2); int end = dri_info.pci.lastIndexOf(':'); int end2 = dri_info.pci.lastIndexOf('.'); if (end2>end) end=end2; dri_info.pci[end]='.'; return true; } return false; } static bool get_dri_device() { if (!get_drm_device_sysfs() && !get_dri_device_proc()) return false; QString cmd = QStringLiteral("lspci -m -v -s ") + dri_info.pci; QStringList pci_info; int num; if (((num = ReadPipe(cmd, pci_info)) || (num = ReadPipe("/sbin/"+cmd, pci_info)) || (num = ReadPipe("/usr/sbin/"+cmd, pci_info)) || (num = ReadPipe("/usr/local/sbin/"+cmd, pci_info))) && num>=7) { QString line; for (int i=2; i<=6; i++) { line = pci_info[i]; line.remove(QRegExp("[^:]*:[ ]*")); switch (i){ case 2: dri_info.vendor = line; break; case 3: dri_info.device = line; break; case 4: dri_info.subvendor = line; break; case 6: dri_info.rev = line; break; } } return true; } return false; } #elif defined(Q_OS_FREEBSD) static bool get_dri_device() { QStringList pci_info; if (ReadPipe("sysctl -n hw.dri.0.name",pci_info)) { dri_info.module = pci_info[0].mid(0, pci_info[0].indexOf(0x20)); } return false; } #else static bool get_dri_device() { return false; } #endif #if KCM_HAVE_GLX static void mesa_hack(Display *dpy, int scrnum) { static const int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, GLX_STENCIL_SIZE, 1, GLX_ACCUM_RED_SIZE, 1, GLX_ACCUM_GREEN_SIZE, 1, GLX_ACCUM_BLUE_SIZE, 1, GLX_ACCUM_ALPHA_SIZE, 1, GLX_DOUBLEBUFFER, None }; XVisualInfo *visinfo; visinfo = glXChooseVisual(dpy, scrnum, const_cast(attribs)); if (visinfo) XFree(visinfo); } #endif static void print_extension_list(const char *ext, QTreeWidgetItem *l1) { int i, j; if (!ext || !ext[0]) return; QString qext = QString::fromLatin1(ext); QTreeWidgetItem *l2 = nullptr; i = j = 0; while (1) { if (ext[j] == ' ' || ext[j] == 0) { /* found end of an extension name */ const int len = j - i; /* print the extension name between ext[i] and ext[j] */ if (!l2) l2 = newItem(l1, qext.mid(i, len)); else l2 = newItem(l1, l2, qext.mid(i, len)); i=j; if (ext[j] == 0) { break; } else { i++; j++; if (ext[j] == 0) break; } } j++; } } #if KCM_HAVE_GLX #if defined(GLX_ARB_get_proc_address) && defined(__GLXextFuncPtr) extern "C" { extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *); } #endif static void print_limits(QTreeWidgetItem *l1, const char * glExtensions, bool getProcAddress) { /* TODO GL_SAMPLE_BUFFERS GL_SAMPLES GL_COMPRESSED_TEXTURE_FORMATS */ if (!glExtensions) return; struct token_name { GLuint type; // count and flags, !!! count must be <=2 for now GLenum token; const QString name; }; struct token_group { int count; int type; const token_name *group; const QString descr; const char *ext; }; QTreeWidgetItem *l2 = nullptr, *l3 = nullptr; #if defined(PFNGLGETPROGRAMIVARBPROC) PFNGLGETPROGRAMIVARBPROC kcm_glGetProgramivARB = nullptr; #endif #define KCMGL_FLOAT 128 #define KCMGL_PROG 256 #define KCMGL_COUNT_MASK(x) (x & 127) #define KCMGL_SIZE(x) (sizeof(x)/sizeof(x[0])) const struct token_name various_limits[] = { { 1, GL_MAX_LIGHTS, i18n("Max. number of light sources") }, { 1, GL_MAX_CLIP_PLANES, i18n("Max. number of clipping planes") }, { 1, GL_MAX_PIXEL_MAP_TABLE, i18n("Max. pixel map table size") }, { 1, GL_MAX_LIST_NESTING, i18n("Max. display list nesting level") }, { 1, GL_MAX_EVAL_ORDER, i18n("Max. evaluator order") }, { 1, GL_MAX_ELEMENTS_VERTICES, i18n("Max. recommended vertex count") }, { 1, GL_MAX_ELEMENTS_INDICES, i18n("Max. recommended index count") }, #ifdef GL_QUERY_COUNTER_BITS { 1, GL_QUERY_COUNTER_BITS, i18n("Occlusion query counter bits")}, #endif #ifdef GL_MAX_VERTEX_UNITS_ARB { 1, GL_MAX_VERTEX_UNITS_ARB, i18n("Max. vertex blend matrices") }, #endif #ifdef GL_MAX_PALETTE_MATRICES_ARB { 1, GL_MAX_PALETTE_MATRICES_ARB, i18n("Max. vertex blend matrix palette size") }, #endif {0,0,QString()} }; const struct token_name texture_limits[] = { { 1, GL_MAX_TEXTURE_SIZE, i18n("Max. texture size") }, { 1, GL_MAX_TEXTURE_UNITS_ARB, i18n("No. of texture units") }, { 1, GL_MAX_3D_TEXTURE_SIZE, i18n("Max. 3D texture size") }, { 1, GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, i18n("Max. cube map texture size") }, #ifdef GL_MAX_RECTANGLE_TEXTURE_SIZE_NV { 1, GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, i18n("Max. rectangular texture size") }, #endif { 1 | KCMGL_FLOAT, GL_MAX_TEXTURE_LOD_BIAS_EXT, i18n("Max. texture LOD bias") }, { 1, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, i18n("Max. anisotropy filtering level") }, { 1, GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, i18n("No. of compressed texture formats") }, {0,0,QString()} }; const struct token_name float_limits[] = { { 2 | KCMGL_FLOAT, GL_ALIASED_POINT_SIZE_RANGE, "ALIASED_POINT_SIZE_RANGE" }, { 2 | KCMGL_FLOAT, GL_SMOOTH_POINT_SIZE_RANGE, "SMOOTH_POINT_SIZE_RANGE" }, { 1 | KCMGL_FLOAT, GL_SMOOTH_POINT_SIZE_GRANULARITY,"SMOOTH_POINT_SIZE_GRANULARITY"}, { 2 | KCMGL_FLOAT, GL_ALIASED_LINE_WIDTH_RANGE, "ALIASED_LINE_WIDTH_RANGE" }, { 2 | KCMGL_FLOAT, GL_SMOOTH_LINE_WIDTH_RANGE, "SMOOTH_LINE_WIDTH_RANGE" }, { 1 | KCMGL_FLOAT, GL_SMOOTH_LINE_WIDTH_GRANULARITY,"SMOOTH_LINE_WIDTH_GRANULARITY"}, {0,0,QString()} }; const struct token_name stack_depth[] = { { 1, GL_MAX_MODELVIEW_STACK_DEPTH, "MAX_MODELVIEW_STACK_DEPTH" }, { 1, GL_MAX_PROJECTION_STACK_DEPTH, "MAX_PROJECTION_STACK_DEPTH" }, { 1, GL_MAX_TEXTURE_STACK_DEPTH, "MAX_TEXTURE_STACK_DEPTH" }, { 1, GL_MAX_NAME_STACK_DEPTH, "MAX_NAME_STACK_DEPTH" }, { 1, GL_MAX_ATTRIB_STACK_DEPTH, "MAX_ATTRIB_STACK_DEPTH" }, { 1, GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, "MAX_CLIENT_ATTRIB_STACK_DEPTH" }, { 1, GL_MAX_COLOR_MATRIX_STACK_DEPTH, "MAX_COLOR_MATRIX_STACK_DEPTH" }, #ifdef GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB { 1, GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB,"MAX_MATRIX_PALETTE_STACK_DEPTH"}, #endif {0,0,QString()} }; #ifdef GL_ARB_fragment_program const struct token_name arb_fp[] = { { 1, GL_MAX_TEXTURE_COORDS_ARB, "MAX_TEXTURE_COORDS" }, { 1, GL_MAX_TEXTURE_IMAGE_UNITS_ARB, "MAX_TEXTURE_IMAGE_UNITS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, "MAX_PROGRAM_ENV_PARAMETERS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, "MAX_PROGRAM_LOCAL_PARAMETERS" }, { 1, GL_MAX_PROGRAM_MATRICES_ARB, "MAX_PROGRAM_MATRICES" }, { 1, GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB, "MAX_PROGRAM_MATRIX_STACK_DEPTH" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, "MAX_PROGRAM_INSTRUCTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, "MAX_PROGRAM_ALU_INSTRUCTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, "MAX_PROGRAM_TEX_INSTRUCTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, "MAX_PROGRAM_TEX_INDIRECTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_TEMPORARIES_ARB, "MAX_PROGRAM_TEMPORARIES" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_PARAMETERS_ARB, "MAX_PROGRAM_PARAMETERS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_ATTRIBS_ARB, "MAX_PROGRAM_ATTRIBS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "MAX_PROGRAM_NATIVE_INSTRUCTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, "MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, "MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, "MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, "MAX_PROGRAM_NATIVE_TEMPORARIES" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, "MAX_PROGRAM_NATIVE_PARAMETERS" }, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, "MAX_PROGRAM_NATIVE_ATTRIBS" }, {0,0,QString()} }; #endif #ifdef GL_ARB_vertex_program const struct token_name arb_vp[] = { { 1 | KCMGL_PROG, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB,"MAX_PROGRAM_ENV_PARAMETERS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB,"MAX_PROGRAM_LOCAL_PARAMETERS"}, { 1, GL_MAX_VERTEX_ATTRIBS_ARB, "MAX_VERTEX_ATTRIBS"}, { 1, GL_MAX_PROGRAM_MATRICES_ARB,"MAX_PROGRAM_MATRICES"}, { 1, GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB,"MAX_PROGRAM_MATRIX_STACK_DEPTH"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_INSTRUCTIONS_ARB,"MAX_PROGRAM_INSTRUCTIONS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_TEMPORARIES_ARB,"MAX_PROGRAM_TEMPORARIES"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_PARAMETERS_ARB,"MAX_PROGRAM_PARAMETERS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_ATTRIBS_ARB,"MAX_PROGRAM_ATTRIBS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB,"MAX_PROGRAM_ADDRESS_REGISTERS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,"MAX_PROGRAM_NATIVE_INSTRUCTIONS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,"MAX_PROGRAM_NATIVE_TEMPORARIES"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB,"MAX_PROGRAM_NATIVE_PARAMETERS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB,"MAX_PROGRAM_NATIVE_ATTRIBS"}, { 1 | KCMGL_PROG, GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB ,"MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS"}, {0,0,QString()} }; #endif #ifdef GL_ARB_vertex_shader const struct token_name arb_vs[] = { { 1, GL_MAX_VERTEX_ATTRIBS_ARB,"MAX_VERTEX_ATTRIBS"}, { 1, GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB,"MAX_VERTEX_UNIFORM_COMPONENTS"}, { 1, GL_MAX_VARYING_FLOATS_ARB,"MAX_VARYING_FLOATS"}, { 1, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB,"MAX_COMBINED_TEXTURE_IMAGE_UNITS"}, { 1, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB,"MAX_VERTEX_TEXTURE_IMAGE_UNITS"}, { 1, GL_MAX_TEXTURE_IMAGE_UNITS_ARB,"MAX_TEXTURE_IMAGE_UNITS"}, { 1, GL_MAX_TEXTURE_COORDS_ARB,"MAX_TEXTURE_COORDS"}, {0,0,QString()} }; #endif #ifdef GL_ARB_fragment_shader const struct token_name arb_fs[] = { { 1, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB,"MAX_FRAGMENT_UNIFORM_COMPONENTS"}, { 1, GL_MAX_TEXTURE_IMAGE_UNITS_ARB,"MAX_TEXTURE_IMAGE_UNITS"}, { 1, GL_MAX_TEXTURE_COORDS_ARB,"MAX_TEXTURE_COORDS"}, {0,0,QString()} }; #endif const struct token_name frame_buffer_props[] = { { 2, GL_MAX_VIEWPORT_DIMS, i18n("Max. viewport dimensions") }, { 1, GL_SUBPIXEL_BITS, i18n("Subpixel bits") }, { 1, GL_AUX_BUFFERS, i18n("Aux. buffers")}, {0,0,QString()} }; const struct token_group groups[] = { {KCMGL_SIZE(frame_buffer_props), 0, frame_buffer_props, i18n("Frame buffer properties"), NULL}, {KCMGL_SIZE(various_limits), 0, texture_limits, i18n("Texturing"), NULL}, {KCMGL_SIZE(various_limits), 0, various_limits, i18n("Various limits"), NULL}, {KCMGL_SIZE(float_limits), 0, float_limits, i18n("Points and lines"), NULL}, {KCMGL_SIZE(stack_depth), 0, stack_depth, i18n("Stack depth limits"), NULL}, #ifdef GL_ARB_vertex_program {KCMGL_SIZE(arb_vp), GL_VERTEX_PROGRAM_ARB, arb_vp, "ARB_vertex_program", "GL_ARB_vertex_program"}, #endif #ifdef GL_ARB_fragment_program {KCMGL_SIZE(arb_fp), GL_FRAGMENT_PROGRAM_ARB, arb_fp, "ARB_fragment_program", "GL_ARB_fragment_program"}, #endif #ifdef GL_ARB_vertex_shader {KCMGL_SIZE(arb_vs), 0, arb_vs, "ARB_vertex_shader", "GL_ARB_vertex_shader"}, #endif #ifdef GL_ARB_fragment_shader {KCMGL_SIZE(arb_fs), 0, arb_fs, "ARB_fragment_shader", "GL_ARB_fragment_shader"}, #endif }; #if defined(GLX_ARB_get_proc_address) && defined(PFNGLGETPROGRAMIVARBPROC) if (getProcAddress && strstr(glExtensions, "GL_ARB_vertex_program")) kcm_glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) glXGetProcAddressARB((const GLubyte *)"glGetProgramivARB"); #else Q_UNUSED(getProcAddress); #endif for (uint i = 0; itype; cur_token++) { bool tfloat = cur_token->type & KCMGL_FLOAT; int count = KCMGL_COUNT_MASK(cur_token->type); GLint max[2]={0,0}; GLfloat fmax[2]={0.0,0.0}; #if defined(PFNGLGETPROGRAMIVARBPROC) && defined(GL_ARB_vertex_program) bool tprog = cur_token->type & KCMGL_PROG; if (tprog && kcm_glGetProgramivARB) kcm_glGetProgramivARB(groups[i].type, cur_token->token, max); else #endif if (tfloat) glGetFloatv(cur_token->token, fmax); else glGetIntegerv(cur_token->token, max); if (glGetError() == GL_NONE) { QString s; if (!tfloat && count == 1) s = QString::number(max[0]); else if (!tfloat && count == 2) s = QStringLiteral("%1, %2").arg(max[0]).arg(max[1]); else if (tfloat && count == 2) s = QStringLiteral("%1 - %2").arg(fmax[0],0,'f',6).arg(fmax[1],0,'f',6); else if (tfloat && count == 1) s = QString::number(fmax[0],'f',6); if (l3) l3 = newItem(l2, l3, cur_token->name, s); else l3 = newItem(l2, cur_token->name, s); } } } } #endif static QTreeWidgetItem *print_screen_info(QTreeWidgetItem *l1, QTreeWidgetItem *after, const QString &title) { QTreeWidgetItem *l2 = nullptr, *l3 = nullptr; if (after) { l1 = newItem(l1, after, title); } else { l1 = newItem(l1, title); } if (IsDirect) { if (get_dri_device()) { l2 = newItem(l1, i18n("3D Accelerator")); l2->setExpanded(true); l3 = newItem(l2, l3, i18n("Vendor"), dri_info.vendor); l3 = newItem(l2, l3, i18n("Device"), dri_info.device); l3 = newItem(l2, l3, i18n("Subvendor"), dri_info.subvendor); l3 = newItem(l2, l3, i18n("Revision"), dri_info.rev); } else { l2 = newItem(l1, l2, i18n("3D Accelerator"), i18n("unknown")); } } if (l2) { l2 = newItem(l1, l2, i18n("Driver")); }else{ l2 = newItem(l1, i18n("Driver")); } l2->setExpanded(true); l3 = newItem(l2, i18n("Vendor"), gli.glVendor); l3 = newItem(l2, l3, i18n("Renderer"), gli.glRenderer); #ifdef KCM_ENABLE_OPENGLES l3 = newItem(l2, l3, i18n("OpenGL ES version"), gli.glVersion); #else l3 = newItem(l2, l3, i18n("OpenGL version"), gli.glVersion); #endif if (IsDirect) { if (dri_info.module.isEmpty()) dri_info.module = i18n("unknown"); l3 = newItem(l2, l3, i18n("Kernel module"), dri_info.module); } #ifdef KCM_ENABLE_OPENGLES l3 = newItem(l2, l3, i18n("OpenGL ES extensions")); #else l3 = newItem(l2, l3, i18n("OpenGL extensions")); #endif print_extension_list(gli.glExtensions, l3); #if KCM_HAVE_GLX - if (QGuiApplication::platformName() == QStringLiteral("xcb")) { + if (QGuiApplication::platformName() == QLatin1String("xcb")) { l3 = newItem(l2, l3, i18n("Implementation specific")); print_limits(l3, gli.glExtensions, strstr(gli.clientExtensions, "GLX_ARB_get_proc_address") != nullptr); } #endif return l1; } #if KCM_HAVE_GLX void print_glx_glu(QTreeWidgetItem *l1, QTreeWidgetItem *l2) { QTreeWidgetItem *l3; l2 = newItem(l1, l2, i18n("GLX")); l3 = newItem(l2, i18n("server GLX vendor"), gli.serverVendor); l3 = newItem(l2, l3, i18n("server GLX version"), gli.serverVersion); l3 = newItem(l2, l3, i18n("server GLX extensions")); print_extension_list(gli.serverExtensions, l3); l3 = newItem(l2, l3, i18n("client GLX vendor") ,gli.clientVendor); l3 = newItem(l2, l3, i18n("client GLX version"), gli.clientVersion); l3 = newItem(l2, l3, i18n("client GLX extensions")); print_extension_list(gli.clientExtensions, l3); l3 = newItem(l2, l3, i18n("GLX extensions")); print_extension_list(gli.glxExtensions, l3); l2 = newItem(l1, l2, i18n("GLU")); l3 = newItem(l2, i18n("GLU version"), gli.gluVersion); l3 = newItem(l2, l3, i18n("GLU extensions")); print_extension_list(gli.gluExtensions, l3); } #endif #if KCM_HAVE_EGL void print_egl(QTreeWidgetItem *l1, QTreeWidgetItem *l2) { QTreeWidgetItem *l3; l2 = newItem(l1, l2, i18n("EGL")); l3 = newItem(l2, i18n("EGL Vendor"), gli.eglVendor); l3 = newItem(l2, l3, i18n("EGL Version"), gli.eglVersion); l3 = newItem(l2, l3, i18n("EGL Extensions")); print_extension_list(gli.eglExtensions, l3); } #endif #if KCM_HAVE_GLX static QTreeWidgetItem *get_gl_info_glx(Display *dpy, int scrnum, Bool allowDirect, QTreeWidgetItem *l1, QTreeWidgetItem *after) { Window win; XSetWindowAttributes attr; unsigned long mask; Window root; XVisualInfo *visinfo; int width = 100, height = 100; QTreeWidgetItem *result = after; root = RootWindow(dpy, scrnum); const int attribSingle[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; const int attribDouble[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; GLXContext ctx; visinfo = glXChooseVisual(dpy, scrnum, const_cast(attribSingle)); if (!visinfo) { visinfo = glXChooseVisual(dpy, scrnum, const_cast(attribDouble)); if (!visinfo) { qDebug() << "Error: couldn't find RGB GLX visual\n"; return result; } } attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect ); if (!ctx) { qDebug() << "Error: glXCreateContext failed\n"; XDestroyWindow(dpy, win); XFree(visinfo); return result; } if (glXMakeCurrent(dpy, win, ctx)) { gli.serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR); gli.serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION); gli.serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS); gli.clientVendor = glXGetClientString(dpy, GLX_VENDOR); gli.clientVersion = glXGetClientString(dpy, GLX_VERSION); gli.clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS); gli.glxExtensions = glXQueryExtensionsString(dpy, scrnum); gli.glVendor = (const char *) glGetString(GL_VENDOR); gli.glRenderer = (const char *) glGetString(GL_RENDERER); gli.glVersion = (const char *) glGetString(GL_VERSION); gli.glExtensions = (const char *) glGetString(GL_EXTENSIONS); gli.displayName = nullptr; gli.gluVersion = (const char *) gluGetString(GLU_VERSION); gli.gluExtensions = (const char *) gluGetString(GLU_EXTENSIONS); IsDirect = glXIsDirect(dpy, ctx); result = print_screen_info(l1, after, IsDirect ? i18n("Direct Rendering (GLX)") : i18n("Indirect Rendering (GLX)")); } else { qDebug() << "Error: glXMakeCurrent failed\n"; } glXMakeCurrent(dpy, GL_NONE, nullptr); glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); XFree(visinfo); return result; } #endif #if KCM_HAVE_EGL static QTreeWidgetItem *get_gl_info_egl(Display *dpy, int scrnum, QTreeWidgetItem *l1, QTreeWidgetItem *after) { Window win; XSetWindowAttributes attr; unsigned long mask; Window root; XVisualInfo *visinfo; int width = 100, height = 100; QTreeWidgetItem *result = after; root = RootWindow(dpy, scrnum); static const EGLint attribs[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, EGL_NONE }; static const EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; XVisualInfo visTemplate; int num_visuals; EGLDisplay egl_dpy; EGLSurface surf; EGLContext ctx; EGLConfig config; EGLint num_configs; EGLint vid, major, minor; egl_dpy = eglGetDisplay(dpy); if (!egl_dpy) { qDebug() << "Error: eglGetDisplay() failed\n"; return result; } if (!eglInitialize(egl_dpy, &major, &minor)) { qDebug() << "Error: eglInitialize() failed\n"; return result; } if (!eglChooseConfig(egl_dpy, attribs, &config, 1, &num_configs)) { qDebug() << "Error: couldn't get an EGL visual config\n"; return result; } if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { qDebug() << "Error: eglGetConfigAttrib() failed\n"; return result; } visTemplate.visualid = vid; visinfo = XGetVisualInfo(dpy, VisualIDMask, &visTemplate, &num_visuals); if (!visinfo) { qDebug() << "Error: couldn't get X visual\n"; return result; } attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); #ifdef KCM_ENABLE_OPENGLES eglBindAPI(EGL_OPENGL_ES_API); #else eglBindAPI(EGL_OPENGL_API); #endif ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs); if (!ctx) { qDebug() << "Error: eglCreateContext failed\n"; XDestroyWindow(dpy, win); XFree(visinfo); return result; } surf = eglCreateWindowSurface(egl_dpy, config, win, NULL); if (!surf) { qDebug() << "Error: eglCreateWindowSurface failed\n"; eglDestroyContext(egl_dpy, ctx); XDestroyWindow(dpy, win); XFree(visinfo); return result; } if (eglMakeCurrent(egl_dpy, surf, surf, ctx)) { gli.eglVendor = eglQueryString(egl_dpy, EGL_VENDOR); gli.eglVersion = eglQueryString(egl_dpy, EGL_VERSION); gli.eglExtensions = eglQueryString(egl_dpy, EGL_EXTENSIONS); gli.glVendor = (const char *) glGetString(GL_VENDOR); gli.glRenderer = (const char *) glGetString(GL_RENDERER); gli.glVersion = (const char *) glGetString(GL_VERSION); gli.glExtensions = (const char *) glGetString(GL_EXTENSIONS); gli.displayName = nullptr; result = print_screen_info(l1, after, i18n("Direct Rendering (EGL)")); } else { qDebug() <<"Error: eglMakeCurrent() failed\n"; } eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(egl_dpy, ctx); eglDestroySurface(egl_dpy, surf); XDestroyWindow(dpy, win); XFree(visinfo); return result; } static QTreeWidgetItem *get_gl_info_egl_qt(QTreeWidgetItem *l1, QTreeWidgetItem *after, QSurfaceFormat::OpenGLContextProfile profile, const QString &title) { QTreeWidgetItem *result = after; QOffscreenSurface surface; surface.create(); QOpenGLContext context; QSurfaceFormat format; format.setProfile(profile); context.setFormat(format); if (!context.create()) { qDebug() << "Could not create QOpenGLContext"; return result; } if (context.format().profile() != profile) { qDebug() << "Could not get requested OpenGL profile, requested" << profile << "got" << context.format().profile(); return result; } if (context.makeCurrent(&surface)) { EGLDisplay egl_dpy = eglGetCurrentDisplay(); gli.eglVendor = eglQueryString(egl_dpy, EGL_VENDOR); gli.eglVersion = eglQueryString(egl_dpy, EGL_VERSION); gli.eglExtensions = eglQueryString(egl_dpy, EGL_EXTENSIONS); gli.glVendor = (const char *) glGetString(GL_VENDOR); gli.glRenderer = (const char *) glGetString(GL_RENDERER); gli.glVersion = (const char *) glGetString(GL_VERSION); gli.glExtensions = (const char *) glGetString(GL_EXTENSIONS); gli.displayName = nullptr; result = print_screen_info(l1, after, title); } else { qDebug() <<"Error: eglMakeCurrent() failed\n"; } context.doneCurrent(); return result; } #endif bool GetInfo_OpenGL(QTreeWidget *treeWidget) { QTreeWidgetItem *l1, *l2 = nullptr; - static bool isX11 = QGuiApplication::platformName() == QStringLiteral("xcb"); - static bool isWayland = QGuiApplication::platformName().contains(QStringLiteral("wayland")); + static bool isX11 = QGuiApplication::platformName() == QLatin1String("xcb"); + static bool isWayland = QGuiApplication::platformName().contains(QLatin1String("wayland")); QTreeWidgetItem *header = new QTreeWidgetItem(); header->setText(0, i18n("Information")); header->setText(1, i18n("Value")); treeWidget->setHeaderItem(header); treeWidget->setRootIsDecorated(false); l1 = new QTreeWidgetItem(treeWidget); if (isX11) { char *displayName = nullptr; Display *dpy; int numScreens, scrnum; dpy = XOpenDisplay(displayName); if (!dpy) { // qDebug() << "Error: unable to open display " << displayName; return false; } l1->setText(0, i18n("Name of the Display")); l1->setText(1, QString::fromLatin1(DisplayString(dpy))); l1->setExpanded(true); l1->setFlags(Qt::ItemIsEnabled); numScreens = ScreenCount(dpy); scrnum = 0; #ifdef KCMGL_MANY_SCREENS for (; scrnum < numScreens; scrnum++) #endif { #if KCM_HAVE_GLX mesa_hack(dpy, scrnum); l2 = get_gl_info_glx(dpy, scrnum, true, l1, l2); if (l2) l2->setExpanded(true); #endif #if KCM_HAVE_EGL l2 = get_gl_info_egl(dpy, scrnum, l1, l2); if (l2) l2->setExpanded(true); #endif // TODO print_visual_info(dpy, scrnum, mode); } #if KCM_HAVE_GLX if (l2) print_glx_glu(l1, l2); else KMessageBox::error(0, i18n("Could not initialize OpenGL/GLX")); #endif XCloseDisplay(dpy); } if (isWayland) { IsDirect = true; l1->setText(0, i18n("Name of the Display")); l1->setText(1, QString::fromLatin1(qgetenv("WAYLAND_DISPLAY"))); l1->setExpanded(true); l1->setFlags(Qt::ItemIsEnabled); #if KCM_HAVE_EGL l2 = get_gl_info_egl_qt(l1, l2, QSurfaceFormat::NoProfile, i18n("OpenGL")); if (l2) l2->setExpanded(true); l2 = get_gl_info_egl_qt(l1, l2, QSurfaceFormat::CoreProfile, i18n("Core Profile")); if (l2) l2->setExpanded(true); l2 = get_gl_info_egl_qt(l1, l2, QSurfaceFormat::CompatibilityProfile, i18n("Compatibility Profile")); if (l2) l2->setExpanded(true); #endif } #if KCM_HAVE_EGL if (l2) print_egl(l1, l2); else KMessageBox::error(0, i18n("Could not initialize OpenGL (ES)/EGL ")); #endif treeWidget->resizeColumnToContents(0); treeWidget->resizeColumnToContents(1); return true; } #include "opengl.moc" diff --git a/Modules/pci/kpci.cpp b/Modules/pci/kpci.cpp index 463a888..337556d 100644 --- a/Modules/pci/kpci.cpp +++ b/Modules/pci/kpci.cpp @@ -1,807 +1,807 @@ /* Retrieve information about PCI subsystem through libpci library from pciutils package. This should be possible on Linux, BSD and AIX. This code is based on example.c, lspci.c and pci.ids from pciutils. Device classes, subclasses and programming interfaces are hardcoded here, since there are only few of them, and they are important and should their names be translated. Author: Konrad Rzepecki */ #include "kpci_private.h" //extern "C" is needed to proper linking with libpci extern "C" { #include } #include #include //getuid #include //isxdigit #include //memcpy #include #include static const QString& getNameById(const id2name *const table, int id) { for (int i=0;; i++) { if ((table[i].id==id)||(table[i].id==-1)) { return table[i].name; }//if }//while }//getNameById static const QString& getNameBy2Id(const id3name *const table, int id, int id2) { for (int i=0;; i++) { if (((table[i].id==id)&&(table[i].id2==id2))|| ((table[i].id==id)&&(table[i].id2==-1))|| (table[i].id==-1)) { return table[i].name; }//if }//while }//getNameBy2Id static const QString& getNameBy3Id(const id4name *const table, int id, int id2, int id3) { for (int i=0;; i++) { if (((table[i].id==id)&&(table[i].id2==id2)&&(table[i].id3==id3))|| ((table[i].id==id)&&(table[i].id2==id2)&&(table[i].id3==-1))|| ((table[i].id==id)&&(table[i].id2==-1))|| (table[i].id==-1)) { return table[i].name; }//if }//while }//getNameBy3Id static QTreeWidgetItem* create(QTreeWidgetItem* parent, const QString& title, const QString& value) { QStringList list; list << title << value; return new QTreeWidgetItem(parent, list); } static QTreeWidgetItem* createTitle(QTreeWidgetItem* parent, const QString& title) { QStringList list; list << title; return new QTreeWidgetItem(parent, list); } static QTreeWidgetItem* addDeviceClass(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QString value; QTreeWidgetItem *localAfter=nullptr; after=create(parent, i18n("Device Class"), getNameById(devClass, info->cooked.devClass)+value.sprintf(" (0x%02X)", info->cooked.devClass)); after=create(parent, i18n("Device Subclass"), getNameBy2Id(devSubclass, info->cooked.devClass, info->cooked.devSubClass)+value.sprintf(" (0x%02X)", info->cooked.devSubClass)); after=create(parent, i18n("Device Programming Interface"), getNameBy3Id(devInterface, info->cooked.devClass, info->cooked.devSubClass, info->cooked.devProgIface.devProgIface)+value.sprintf(" (0x%02X)", info->cooked.devProgIface.devProgIface)); if ((info->cooked.devClass==0x01)&&(info->cooked.devSubClass==0x01)) { //programming interface for IDE localAfter=create(after, i18n("Master IDE Device"), (info->cooked.devProgIface.devProgIface_bits.progIdeMaster ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Secondary programmable indicator"), (info->cooked.devProgIface.devProgIface_bits.progSecProgInd ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Secondary operating mode"), (info->cooked.devProgIface.devProgIface_bits.progSecOperMode ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Primary programmable indicator"), (info->cooked.devProgIface.devProgIface_bits.progPriProgInd ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Primary operating mode"), (info->cooked.devProgIface.devProgIface_bits.progPriOperMode ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); }//if return after; }//addDeviceClass static QTreeWidgetItem* addVendor(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, pci_access *PCIAccess) { char nameBuffer[NAME_BUFFER_SIZE]; QString line, value, topname; short int subvendor=0, subdevice=0; bool isVendor=false, isDevice=false, isSub=false; memset((void*)nameBuffer, 0, NAME_BUFFER_SIZE); if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_CARDBUS) { subvendor=info->cooked.header.header2.cbSubVendor; subdevice=info->cooked.header.header2.cbSubDevice; }//if else { subvendor=info->cooked.header.header0.subVendor; subdevice=info->cooked.header.header0.subDevice; }//else //WARNING all pci_lookup_name calls should have 4 extra args for compatibility with older pcilib ! if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, info->cooked.vendor, 0, 0, 0)!=nullptr) { //line.setAscii(nameBuffer); //not work, workaround below line = QString::fromLatin1(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, info->cooked.vendor, 0, 0, 0)); - if (line.contains(QStringLiteral("Unknown"))==0) { + if (line.contains(QLatin1String("Unknown"))==0) { isVendor=true; topname=line; after=create(parent, i18n("Vendor"), line+value.sprintf(" (0x%04X)", info->cooked.vendor)); if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_DEVICE, info->cooked.vendor, info->cooked.device, 0, 0)!=nullptr) { //line.setAscii(nameBuffer); //not work, workaround below line = QString::fromLatin1(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_DEVICE, info->cooked.vendor, info->cooked.device, 0, 0)); - if (line.contains(QStringLiteral("Unknown"))==0) { + if (line.contains(QLatin1String("Unknown"))==0) { isDevice=true; topname+=QStringLiteral(" ")+line; after=create(parent, i18n("Device"), line+value.sprintf(" (0x%04X)", info->cooked.device)); if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE) { isSub=true; }//if else if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_DEVICE|PCI_LOOKUP_SUBSYSTEM, info->cooked.vendor, info->cooked.device, subvendor, subdevice)!=nullptr) { //line.setAscii(nameBuffer); //not work, workaround below line = QString::fromLatin1(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_DEVICE|PCI_LOOKUP_SUBSYSTEM, info->cooked.vendor, info->cooked.device, subvendor, subdevice)); - if (line.contains(QStringLiteral("Unknown"))==0) { + if (line.contains(QLatin1String("Unknown"))==0) { isSub=true; after=create(parent, i18n("Subsystem"), line+value.sprintf(" (0x%04X:0x%04X)", subvendor, subdevice)); }//if }//eliif }//if }//iif }//if }//if if (!isVendor) { after=create(parent, i18n("Vendor"), i18nc(strCtxt, strUnknown)+value.sprintf(" (0x%04X)", info->cooked.vendor)); if (!isDevice) { after=create(parent, i18n("Device"), i18nc(strCtxt, strUnknown)+value.sprintf(" (0x%04X)", info->cooked.device)); }//if topname=i18nc(strCtxt, strUnknown); }//if if ((!isSub)&&(info->cooked.headerType.headerType_bits.headerType!=PCI_HEADER_TYPE_BRIDGE)) { //if entire subsytem was not found, search at least for subvendor if (pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, subvendor, 0, 0, 0)!=nullptr) { //line.setAscii(nameBuffer); //not work, workaround below line = QString::fromLatin1(pci_lookup_name(PCIAccess, nameBuffer, NAME_BUFFER_SIZE, PCI_LOOKUP_VENDOR, subvendor, 0, 0, 0)); - if (line.contains(QStringLiteral("Unknown"))==0) { + if (line.contains(QLatin1String("Unknown"))==0) { after=create(parent, i18n("Subsystem"), line+i18n(" - device:")+value.sprintf(" 0x%04X (0x%04X:0x%04X)", subdevice, subvendor, subdevice)); }//if else { after=create(parent, i18n("Subsystem"), i18nc(strCtxt, strUnknown)+value.sprintf(" (0x%04X:0x%04X)", subvendor, subdevice)); }//else }//if else { after=create(parent, i18n("Subsystem"), i18nc(strCtxt, strUnknown)+value.sprintf(" (0x%04X:0x%04X)", subvendor, subdevice)); }//else }//if parent->setText(1, topname); return after; }//addVendor static QTreeWidgetItem* addInterrupt(QTreeWidgetItem *parent, QTreeWidgetItem *after, int irq, int pin) { QTreeWidgetItem *localAfter=nullptr; QString value; if ((irq!=0)||(pin!=0)) { after=createTitle(parent, i18n("Interrupt")); localAfter=create(after, i18n("IRQ"), value.sprintf("%i", irq)); localAfter=create(after, i18n("Pin"), value.sprintf("%c", (pin==0 ? '?' : 'A'-1+pin))); }//if return after; }//addInterrupt static QTreeWidgetItem* addControl(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; after=create(parent, i18n("Control"), value.sprintf("0x%04X", info->cooked.command.command)); localAfter=create(after, i18n("Response in I/O space"), (info->cooked.command.command_bits.comIo ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Response in memory space"), (info->cooked.command.command_bits.comMemory ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Bus mastering"), (info->cooked.command.command_bits.comMaster ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Response to special cycles"), (info->cooked.command.command_bits.comSpecial ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Memory write and invalidate"), (info->cooked.command.command_bits.comInvalidate ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Palette snooping"), (info->cooked.command.command_bits.comVgaPalette ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Parity checking"), (info->cooked.command.command_bits.comParity ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Address/data stepping"), (info->cooked.command.command_bits.comWait ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("System error"), (info->cooked.command.command_bits.comSerr ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Back-to-back writes"), (info->cooked.command.command_bits.comFastBack ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Interrupt"), (info->cooked.command.command_bits.comInterrupt ? i18nc(strCtxt, strDisabled) : i18nc(strCtxt, strEnabled))); //reverse order is intentional return after; }//addControl static QTreeWidgetItem* addStatus(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; after=create(parent, i18n("Status"), value.sprintf("0x%04X", info->cooked.status.status)); localAfter=create(after, i18n("Interrupt status"), (info->cooked.status.status_bits.statCapList ? i18nc(strCtxt, strEnabled) : i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Capability list"), (info->cooked.status.status_bits.statCapList ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("66 MHz PCI 2.1 bus"), (info->cooked.status.status_bits.stat66MHz ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("User-definable features"), (info->cooked.status.status_bits.statUdf ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Accept fast back-to-back"), (info->cooked.status.status_bits.statFastBack ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Data parity error"), (info->cooked.status.status_bits.statParity ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Device selection timing"), getNameById(devSel, info->cooked.status.status_bits.statDevsel)); localAfter=create(after, i18n("Signaled target abort"), (info->cooked.status.status_bits.statSigTargetAbort ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Received target abort"), (info->cooked.status.status_bits.statRecTargetAbort ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Received master abort"), (info->cooked.status.status_bits.statRecMasterAbort ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Signaled system error"), (info->cooked.status.status_bits.statSigSystemError ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Parity error"), (info->cooked.status.status_bits.statDetectedParity ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); return after; }//addStatus static QTreeWidgetItem* addLatency(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; after=create(parent, i18n("Latency"), value.sprintf("%u", info->cooked.latencyTimer)); if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_NORMAL) { if (info->cooked.header.header0.minGnt==0) { localAfter=create(after, i18n("MIN_GNT"), i18n("No major requirements (0x00)")); }//if else { localAfter=create(after, i18n("MIN_GNT"), value.sprintf("%u ns (0x%02X)", info->cooked.header.header0.minGnt*250, info->cooked.header.header0.minGnt)); }//else if (info->cooked.header.header0.maxLat==0) { localAfter=create(after, i18n("MAX_LAT"), i18n("No major requirements (0x00)")); }//if else { localAfter=create(after, i18n("MAX_LAT"), value.sprintf("%u ns (0x%02X)", info->cooked.header.header0.maxLat*250, info->cooked.header.header0.maxLat)); }//else }//if return after; }//addLatency static QTreeWidgetItem* addHeaderType(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; after=create(parent, i18n("Header"),value.sprintf("0x%02X",info->cooked.headerType.headerTypeFull)); localAfter=create(after, i18n("Type"),getNameById(headerType,info->cooked.headerType.headerType_bits.headerType)+value.sprintf(" (0x%02X)",info->cooked.headerType.headerType_bits.headerType)); localAfter=create(after, i18n("Multifunctional"),(info->cooked.headerType.headerType_bits.multifunctional?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); return after; }//addHeaderType static QTreeWidgetItem* addBist(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; after=create(parent, i18n("Build-in self test"), value.sprintf("0x%02X", info->cooked.bist.bist)); localAfter=create(after, i18n("BIST Capable"), (info->cooked.bist.bist_bits.bistCapable ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); if (info->cooked.bist.bist_bits.bistCapable==1) { localAfter=create(after, i18n("BIST Start"), (info->cooked.bist.bist_bits.bistStart ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Completion code"), value.sprintf("0x%01X", info->cooked.bist.bist_bits.bistCode)); }//if return after; }//addBist static QTreeWidgetItem* addSize(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciaddr_t size) { if (size<0x400) { after=create(parent, i18n("Size"), QStringLiteral("%1 B").arg(static_cast(size))); }//if else if (size<0x100000) { after=create(parent, i18n("Size"), QStringLiteral("%1 kiB").arg(static_cast(size/0x400))); }//elif else if (size<0x40000000) { after=create(parent, i18n("Size"), QStringLiteral("%1 MiB").arg(static_cast(size/0x100000))); }//elif #ifdef HAVE_PCIADDR_T64 else if (size<0x10000000000LL) { after=create(parent, i18n("Size"),QStringLiteral("%1 GiB").arg(static_cast(size/0x40000000))); }//elif else if (size<0x4000000000000LL) { after=create(parent, i18n("Size"),QStringLiteral("%1 PiB").arg(static_cast(size/0x10000000000LL))); }//elif else if (size<0x1000000000000000LL) { after=create(parent, i18n("Size"),QStringLiteral("%1 EiB").arg(static_cast(size/0x4000000000000LL))); }//elif #else //HAVE_PCIADDR_T64 else { after=create(parent, i18n("Size"), QStringLiteral("%1 GiB").arg(static_cast(size/0x40000000))); }//else #endif //HAVE_PCIADDR_T64 return after; }//addSize static QTreeWidgetItem* addMapping(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, pci_dev* PCIDevice) { QTreeWidgetItem *localAfter=nullptr; QTreeWidgetItem *topLocalAfter=nullptr; QString value; bool is64b=false; after=createTitle(parent, i18n("Address mappings")); for (int i=0; i<6; i++) { if (((info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE)&&(i>1))||((info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_CARDBUS)&&(i>0))) { break; }//if if (is64b) { //skip one range continue; }//if topLocalAfter=createTitle(after, i18n("Mapping %1", i)); localAfter=create(topLocalAfter, i18n("Space"), (info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressMap ? i18n("I/O") : i18n("Memory"))); if (info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressMap==0) { //memory only localAfter=create(topLocalAfter, i18n("Type"), getNameById(mappingType, info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressType)); localAfter=create(topLocalAfter, i18n("Prefetchable"), (info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressPref ? i18nc(strCtxt, strYes) : i18nc(strCtxt, strNo))); }//if if (is64b) { //there is no long long support in Qt so we need compose value topLocalAfter->setText(1, value.sprintf("0x%08X%08X", info->cooked.header.header0.mapping[i+1].baseAddress, info->cooked.header.header0.mapping[i].baseAddress)); if (info->cooked.header.header0.mapping[i+1].baseAddress==0) { //no top 4 bytes if ((info->cooked.header.header0.mapping[i].baseAddress&(~(info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressMap ? 0x3 : 0xF)))==0) { //no address at all localAfter=create(topLocalAfter, i18n("Address"), i18nc("unassigned address", "Unassigned")); localAfter=create(topLocalAfter, i18n("Size"), i18nc("unassigned size", "Unassigned")); }//if else { localAfter=create(topLocalAfter, i18n("Address"), value.sprintf("0x%X", (info->cooked.header.header0.mapping[i].baseAddress&(~(info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressMap ? 0x3 : 0xF))))); localAfter=addSize(topLocalAfter, localAfter, PCIDevice->size[i]); }//else }//if else { localAfter=create(topLocalAfter, i18n("Address"), value.sprintf("0x%X%08X", info->cooked.header.header0.mapping[i+1].baseAddress, (~(info->cooked.header.header0.mapping[i].baseAddress&(info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressMap ? 0x3 : 0xF))))); localAfter=addSize(topLocalAfter, localAfter, PCIDevice->size[i]); }//else }//if else { topLocalAfter->setText(1, value.sprintf("0x%08X", info->cooked.header.header0.mapping[i].baseAddress)); if ((info->cooked.header.header0.mapping[i].baseAddress&(~(info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressMap ? 0x3 : 0xF)))==0) { //no address at all localAfter=create(topLocalAfter, i18n("Address"), i18nc("unassigned address", "Unassigned")); localAfter=create(topLocalAfter, i18n("Size"), i18nc("unassigned size", "Unassigned")); }//if else { localAfter=create(topLocalAfter, i18n("Address"), value.sprintf("0x%X", (info->cooked.header.header0.mapping[i].baseAddress&(~(info->cooked.header.header0.mapping[i].baseAddress_bits.baseAddressMap ? 0x3 : 0xF))))); localAfter=addSize(topLocalAfter, localAfter, PCIDevice->size[i]); }//else }//else }//for return after; }//addMapping static QTreeWidgetItem* addBus(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE) { after=createTitle(parent, i18n("Bus")); localAfter=create(after, i18n("Primary bus number"), value.sprintf("0x%02X", info->cooked.header.header1.primaryBus)); localAfter=create(after, i18n("Secondary bus number"), value.sprintf("0x%02X", info->cooked.header.header1.secondaryBus)); localAfter=create(after, i18n("Subordinate bus number"), value.sprintf("0x%02X", info->cooked.header.header1.subordinateBus)); localAfter=create(after, i18n("Secondary latency timer"), value.sprintf("0x%02X", info->cooked.header.header1.secLatencyTimer)); }//if else if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_CARDBUS) { //should be checked after=createTitle(parent, i18n("Bus")); localAfter=create(after, i18n("Primary bus number"), value.sprintf("0x%02X", info->cooked.header.header2.cbPrimaryBus)); localAfter=create(after, i18n("CardBus number"), value.sprintf("0x%02X", info->cooked.header.header2.cbCardBus)); localAfter=create(after, i18n("Subordinate bus number"), value.sprintf("0x%02X", info->cooked.header.header2.cbSubordinateBus)); localAfter=create(after, i18n("CardBus latency timer"), value.sprintf("0x%02X", info->cooked.header.header2.cbLatencyTimer)); }//elif return after; }//addBus static QTreeWidgetItem* addSecStatus(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE) { after=create(parent, i18n("Secondary status"), value.sprintf("0x%04X", info->cooked.header.header1.secStatus.secStatus)); localAfter=create(after, i18n("Interrupt status"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatCapList?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Capability list"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatCapList?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("66 MHz PCI 2.1 bus"),(info->cooked.header.header1.secStatus.secStatus_bits.secStat66MHz?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("User-definable features"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatUdf?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Accept fast back-to-back"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatFastBack?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Data parity error"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatParity?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Device selection timing"),getNameById(devSel,info->cooked.header.header1.secStatus.secStatus_bits.secStatDevsel)); localAfter=create(after, i18n("Signaled target abort"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatSigTargetAbort?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Received target abort"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatRecTargetAbort?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Received master abort"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatRecMasterAbort?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Signaled system error"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatSigSystemError?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Parity error"),(info->cooked.header.header1.secStatus.secStatus_bits.secStatDetectedParity?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); }//if else if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_CARDBUS) { //should be checked after=create(parent,i18n("Secondary status"),value.sprintf("0x%04X",info->cooked.header.header2.cbSecStatus.cbSecStatus)); localAfter=create(after, i18n("Interrupt status"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatCapList?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Capability list"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatCapList?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("66 MHz PCI 2.1 bus"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStat66MHz?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("User-definable features"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatUdf?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Accept fast back-to-back"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatFastBack?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Data parity error"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatParity?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Device selection timing"),getNameById(devSel,info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatDevsel)); localAfter=create(after, i18n("Signaled target abort"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatSigTargetAbort?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Received target abort"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatRecTargetAbort?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Received master abort"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatRecMasterAbort?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Signaled system error"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatSigSystemError?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Parity error"),(info->cooked.header.header2.cbSecStatus.cbSecStatus_bits.cbSecStatDetectedParity?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); }//elif return after; }//addSecStatus static QTreeWidgetItem* addBridgeBehind(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE) { after=createTitle(parent, i18n("I/O behind bridge")); localAfter=create(after, i18n("32-bit"),(info->cooked.header.header1.ioBase.ioBase_bits.ioBaseType?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); if (info->cooked.header.header1.ioBase.ioBase_bits.ioBaseType==0) { localAfter=create(after, i18n("Base"),value.sprintf("0x%04X",info->cooked.header.header1.ioBase.ioBase&0xFFF0)); localAfter=create(after, i18n("Limit"),value.sprintf("0x%04X",info->cooked.header.header1.ioLimit|0x0F)); }//if else { localAfter=create(after, i18n("Base"),value.sprintf("0x%04X%04X",info->cooked.header.header1.ioBaseUpper16,info->cooked.header.header1.ioBase.ioBase&0xFFF0)); localAfter=create(after, i18n("Limit"),value.sprintf("0x%04X%04X",info->cooked.header.header1.ioLimitUpper16,info->cooked.header.header1.ioLimit|0x0F)); }//else after=createTitle(parent, i18n("Memory behind bridge")); localAfter=create(after, i18n("Base"),value.sprintf("0x%08X",(info->cooked.header.header1.memoryBase.memoryBase<<16)&0xFFFFFFF0)); localAfter=create(after, i18n("Limit"),value.sprintf("0x%08X",(info->cooked.header.header1.memoryLimit<<16)|0x0FFFFF)); after=createTitle(parent, i18n("Prefetchable memory behind bridge")); localAfter=create(after, i18n("64-bit"),(info->cooked.header.header1.ioBase.ioBase_bits.ioBaseType?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); if (info->cooked.header.header1.ioBase.ioBase_bits.ioBaseType==0) { localAfter=create(after, i18n("Base"),value.sprintf("0x%08X",(info->cooked.header.header1.prefMemoryBase.prefMemoryBase<<16)&0xFFFFFFF0)); localAfter=create(after, i18n("Limit"),value.sprintf("0x%08X",(info->cooked.header.header1.prefMemoryLimit<<16)|0x0FFFFF)); }//if else { localAfter=create(after, i18n("Base"),value.sprintf("0x%08X%08X",info->cooked.header.header1.prefBaseUpper32,(info->cooked.header.header1.prefMemoryBase.prefMemoryBase<<16)&0xFFFFFFF0)); localAfter=create(after, i18n("Limit"),value.sprintf("0x%0x8X%08X",info->cooked.header.header1.prefLimitUpper32,(info->cooked.header.header1.prefMemoryLimit<<16)|0x0FFFFF)); }//else }//if return after; }//addBridgeBechind static QTreeWidgetItem* addBridgeControl(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE) { after=create(parent, i18n("Bridge control"),value.sprintf("0x%04X",info->cooked.header.header1.bridgeControl.bridgeControl)); localAfter=create(after, i18n("Secondary parity checking"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlParity?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Secondary system error"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlSerr?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("ISA ports forwarding"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlIsa?i18nc(strCtxt, strDisabled):i18nc(strCtxt, strEnabled))); //reverse order is intentional localAfter=create(after, i18n("VGA forwarding"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlVga?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Master abort"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlMasterAbort?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Secondary bus reset"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlBusReset?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Secondary back-to-back writes"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlFastBack?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Primary discard timer counts"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlPriDisTim?i18n("2e10 PCI clocks"):i18n("2e15 PCI clocks"))); localAfter=create(after, i18n("Secondary discard timer counts"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlSecDisTim?i18n("2e10 PCI clocks"):i18n("2e15 PCI clocks"))); localAfter=create(after, i18n("Discard timer error"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlDisTimStat?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Discard timer system error"),(info->cooked.header.header1.bridgeControl.bridgeControl_bits.bridgeControlDisTimeSerr?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); }//if return after; }//addBridgeControl static QTreeWidgetItem* addRom(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, pci_dev* PCIDevice) { QTreeWidgetItem *localAfter=nullptr; QString value; if ((info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_NORMAL)||(info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE)) { after=createTitle(parent, i18n("Expansion ROM")); localAfter=create(after, i18n("Status"),(info->cooked.header.header0.romAddress.romAddress_bits.romEnabled?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); if (PCIDevice->rom_base_addr==0) { //no address at all localAfter=create(after, i18n("Address"),i18nc("unassigned address", "Unassigned")); localAfter=create(after, i18n("Size"),i18nc("unassigned size", "Unassigned")); }//if else { localAfter=create(after, i18n("Address"),value.sprintf("0x%X",static_cast(PCIDevice->rom_base_addr))); localAfter=addSize(after, localAfter, PCIDevice->rom_size); }//else }//if return after; }//addRom static QTreeWidgetItem* addCardbusResource(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QTreeWidgetItem *topLocalAfter=nullptr; QString value; int pref=0; if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_CARDBUS) { after=createTitle(parent, i18n("Memory windows")); for (int i=0; i<2; i++) { pref=(i ? info->cooked.header.header2.cbControl.cbControl_bits.cbControlPref1 : info->cooked.header.header2.cbControl.cbControl_bits.cbControlPref0); topLocalAfter=createTitle(after, i18n("Window %1", i)); localAfter=create(topLocalAfter, i18n("Prefetchable"),(pref?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(topLocalAfter, i18n("Base"),value.sprintf("0x%08X",info->cooked.header.header2.cbMemory[i].cbMemoryBase)); localAfter=create(topLocalAfter, i18n("Limit"),value.sprintf("0x%08X",info->cooked.header.header2.cbMemory[i].cbMemoryLimit)); }//for after=createTitle(parent, i18n("I/O windows")); for (int i=0; i<2; i++) { topLocalAfter=createTitle(after, i18n("Window %1", i)); localAfter=create(topLocalAfter, i18n("Type"),(info->cooked.header.header2.cbIo[i].cbIoBase.cbIoBase_bits.cbIoBaseType?i18n("32-bit"):i18n("16-bit"))); if (info->cooked.header.header2.cbIo[i].cbIoBase.cbIoBase_bits.cbIoBaseType==1) { localAfter=create(topLocalAfter, i18n("Base"),value.sprintf("0x%08X",info->cooked.header.header2.cbIo[i].cbIoBase.cbIoBase&0xFFFFFFFC)); localAfter=create(topLocalAfter, i18n("Limit"),value.sprintf("0x%08X",info->cooked.header.header2.cbIo[i].cbIoLimit|0x03)); }//if else { localAfter=create(topLocalAfter, i18n("Base"),value.sprintf("0x%04X",info->cooked.header.header2.cbIo[i].cbIoBase.cbIoBase&0xFFFC)); localAfter=create(topLocalAfter, i18n("Limit"),value.sprintf("0x%04X",(info->cooked.header.header2.cbIo[i].cbIoLimit&0xFFFF)|0x03)); }//else }//for after=create(parent, i18n("16-bit legacy interface ports"),value.sprintf("0x%04X",info->cooked.header.header2.cbLegacyModeBase)); }//if return after; }//addCardbusResource static QTreeWidgetItem* addCardbusControl(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value; if (info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_CARDBUS) { after=create(parent, i18n("CardBus control"),value.sprintf("0x%04X",info->cooked.header.header2.cbControl.cbControl)); localAfter=create(after, i18n("Secondary parity checking"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlParity?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Secondary system error"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlSerr?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("ISA ports forwarding"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlIsa?i18nc(strCtxt, strDisabled):i18nc(strCtxt, strEnabled))); //reverse order is intentional localAfter=create(after, i18n("VGA forwarding"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlVga?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Master abort"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlMasterAbort?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Interrupts for 16-bit cards"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControl16Int?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Window 0 prefetchable memory"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlPref0?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Window 1 prefetchable memory"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlPref1?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Post writes"),(info->cooked.header.header2.cbControl.cbControl_bits.cbControlPostWrites?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); }//if return after; }//addCardbusControl static QTreeWidgetItem* addRaw(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QString value, temp; after=createTitle(parent, i18n("Raw PCI config space")); for (int i=0; i<(getuid()==0 ? 16 : 4); i++) { for (int j=0; j<16; j++) { if (j!=0) { value+=temp.sprintf(" %02X", info->raw[i*16+j]); }//if else { value.sprintf("%02X", info->raw[i*16+j]); }//if }//for localAfter=create(after, temp.sprintf("0x%02X:",i*16),value); }//for return after; }//addRaw static QTreeWidgetItem* addCapsPm(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) { QTreeWidgetItem *localAfter=nullptr; QTreeWidgetItem *subLocalAfter=nullptr; QString value; pmInfo infoPm; if ((offset+2+sizeof(pmInfo))<256) { memcpy(reinterpret_cast(&infoPm.raw[0]), reinterpret_cast(&info->raw[offset+2]), sizeof(pmInfo)); after=create(parent, i18n("Capabilities"),value.sprintf("0x%04X",infoPm.cooked.caps.caps)); localAfter=create(after, i18n("Version"),QString::number(infoPm.cooked.caps.caps_bits.capsVer)); localAfter=create(after, i18n("Clock required for PME generation"),(infoPm.cooked.caps.caps_bits.capsClock?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Device-specific initialization required"),(infoPm.cooked.caps.caps_bits.capsDsi?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); localAfter=create(after, i18n("Maximum auxiliary current required in D3 cold"),getNameById(auxCur,infoPm.cooked.caps.caps_bits.capsAuxCur)); localAfter=create(after, i18n("D1 support"),(infoPm.cooked.caps.caps_bits.capsD1Supp?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("D2 support"),(infoPm.cooked.caps.caps_bits.capsD2Supp?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=createTitle(after, i18n("Power management events")); subLocalAfter=create(localAfter, i18n("D0"),(infoPm.cooked.caps.caps_bits.capsPmeD0?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); subLocalAfter=create(localAfter, i18n("D1"),(infoPm.cooked.caps.caps_bits.capsPmeD1?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); subLocalAfter=create(localAfter, i18n("D2"),(infoPm.cooked.caps.caps_bits.capsPmeD2?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); subLocalAfter=create(localAfter, i18n("D3 hot"),(infoPm.cooked.caps.caps_bits.capsPmeD3hot?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); subLocalAfter=create(localAfter, i18n("D3 cold"),(infoPm.cooked.caps.caps_bits.capsPmeD3cold?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=nullptr; after=create(parent, i18n("Status"),value.sprintf("0x%04X",infoPm.cooked.status.status)); localAfter=create(after, i18n("Power state"),getNameById(powerState,infoPm.cooked.status.status_bits.statPower)); localAfter=create(after, i18n("Power management"),(infoPm.cooked.status.status_bits.statPme?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Data select"),QString::number(infoPm.cooked.status.status_bits.statDataSelect)); localAfter=create(after, i18n("Data scale"),QString::number(infoPm.cooked.status.status_bits.statDataScale)); localAfter=create(after, i18n("Power management status"),(infoPm.cooked.status.status_bits.statPmeStat?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); if ((info->cooked.devClass==0x06)&&(info->cooked.devSubClass==0x04)) { //PCI bridge subLocalAfter=nullptr; localAfter=create(after, i18n("Bridge status"),value.sprintf("0x%02X",infoPm.cooked.statusBridge.statusBridge)); subLocalAfter=create(localAfter, i18n("Secondary bus state in D3 hot"),(infoPm.cooked.statusBridge.statusBridge_bits.statBridgeBx?i18n("B2"):i18n("B3"))); subLocalAfter=create(localAfter, i18n("Secondary bus power & clock control"),(infoPm.cooked.statusBridge.statusBridge_bits.statBridgeClock?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); }//if }//if after=create(parent, i18n("Data"),value.sprintf("0x%02X",infoPm.cooked.data)); return after; }//addCapsPm static QTreeWidgetItem* addCapsAgp(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) { QTreeWidgetItem *localAfter=nullptr; QString value; agpInfo infoAgp; int i, cycleSize; if ((offset+2+sizeof(agpInfo))<256) { memcpy(reinterpret_cast(&infoAgp.raw[0]), reinterpret_cast(&info->raw[offset+2]), sizeof(agpInfo)); //after=create(parent, i18n("Revision"),value.sprintf("%i.%i",infoAgp.revMaior,infoAgp.revMinor)); after=create(parent, i18n("Revision"),QStringLiteral("%1.%2").arg(infoAgp.cooked.revision.revMaior).arg(infoAgp.cooked.revision.revMinor)); after=create(parent, i18n("Status"),value.sprintf("0x%08X",infoAgp.cooked.status.status)); localAfter=create(after, i18n("Rate"),getNameById(agpRate,infoAgp.cooked.status.status_bits0.statusEnhRate)); localAfter=create(after, i18n("AGP 3.0 mode"),(infoAgp.cooked.status.status_bits1.statusMode?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Fast Writes"),(infoAgp.cooked.status.status_bits1.statusFastWrite?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Address over 4 GiB"),(infoAgp.cooked.status.status_bits1.statusOver4gb?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); if (infoAgp.cooked.status.status_bits1.statusMode==1) { localAfter=create(after, i18n("Translation of host processor access"),(infoAgp.cooked.status.status_bits1.statusHtrans?i18nc(strCtxt, strDisabled):i18nc(strCtxt, strEnabled))); //reverse order is intentional localAfter=create(after, i18n("64-bit GART"),(infoAgp.cooked.status.status_bits1.statusGart64b?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Cache Coherency"),(infoAgp.cooked.status.status_bits1.statusItaCoh?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); }//if localAfter=create(after, i18n("Side-band addressing"),(infoAgp.cooked.status.status_bits1.statusSba?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); if (infoAgp.cooked.status.status_bits1.statusMode==1) { localAfter=create(after, i18n("Calibrating cycle"),getNameById(calCycle,infoAgp.cooked.status.status_bits1.statusCalCycle)); for (i=0, cycleSize=1; i<(infoAgp.cooked.status.status_bits1.statusOptReqSize+4); i++) { cycleSize*=2; }//for localAfter=create(after, i18n("Optimum asynchronous request size"),value.sprintf("%i (0x%02X)",cycleSize,infoAgp.cooked.status.status_bits1.statusOptReqSize)); localAfter=create(after, i18n("Isochronous transactions"),(infoAgp.cooked.status.status_bits1.statusIsochSupp?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); }//if localAfter=create(after, i18n("Maximum number of AGP command"),value.sprintf("%i (0x%02X)",infoAgp.cooked.status.status_bits1.statusReq+1,infoAgp.cooked.status.status_bits1.statusReq)); localAfter=nullptr; after=create(parent, i18n("Configuration"),value.sprintf("0x%08X",infoAgp.cooked.config.config)); localAfter=create(after, i18n("Rate"),getNameById(agpRate,infoAgp.cooked.config.config_bits0.configEnhRate)); localAfter=create(after, i18n("Fast Writes"),(infoAgp.cooked.config.config_bits1.configFastWrite?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); if (infoAgp.cooked.status.status_bits1.statusMode==1) { localAfter=create(after, i18n("Address over 4 GiB"),(infoAgp.cooked.config.config_bits1.configOver4gb?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("64-bit GART"),(infoAgp.cooked.config.config_bits1.configGart64b?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); }//if localAfter=create(after, i18n("AGP"),(infoAgp.cooked.config.config_bits1.configAgp?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Side-band addressing"),(infoAgp.cooked.config.config_bits1.configSba?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); if (infoAgp.cooked.status.status_bits1.statusMode==1) { localAfter=create(after, i18n("Calibrating cycle"),getNameById(calCycle,infoAgp.cooked.config.config_bits1.configCalCycle)); for (i=0, cycleSize=1; i<(infoAgp.cooked.config.config_bits1.configOptReqSize+4); i++) { cycleSize*=2; }//for localAfter=create(after, i18n("Optimum asynchronous request size"),value.sprintf("%i (0x%02X)",cycleSize,infoAgp.cooked.config.config_bits1.configOptReqSize)); }//if localAfter=create(after, i18n("Maximum number of AGP command"),value.sprintf("%i (0x%02X)",infoAgp.cooked.config.config_bits1.configReq+1,infoAgp.cooked.config.config_bits1.configReq)); }//if return after; }//addCapsAgp static QTreeWidgetItem* addCapsVpd(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) { QString value; vpdInfo infoVpd; if ((offset+2+sizeof(vpdInfo))<256) { memcpy(reinterpret_cast(&infoVpd.raw[0]), reinterpret_cast(&info->raw[offset+2]), sizeof(vpdInfo)); after=create(parent, i18n("Data address"),value.sprintf("0x%04X",infoVpd.cooked.vpdAddress)); after=create(parent, i18n("Transfer completed"),(infoVpd.cooked.vpdTransfer?i18nc(strCtxt, strYes):i18nc(strCtxt, strNo))); after=create(parent, i18n("Data"),value.sprintf("0x%08X",infoVpd.cooked.vpdData)); }//if return after; }//addCapsVpd static QTreeWidgetItem* addCapsMsi(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) { QTreeWidgetItem *localAfter=nullptr; QString value; msiInfo infoMsi; int size=10; if ((offset+4)<256) { //copy control only (for now) memcpy(reinterpret_cast(&infoMsi.raw[0]), reinterpret_cast(&info->raw[offset+2]), 2); after=create(parent, i18n("Message control"),value.sprintf("0x%04X",infoMsi.cooked.msiControl.msiControl)); localAfter=create(after, i18n("Message signaled interrupts"),(infoMsi.cooked.msiControl.msiControl_bits.msiEnable?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Multiple message capable"),getNameById(multipleMessage,infoMsi.cooked.msiControl.msiControl_bits.msiMmCapable)); localAfter=create(after, i18n("Multiple message enable"),getNameById(multipleMessage,infoMsi.cooked.msiControl.msiControl_bits.msiMmEnable)); localAfter=create(after, i18n("64-bit address"),(infoMsi.cooked.msiControl.msiControl_bits.msi64bit?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); localAfter=create(after, i18n("Per vector masking"),(infoMsi.cooked.msiControl.msiControl_bits.msiPerVector?i18nc(strCtxt, strEnabled):i18nc(strCtxt, strDisabled))); size+=(infoMsi.cooked.msiControl.msiControl_bits.msi64bit ? 4 : 0)+(infoMsi.cooked.msiControl.msiControl_bits.msiPerVector ? 8 : 0); if ((offset+size)<256) { //copy all MSI data memcpy(reinterpret_cast(&infoMsi.raw[0]), reinterpret_cast(&info->raw[offset+size]), 2); if (infoMsi.cooked.msiControl.msiControl_bits.msi64bit==1) { after=create(parent, i18n("Address"),value.sprintf("0x%08X%08X",infoMsi.cooked.payload.address.msiUpperAddress,infoMsi.cooked.msiAddress)); after=create(parent, i18n("Data"),value.sprintf("0x%04X",infoMsi.cooked.payload.address.msiData64)); if (infoMsi.cooked.msiControl.msiControl_bits.msiPerVector==1) { after=create(parent, i18n("Mask"),value.sprintf("0x%08X",infoMsi.cooked.payload.address.msiMask64)); after=create(parent, i18n("Pending"),value.sprintf("0x%08X",infoMsi.cooked.payload.address.msiPending64)); }//if }//if else { after=create(parent, i18n("Address"),value.sprintf("0x%08X",infoMsi.cooked.msiAddress)); after=create(parent, i18n("Data"),value.sprintf("0x%04X",infoMsi.cooked.payload.data.msiData)); if (infoMsi.cooked.msiControl.msiControl_bits.msiPerVector==1) { after=create(parent, i18n("Mask"),value.sprintf("0x%08X",infoMsi.cooked.payload.data.msiMask)); after=create(parent, i18n("Pending"),value.sprintf("0x%08X",infoMsi.cooked.payload.data.msiPending)); }//if }//else }//if }//if return after; }//addCapsMsi static QTreeWidgetItem* addCapsVendor(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info, int offset) { QString value, temp; after=create(parent, i18n("Length"),value.sprintf("0x%02X",info->raw[offset+2])); if ((offset+3)<256) { //check partial size if (info->raw[offset+2]<=2) { after=create(parent, i18n("Data"),i18nc("no data", "None")); }//if else { if ((offset+info->raw[offset+2])<256) { //check full size for (int i=3; i<(info->raw[offset+2]); i++) { if (i!=3) { value+=temp.sprintf(" 0x%02X", info->raw[offset+i]); }//if else { value.sprintf("0x%02X", info->raw[offset+i]); }//if }//for after=create(parent, i18n("Data"),value); }//if }//else }//if return after; }//addCapsVendor static QTreeWidgetItem* addCaps(QTreeWidgetItem *parent, QTreeWidgetItem *after, pciInfo *info) { QTreeWidgetItem *localAfter=nullptr; QTreeWidgetItem *topLocalAfter=nullptr; QString value; unsigned char offset; if ((info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_NORMAL)||(info->cooked.headerType.headerType_bits.headerType==PCI_HEADER_TYPE_BRIDGE)) { if ((info->cooked.header.header0.capabilityList!=0)&&(info->cooked.status.status_bits.statCapList!=0)) { after=create(parent, i18n("Capabilities"),value.sprintf("0x%02X",info->cooked.header.header0.capabilityList)); if (getuid()==0) { for (offset=info->cooked.header.header0.capabilityList; offset!=0; offset=info->raw[offset+1]) { topLocalAfter=create(after, getNameById(capNames,info->raw[offset]),value.sprintf("0x%02X",info->raw[offset])); localAfter=create(topLocalAfter, i18n("Next"),(info->raw[offset+1]==0?i18n("0x00 (None)"):value.sprintf("0x%02X",info->raw[offset+1]))); switch (info->raw[offset]) { case 0x01: //Power Managemet addCapsPm(topLocalAfter, localAfter, info, offset); break; case 0x02: //AGP addCapsAgp(topLocalAfter, localAfter, info, offset); break; case 0x03: //VPD addCapsVpd(topLocalAfter, localAfter, info, offset); break; case 0x05: //MSI addCapsMsi(topLocalAfter, localAfter, info, offset); break; case 0x09: //vendor specific addCapsVendor(topLocalAfter, localAfter, info, offset); break; default: break; }//switch }//for }//if else { topLocalAfter=createTitle(after, i18n("Root only")); }//else }//if else { after=create(parent, i18n("Capabilities"),i18n("0x00 (None)")); }//else }//if return after; }//addCaps bool GetInfo_PCIUtils(QTreeWidget* tree) { QStringList headers; headers << i18n("Information") << i18n("Value"); tree->setHeaderLabels(headers); tree->setRootIsDecorated(true); pci_access *PCIAccess=nullptr; pci_dev *PCIDevice=nullptr; //init libpci PCIAccess=pci_alloc(); if (PCIAccess==nullptr) { return false; }//if pci_init(PCIAccess); pci_scan_bus(PCIAccess); QTreeWidgetItem *DeviceName=nullptr, *after=nullptr; QString value; pciInfo info; //proces all devices for (PCIDevice=PCIAccess->devices; PCIDevice; PCIDevice=PCIDevice->next) { //get PCI data pci_fill_info(PCIDevice, PCI_FILL_IDENT|PCI_FILL_IRQ|PCI_FILL_BASES|PCI_FILL_ROM_BASE|PCI_FILL_SIZES); if (getuid()==0) { pci_read_block(PCIDevice, 0, info.raw, 256); }//if else { pci_read_block(PCIDevice, 0, info.raw, 64); }//else QStringList deviceList; deviceList << value.sprintf("%02X:%02X.%d", PCIDevice->bus, PCIDevice->dev, PCIDevice->func); //create device tree DeviceName=new QTreeWidgetItem(tree, deviceList); //adding class, subclass and programming interface info after=addDeviceClass(DeviceName, nullptr, &info); //adding revision after=create(DeviceName, i18n("Revision"), value.sprintf("0x%02X", info.cooked.revision)); //adding vendor, device, and subvendor/sudevice info after=addVendor(DeviceName, after, &info, PCIAccess); //adding control after=addControl(DeviceName, after, &info); //adding status after=addStatus(DeviceName, after, &info); //adding cache line size after=create(DeviceName, i18n("Cache line size"), value.sprintf("0x%02X", info.cooked.cacheLineSize)); //adding latency after=addLatency(DeviceName, after, &info); //adding header type after=addHeaderType(DeviceName, after, &info); //adding BIST after=addBist(DeviceName, after, &info); //adding address mapping after=addMapping(DeviceName, after, &info, PCIDevice); //adding bus info after=addBus(DeviceName, after, &info); //adding secondary status after=addSecStatus(DeviceName, after, &info); //adding resourece behind bridge after=addBridgeBehind(DeviceName, after, &info); //adding bridge control after=addBridgeControl(DeviceName, after, &info); //adding cardbus resource after=addCardbusResource(DeviceName, after, &info); //adding cardbus control after=addCardbusControl(DeviceName, after, &info); //adding ROM after=addRom(DeviceName, after, &info, PCIDevice); //adding capabilities after=addCaps(DeviceName, after, &info); //adding interrupt info (IRQ, pin) after=addInterrupt(DeviceName, after, PCIDevice->irq, info.cooked.header.header0.interruptPin); //PCI data have wrong IRQ ?!? //add raw PCI config data after=addRaw(DeviceName, after, &info); }//for pci_cleanup(PCIAccess); return true; }//GetInfo_PCIUtils