freebsd-ports/x11/kde4-workspace/files/patch-usbview
Alonso Schaich 63ff0b60db Update KDE SC to 4.14.3
The kde@ team presents KDE SC 4.14.3, the last planed release
of the KDE SC 4 series.

In addition to the updates provided by the KDE SC developers, this
update also addresses numerous FreeBSD and PORTS specific
issues, found and solved by the kde@ team and area51 testers,
most notorously Tobias C. Berner <tcberner@gmail.com>

PR:		197751
PR:		197871
PR:		184996
Reviewed by:	rakuco (mentor)
Differential:	https://reviews.freebsd.org/D1950
2015-03-11 23:11:47 +00:00

493 lines
14 KiB
Text

Use libusb-1 to query info about usb devices on all platforms, leave old
method as a fallback for Linux only.
Remove *BSD specific code, it doesn't work on FreeBSD 8.x and greater.
Old code probably works on NetBSD, but let it use libusb-1 as well.
Use DeviceNotifier instead of polling.
--- /dev/null
+++ cmake/modules/FindLibUSB1.cmake
@@ -0,0 +1,21 @@
+# - Try to find libusb v1.0 library
+# Once done this defines
+#
+# LIBUSB1_FOUND - system has libusb
+# LIBUSB1_INCLUDE_DIR - libusb include directory
+# LIBUSB1_LIBRARY - libusb library
+
+find_package(PkgConfig)
+pkg_check_modules(PC_LIBUSB1 QUIET libusb-1.0)
+
+find_path(LIBUSB1_INCLUDE_DIR libusb.h
+ HINTS ${PC_LIBUSB1_INCLUDEDIR} ${PC_LIBUSB1_INCLUDE_DIRS})
+
+# On FreeBSD libusb provides both v0.1 and v1.0 API
+find_library(LIBUSB1_LIBRARY NAMES usb-1.0 usb
+ HINTS ${PC_LIBUSB1_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LIBUSB1 DEFAULT_MSG LIBUSB1_LIBRARY LIBUSB1_INCLUDE_DIR)
+
+mark_as_advanced(LIBUSB1_INCLUDE_DIR LIBUSB1_LIBRARY)
--- kinfocenter/Modules/usbview/CMakeLists.txt
+++ kinfocenter/Modules/usbview/CMakeLists.txt
@@ -1,15 +1,25 @@
+macro_optional_find_package(LibUSB1)
+macro_bool_to_01(LIBUSB1_FOUND HAVE_LIBUSB1)
+macro_log_feature(LIBUSB1_FOUND "libusb-1" "User level access to USB devices" "http://libusb.sourceforge.net/" FALSE "" "Provides usb info support in KControl.")
-
+configure_file (config-kcmusb.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kcmusb.h )
########### next target ###############
+if (LIBUSB1_FOUND)
+ include_directories( ${LIBUSB1_INCLUDE_DIR} )
+endif (LIBUSB1_FOUND)
+
set(kcm_usb_PART_SRCS kcmusb.cpp usbdevices.cpp usbdb.cpp )
kde4_add_plugin(kcm_usb ${kcm_usb_PART_SRCS})
-target_link_libraries(kcm_usb ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY})
+target_link_libraries(kcm_usb ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS} ${QT_QTGUI_LIBRARY})
+if (LIBUSB1_FOUND)
+ target_link_libraries(kcm_usb ${LIBUSB1_LIBRARY})
+endif (LIBUSB1_FOUND)
install(TARGETS kcm_usb DESTINATION ${PLUGIN_INSTALL_DIR} )
--- /dev/null
+++ kinfocenter/Modules/usbview/config-kcmusb.h.cmake
@@ -0,0 +1,2 @@
+/* Defined if you have libusb */
+#cmakedefine HAVE_LIBUSB1 1
--- kinfocenter/Modules/usbview/kcmusb.cpp
+++ kinfocenter/Modules/usbview/kcmusb.cpp
@@ -12,7 +12,6 @@
#include <QLayout>
#include <QSplitter>
#include <QtGui/QTextEdit>
-#include <QTimer>
#include <QHBoxLayout>
#include <QList>
#include <QTreeWidget>
@@ -20,6 +19,7 @@
#include <kaboutdata.h>
#include <kdialog.h>
+#include <solid/devicenotifier.h>
#include <KPluginFactory>
#include <KPluginLoader>
@@ -63,11 +63,8 @@ USBViewer::USBViewer(QWidget *parent, const QVariantList &) :
_details = new QTextEdit(splitter);
_details->setReadOnly(true);
- QTimer *refreshTimer = new QTimer(this);
- // 1 sec seems to be a good compromise between latency and polling load.
- refreshTimer->start(1000);
-
- connect(refreshTimer, SIGNAL(timeout()), SLOT(refresh()));
+ connect(Solid::DeviceNotifier::instance(),SIGNAL(deviceAdded(QString)), SLOT(refresh()));
+ connect(Solid::DeviceNotifier::instance(),SIGNAL(deviceRemoved(const QString)), SLOT(refresh()));
connect(_devices, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectionChanged(QTreeWidgetItem*)));
KAboutData *about = new KAboutData(I18N_NOOP("kcmusb"), 0, ki18n("KDE USB Viewer"),
@@ -113,8 +110,12 @@ static void delete_recursive(QTreeWidgetItem *item, const QMap<int, QTreeWidgetI
void USBViewer::refresh() {
QMap<int, QTreeWidgetItem*> new_items;
+#if defined(HAVE_LIBUSB1)
+ USBDevice::parse();
+#else
if (!USBDevice::parse("/proc/bus/usb/devices"))
USBDevice::parseSys("/sys/bus/usb/devices");
+#endif
int level = 0;
bool found = true;
--- kinfocenter/Modules/usbview/usbdevices.cpp
+++ kinfocenter/Modules/usbview/usbdevices.cpp
@@ -27,9 +27,9 @@
#include <math.h>
-#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
-#include <sys/ioctl.h>
-#include <sys/param.h>
+#include <config-kcmusb.h>
+#if defined(HAVE_LIBUSB1)
+#include <libusb.h>
#endif
QList<USBDevice*> USBDevice::_devices;
@@ -48,6 +48,7 @@ USBDevice::~USBDevice() {
}
+#if !defined(HAVE_LIBUSB1)
static QString catFile(QString fname) {
char buffer[256];
QString result;
@@ -129,6 +130,7 @@ void USBDevice::parseLine(const QString& line) {
} else if (line.startsWith("P:"))
sscanf(line.toLocal8Bit().data(), "P: Vendor=%x ProdID=%x Rev=%x.%x", &_vendorID, &_prodID, &_revMajor, &_revMinor);
}
+#endif // !defined(HAVE_LIBUSB1)
USBDevice* USBDevice::find(int bus, int device) {
foreach(USBDevice* usbDevice, _devices) {
@@ -160,6 +162,10 @@ QString USBDevice::dump() {
r += "<br/><table>";
+ r += i18n("<tr><td><i>Bus number</i></td><td>%1</td></tr>", _bus);
+ r += i18n("<tr><td><i>Device address</i></td><td>%1</td></tr>", _device);
+ r += "<tr><td></td></tr>";
+
QString c = QString("<td>%1</td>").arg(_class);
QString cname = _db->cls(_class);
if (!cname.isEmpty())
@@ -175,11 +181,9 @@ QString USBDevice::dump() {
if (!prname.isEmpty())
pr += "<td>(" + prname +")</td>";
r += i18n("<tr><td><i>Protocol</i></td>%1</tr>", pr);
-#if !(defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD))
r += ki18n("<tr><td><i>USB Version</i></td><td>%1.%2</td></tr>")
.subs(_verMajor,0,16).subs(_verMinor,2,16,QChar::fromLatin1('0'))
.toString();
-#endif
r += "<tr><td></td></tr>";
QString v = QString::number(_vendorID, 16);
@@ -198,22 +202,15 @@ QString USBDevice::dump() {
r += "<tr><td></td></tr>";
r += i18n("<tr><td><i>Speed</i></td><td>%1 Mbit/s</td></tr>", _speed);
- r += i18n("<tr><td><i>Channels</i></td><td>%1</td></tr>", _channels);
-#if (defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)) && !defined(DISABLE_USBDEVICES_FREEBSD)
- if ( _power )
+#if defined(HAVE_LIBUSB1)
+ if ( _power != -1 )
r += i18n("<tr><td><i>Power Consumption</i></td><td>%1 mA</td></tr>", _power);
else
- r += i18n("<tr><td><i>Power Consumption</i></td><td>self powered</td></tr>");
- r += i18n("<tr><td><i>Attached Devicenodes</i></td><td>%1</td></tr>", _devnodes.at(0));
- if ( _devnodes.count() > 1 ) {
- QStringList::const_iterator it = _devnodes.constBegin();
- ++it;
- for (; it != _devnodes.constEnd(); ++it )
- r += "<tr><td></td><td>" + *it + "</td></tr>";
- }
-#else
+ r += i18n("<tr><td><i>Power Consumption</i></td><td>unknown</td></tr>");
+#else // defined(HAVE_LIBUSB1)
+ r += i18n("<tr><td><i>Channels</i></td><td>%1</td></tr>", _channels);
+#endif // defined(HAVE_LIBUSB1)
r += i18n("<tr><td><i>Max. Packet Size</i></td><td>%1</td></tr>", _maxPacketSize);
-#endif
r += "<tr><td></td></tr>";
if (_hasBW) {
@@ -228,7 +225,82 @@ QString USBDevice::dump() {
return r;
}
-#if !(defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD))
+#if defined(HAVE_LIBUSB1)
+
+void USBDevice::dump_usbdev_info(libusb_device *dev) {
+
+ _bus = libusb_get_bus_number(dev);
+ _device = libusb_get_device_address(dev);
+
+ switch (libusb_get_device_speed(dev)) {
+ case LIBUSB_SPEED_LOW: _speed = 1.5; break;
+ case LIBUSB_SPEED_FULL: _speed = 12; break;
+ case LIBUSB_SPEED_HIGH: _speed = 480; break;
+ case LIBUSB_SPEED_SUPER: _speed = 5000; break;
+ }
+
+ struct libusb_config_descriptor *conf;
+ if (libusb_get_active_config_descriptor(dev, &conf) == 0) {
+ _power = conf->MaxPower;
+ libusb_free_config_descriptor(conf);
+ } else {
+ _power = -1;
+ }
+
+ struct libusb_device_descriptor desc;
+ if (libusb_get_device_descriptor(dev, &desc) == 0) {
+ _verMajor = desc.bcdUSB >> 8;
+ _verMinor = desc.bcdUSB & 0x00FF;
+ _class = desc.bDeviceClass;
+ _sub = desc.bDeviceSubClass;
+ _prot = desc.bDeviceProtocol;
+ _maxPacketSize = desc.bMaxPacketSize0;
+ _configs = desc.bNumConfigurations;
+ _vendorID = desc.idVendor;
+ _prodID = desc.idProduct;
+ _revMajor = desc.bcdDevice >> 8;
+ _revMinor = desc.bcdDevice & 0x00FF;
+ }
+
+ libusb_device_handle *hdev;
+ uchar buf[256];
+ if (libusb_open(dev, &hdev) == 0) {
+ if (libusb_get_string_descriptor_ascii(hdev, desc.iManufacturer, buf, sizeof(buf)) > 0)
+ _manufacturer = (char*) buf;
+ if (libusb_get_string_descriptor_ascii(hdev, desc.iProduct, buf, sizeof(buf)) > 0)
+ _product = (char*) buf;
+ if (libusb_get_string_descriptor_ascii(hdev, desc.iSerialNumber, buf, sizeof(buf)) > 0)
+ _serial = (char*) buf;
+ libusb_close(hdev);
+ }
+}
+
+bool USBDevice::parse() {
+ _devices.clear();
+
+ int r = libusb_init(NULL);
+ if (r != 0)
+ return false;
+
+ libusb_device **devs;
+ ssize_t cnt = libusb_get_device_list(NULL, &devs);
+ if (cnt < 0)
+ return false;
+
+ libusb_device *dev;
+ int i = 0;
+ while ((dev = devs[i++]) != NULL) {
+ USBDevice* device = new USBDevice();
+ device->dump_usbdev_info(dev);
+ }
+ libusb_free_device_list(devs, 1);
+
+ libusb_exit(NULL);
+ return true;
+}
+
+#else // defined(HAVE_LIBUSB1)
+#if defined(Q_OS_LINUX)
bool USBDevice::parse(const QString &fname) {
_devices.clear();
@@ -290,146 +362,19 @@ bool USBDevice::parseSys(const QString &dname) {
return d.count();
}
-#else
-
-// Unused by *BSD
-bool USBDevice::parseSys(const QString &fname)
-{
- Q_UNUSED(fname)
-
- return true;
-}
-
-# if defined(DISABLE_USBDEVICES_FREEBSD)
-
-/*
- * FIXME: The USB subsystem has changed a lot in FreeBSD 8.0
- * Support for it must be written.
- */
+#else // defined(Q_OS_LINUX)
-bool USBDevice::parse(const QString &fname)
-{
+bool USBDevice::parse(const QString &fname) {
Q_UNUSED(fname)
return true;
}
-# else
-
-/*
- * FreeBSD support by Markus Brueffer <markus@brueffer.de>
- *
- * Basic idea and some code fragments were taken from FreeBSD's usbdevs(8),
- * originally developed for NetBSD, so this code should work with no or
- * only little modification on NetBSD.
- */
-
-void USBDevice::collectData( int fd, int level, usb_device_info &di, int parent)
-{
- // determine data for this device
- _level = level;
- _parent = parent;
-
- _bus = di.udi_bus;
- _device = di.udi_addr;
- _product = QLatin1String(di.udi_product);
- if ( _device == 1 )
- _product += ' ' + QString::number( _bus );
- _manufacturer = QLatin1String(di.udi_vendor);
- _prodID = di.udi_productNo;
- _vendorID = di.udi_vendorNo;
- _class = di.udi_class;
- _sub = di.udi_subclass;
- _prot = di.udi_protocol;
- _power = di.udi_power;
- _channels = di.udi_nports;
-
- // determine the speed
-#if defined(__DragonFly__) || (defined(Q_OS_FREEBSD) && __FreeBSD_version > 490102) || defined(Q_OS_NETBSD)
- switch (di.udi_speed) {
- case USB_SPEED_LOW: _speed = 1.5; break;
- case USB_SPEED_FULL: _speed = 12.0; break;
- case USB_SPEED_HIGH: _speed = 480.0; break;
- }
-#else
- _speed = di.udi_lowspeed ? 1.5 : 12.0;
-#endif
-
- // Get all attached devicenodes
- for ( int i = 0; i < USB_MAX_DEVNAMES; ++i )
- if ( di.udi_devnames[i][0] )
- _devnodes << di.udi_devnames[i];
-
- // For compatibility, split the revision number
- sscanf( di.udi_release, "%x.%x", &_revMajor, &_revMinor );
-
- // Cycle through the attached devices if there are any
- for ( int p = 0; p < di.udi_nports; ++p ) {
- // Get data for device
- struct usb_device_info di2;
-
- di2.udi_addr = di.udi_ports[p];
-
- if ( di2.udi_addr >= USB_MAX_DEVICES )
- continue;
-
- if ( ioctl(fd, USB_DEVICEINFO, &di2) == -1 )
- continue;
-
- // Only add the device if we didn't detect it, yet
- if (!find( di2.udi_bus, di2.udi_addr ) )
- {
- USBDevice *device = new USBDevice();
- device->collectData( fd, level + 1, di2, di.udi_addr );
- }
- }
-}
-
-bool USBDevice::parse(const QString &fname)
-{
- Q_UNUSED(fname)
-
- static bool showErrorMessage = true;
- bool error = false;
- _devices.clear();
-
- QFile controller("/dev/usb0");
- int i = 1;
- while ( controller.exists() )
- {
- // If the devicenode exists, continue with further inspection
- if ( controller.open(QIODevice::ReadOnly) )
- {
- for ( int addr = 1; addr < USB_MAX_DEVICES; ++addr )
- {
- struct usb_device_info di;
-
- di.udi_addr = addr;
- if ( ioctl(controller.handle(), USB_DEVICEINFO, &di) != -1 )
- {
- if (!find( di.udi_bus, di.udi_addr ) )
- {
- USBDevice *device = new USBDevice();
- device->collectData( controller.handle(), 0, di, 0);
- }
- }
- }
- controller.close();
-#ifndef Q_OS_NETBSD
- } else {
- error = true;
-#endif
- }
- controller.setFileName( QString::fromLocal8Bit("/dev/usb%1").arg(i++) );
- }
-
- if ( showErrorMessage && error ) {
- showErrorMessage = false;
- KMessageBox::error( 0, i18n("Could not open one or more USB controller. Make sure, you have read access to all USB controllers that should be listed here."));
- }
+bool USBDevice::parseSys(const QString &dname) {
+ Q_UNUSED(dname)
return true;
}
-# endif // defined(DISABLE_USBDEVICES_FREEBSD)
-#endif // !(defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD))
+#endif // defined(Q_OS_LINUX)
+#endif // defined(HAVE_LIBUSB1)
--- kinfocenter/Modules/usbview/usbdevices.h
+++ kinfocenter/Modules/usbview/usbdevices.h
@@ -14,18 +14,9 @@
#include <QList>
#include <QString>
-#if defined(__DragonFly__)
-#include <bus/usb/usb.h>
-#include <QStringList>
-#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
-#include <sys/param.h>
-# if defined(__FreeBSD_version) && __FreeBSD_version >= 800100
-# define DISABLE_USBDEVICES_FREEBSD
-# warning "The USB subsystem has changed in 8.0. Disabling."
-# else
-# include <dev/usb/usb.h>
-# include <QStringList>
-# endif
+#include <config-kcmusb.h>
+#if defined(HAVE_LIBUSB1)
+#include <libusb.h>
#endif
class USBDB;
@@ -36,10 +27,12 @@ public:
USBDevice();
~USBDevice();
-
+#if defined(HAVE_LIBUSB1)
+ void dump_usbdev_info(libusb_device *dev);
+#else
void parseLine(const QString &line);
void parseSysDir(int bus, int parent, int level, const QString &line);
-
+#endif
int level() const {
return _level;
}
@@ -60,8 +53,12 @@ public:
return _devices;
}
static USBDevice *find(int bus, int device);
+#if defined(HAVE_LIBUSB1)
+ static bool parse();
+#else
static bool parse(const QString& fname);
static bool parseSys(const QString& fname);
+#endif
private:
@@ -82,10 +79,6 @@ private:
unsigned int _vendorID, _prodID, _revMajor, _revMinor;
-#if (defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)) && !defined(DISABLE_USBDEVICES_FREEBSD)
- void collectData( int fd, int level, usb_device_info &di, int parent );
- QStringList _devnodes;
-#endif
};
#endif