diff --git a/kdnssd/kdedmodule/dnssdwatcher.desktop b/kdnssd/kdedmodule/dnssdwatcher.desktop index 12168a3..fd44a51 100644 --- a/kdnssd/kdedmodule/dnssdwatcher.desktop +++ b/kdnssd/kdedmodule/dnssdwatcher.desktop @@ -8,6 +8,7 @@ Name[de]=DNS-SD-Dienst-berwachung Name[en_GB]=DNS-SD Service Discovery Monitor Name[es]=Monitor para descubrir servicios DNS-SD Name[et]=DNS-SD teenuste tuvastamise jlgija +Name[fr]=Dcouverte de services DNS-SD Name[hr]=Nadzornik otkrivanja usluga DNS-SD-a Name[it]=Rilevamento di servizi DNS-SD Name[kk]=DNS-SD @@ -31,6 +32,7 @@ Comment[de]=berwacht das Netzwerk nach DNS-SD-Diensten Comment[en_GB]=Monitors the network for DNS-SD services Comment[es]=Monitorizar la red en busca de servicios DNS-SD Comment[et]=DNS-SD teenuste vrgu jlgimine +Comment[fr]=Surveille le rseau et recherche les services DNS-SD Comment[hr]=Nadgleda mreu za usluge DNS-SD-a Comment[it]=Controlla la presenza di servizi DNS-SD nella rete Comment[kk]= DNS-SD diff --git a/kget/extensions/konqueror/CMakeLists.txt b/kget/extensions/konqueror/CMakeLists.txt index 57d6ad7..ba47ba4 100644 --- a/kget/extensions/konqueror/CMakeLists.txt +++ b/kget/extensions/konqueror/CMakeLists.txt @@ -26,7 +26,7 @@ QT4_ADD_DBUS_INTERFACE(kget_browser_integration_SRCS ../../dbus/org.kde.kget.mai kde4_add_plugin(kget_browser_integration ${kget_browser_integration_SRCS}) -target_link_libraries(kget_browser_integration ${KDE4_KHTML_LIBS}) +target_link_libraries(kget_browser_integration ${KDE4_KHTML_LIBS} ${KDE4_KIO_LIBRARY}) if(KWEBKITPART_FOUND) target_link_libraries(kget_browser_integration ${KWEBKITPART_LIBRARIES} ${KDE4_KDEUI_LIBRARY} ${QT_QTWEBKIT_LIBRARY}) @@ -37,6 +37,7 @@ install(TARGETS kget_browser_integration DESTINATION ${PLUGIN_INSTALL_DIR}) ########### install files ############### install(FILES kget_plug_in.rc DESTINATION ${DATA_INSTALL_DIR}/khtml/kpartplugins) +install(FILES kget_plug_in.rc DESTINATION ${DATA_INSTALL_DIR}/dolphinpart/kpartplugins) if (KWEBKITPART_FOUND) install(FILES kget_plug_in.rc DESTINATION ${DATA_INSTALL_DIR}/kwebkitpart/kpartplugins) diff --git a/kget/extensions/konqueror/kget_plug_in.cpp b/kget/extensions/konqueror/kget_plug_in.cpp index a0ff509..f7f2f9d 100644 --- a/kget/extensions/konqueror/kget_plug_in.cpp +++ b/kget/extensions/konqueror/kget_plug_in.cpp @@ -41,15 +41,167 @@ #include #endif +KGet_plug_in::KGet_plug_in( QObject* parent ) + : Plugin(parent), + m_dolphinPart(0), + m_type(None) +{ + KActionMenu *menu = new KActionMenu(KIcon("kget"), i18n("Download Manager"), + actionCollection()); + actionCollection()->addAction("kget_menu", menu); + + menu->setDelayed( false ); + connect( menu->menu(), SIGNAL( aboutToShow() ), SLOT( showPopup() )); + + m_dropTargetAction = new KToggleAction(i18n("Show Drop Target"), actionCollection()); + + connect(m_dropTargetAction, SIGNAL(triggered()), this, SLOT(slotShowDrop())); + actionCollection()->addAction("show_drop", m_dropTargetAction); + menu->addAction(m_dropTargetAction); + + QAction *showLinksAction = actionCollection()->addAction("show_links"); + showLinksAction->setText(i18n("List All Links")); + connect(showLinksAction, SIGNAL(triggered()), SLOT(slotShowLinks())); + menu->addAction(showLinksAction); + + QAction *showSelectedLinksAction = actionCollection()->addAction("show_selected_links"); + showSelectedLinksAction->setText(i18n("List Selected Links")); + connect(showSelectedLinksAction, SIGNAL(triggered()), SLOT(slotShowSelectedLinks())); + menu->addAction(showSelectedLinksAction); + + if (parent) { + if (parent->inherits("KHTMLPart")) { + m_type = KHTMLType; + } else if (parent->inherits("KWebKitPart")) { + m_type = KWebkitType; + } else if (parent->inherits("DolphinPart")) { + m_type = DolphinType; + } + } + + //FIXME once DolphinPart gets exported + if ((m_type != KHTMLType) && (m_type != KWebkitType))//TODO support also for DolphinPart? --> DolphinView::selectedUrls() + actionCollection()->action("show_selected_links")->setVisible(false); + + if (m_type == DolphinType) { + m_dolphinPart = qobject_cast(parent); + connect(m_dolphinPart, SIGNAL(started(KIO::Job*)), this, SLOT(slotCheckUrlDolphin()));//TODO use aboutToOpenURL from DolphinPart instead? + } +} + + +KGet_plug_in::~KGet_plug_in() +{ +} + +void KGet_plug_in::slotCheckUrlDolphin() +{ + m_dolphinPartUrl = m_dolphinPart->url(); + const QString protocol = m_dolphinPartUrl.protocol(); + const bool visible = protocol.contains("ftp"); + actionCollection()->action("kget_menu")->setVisible(visible); +} + -QStringList getLinks(QObject *obj, bool selectedOnly = false) +void KGet_plug_in::showPopup() { + bool hasDropTarget = false; + + if(QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) + { + OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus()); + QDBusReply reply = kgetInterface.dropTargetVisible(); + if (reply.isValid()) + hasDropTarget = reply.value(); + } + + m_dropTargetAction->setChecked(hasDropTarget); + + bool enabled = false; + if (m_type == KHTMLType) { + const QString selectedHtml = qobject_cast(parent())->selectedTextAsHTML(); + DOM::HTMLDocument document; + document.open(); + document.write( selectedHtml ); + document.close(); + enabled = (document.getElementsByTagName("a").length() > 0); + } +#ifdef HAVE_KWEBKITPART + else if (m_type == KWebkitType) + { + // TODO: Find a way to find links and images in selected content. + // No straight forward way to accomplish this in QtWebKit without + // resorting to javascript based hacks right now! + } +#endif + actionCollection()->action("show_selected_links")->setEnabled(enabled); +} + +void KGet_plug_in::slotShowDrop() +{ + if(!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) { + QWidget *parentWidget = 0; + if (m_type == KHTMLType) + parentWidget = qobject_cast(parent())->widget(); +#ifdef HAVE_KWEBKITPART + else if (m_type == KWebkitType) + parentWidget = qobject_cast(parent())->view(); +#endif + else if (m_type == DolphinType) { + parentWidget = qobject_cast(parent())->widget(); + } + KRun::runCommand("kget --showDropTarget --hideMainWindow", "kget", "kget", parentWidget); + } else { + OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus()); + kgetInterface.setDropTargetVisible(m_dropTargetAction->isChecked()); + } +} + +void KGet_plug_in::slotShowLinks() +{ + getLinks(false); +} + +void KGet_plug_in::slotShowSelectedLinks() +{ + getLinks(true); +} + +void KGet_plug_in::slotImportLinks() +{ + if (m_linkList.isEmpty()) { + KParts::ReadOnlyPart *part = qobject_cast(parent()); + KMessageBox::sorry(part ? part->widget() : 0, + i18n("There are no links in the active frame of the current HTML page."), + i18n("No Links")); + return; + } + + // Remove any duplicates links from the list... + m_linkList.removeDuplicates(); + + if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget") && + KToolInvocation::kdeinitExecWait("kget") != 0) + { + KParts::ReadOnlyPart *part = qobject_cast(parent()); + KMessageBox::sorry(part ? part->widget() : 0, + i18n("Unable to communicate with the KGet download manager."), + i18n("Communication Error")); + return; + } + + OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus()); + kgetInterface.importLinks(m_linkList); +} + +void KGet_plug_in::getLinks(bool selectedOnly) +{ + QObject *obj = parent(); Q_ASSERT(obj); - QStringList linkList; + m_linkList.clear(); - if (obj->inherits("KHTMLPart")) - { + if (m_type == KHTMLType) { KHTMLPart *htmlPart = qobject_cast(obj); KParts::Part *activePart = 0; @@ -86,9 +238,9 @@ QStringList getLinks(QObject *obj, bool selectedOnly = false) if ( link.isNull() || link.nodeType() != DOM::Node::ELEMENT_NODE ) continue; - LinkItem *item = new LinkItem( (DOM::Element) link ); + LinkItem *item = new LinkItem( (DOM::Element) link );//TODO remove C cast if (item->isValid()) - linkList.append(item->url.url()); + m_linkList.append(item->url.url()); else delete item; } @@ -97,20 +249,20 @@ QStringList getLinks(QObject *obj, bool selectedOnly = false) for ( uint i = 0; i < images.length(); i++ ) { DOM::Node image = images.item( i ); - if ( image.isNull() || image.nodeType() != DOM::Node::ELEMENT_NODE ) + if ( image.isNull() || image.nodeType() != DOM::Node::ELEMENT_NODE )//TODO remove C cast continue; LinkItem *item = new LinkItem( (DOM::Element) image ); if (item->isValid()) - linkList.append(item->url.url()); + m_linkList.append(item->url.url()); else delete item; } } + slotImportLinks(); } #ifdef HAVE_KWEBKITPART - else if (obj->inherits("KWebKitPart")) - { + else if (m_type == KWebkitType) { KWebKitPart *part = qobject_cast(obj); Q_ASSERT(part); @@ -146,149 +298,36 @@ QStringList getLinks(QObject *obj, bool selectedOnly = false) const QUrl url = frame->baseUrl().resolved(QUrl(element.attribute("href"))); if (url.isValid()) - linkList << url.toString(); + m_linkList << url.toString(); } } } + slotImportLinks(); } #endif - - return linkList; -} - -KGet_plug_in::KGet_plug_in( QObject* parent ) - :Plugin(parent) -{ - KActionMenu *menu = new KActionMenu(KIcon("kget"), i18n("Download Manager"), - actionCollection()); - actionCollection()->addAction("kget_menu", menu); - - menu->setDelayed( false ); - connect( menu->menu(), SIGNAL( aboutToShow() ), SLOT( showPopup() )); - - m_dropTargetAction = new KToggleAction(i18n("Show Drop Target"), actionCollection()); - - connect(m_dropTargetAction, SIGNAL(triggered()), this, SLOT(slotShowDrop())); - actionCollection()->addAction("show_drop", m_dropTargetAction); - menu->addAction(m_dropTargetAction); - - QAction *showLinksAction = actionCollection()->addAction("show_links"); - showLinksAction->setText(i18n("List All Links")); - connect(showLinksAction, SIGNAL(triggered()), SLOT(slotShowLinks())); - menu->addAction(showLinksAction); - - QAction *showSelectedLinksAction = actionCollection()->addAction("show_selected_links"); - showSelectedLinksAction->setText(i18n("List Selected Links")); - connect(showSelectedLinksAction, SIGNAL(triggered()), SLOT(slotShowSelectedLinks())); - menu->addAction(showSelectedLinksAction); - - if (parent && !parent->inherits("KHTMLPart") && !parent->inherits("KWebKitPart")) - actionCollection()->action("show_selected_links")->setVisible(false); -} - - -KGet_plug_in::~KGet_plug_in() -{ -} - - -void KGet_plug_in::showPopup() -{ - bool hasDropTarget = false; - - if(QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) - { - OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus()); - QDBusReply reply = kgetInterface.dropTargetVisible(); - if (reply.isValid()) - hasDropTarget = reply.value(); - } - - m_dropTargetAction->setChecked(hasDropTarget); - - if ( parent() ) - { - bool enabled = false; - if (parent()->inherits("KHTMLPart")) - { - const QString selectedHtml = qobject_cast(parent())->selectedTextAsHTML(); - DOM::HTMLDocument document; - document.open(); - document.write( selectedHtml ); - document.close(); - enabled = (document.getElementsByTagName("a").length() > 0); - } -#ifdef HAVE_KWEBKITPART - else if (parent()->inherits("KWebKitPart")) - { - // TODO: Find a way to find links and images in selected content. - // No straight forward way to accomplish this in QtWebKit without - // resorting to javascript based hacks right now! - } -#endif - actionCollection()->action("show_selected_links")->setEnabled(enabled); + else if (m_type == DolphinType) { + const KUrl url = qobject_cast(obj)->url(); + KIO::ListJob *list = KIO::listDir(m_dolphinPartUrl, KIO::HideProgressInfo);//TODO link with KIO? + connect(list, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), this, SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList))); + connect(list, SIGNAL(finished(KJob*)), this, SLOT(slotImportLinks())); } } -void KGet_plug_in::slotShowDrop() +void KGet_plug_in::slotEntries(KIO::Job *job, const KIO::UDSEntryList &entries) { - if(!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) { - QWidget *parentWidget = 0; - if (parent()) - { - if (parent()->inherits("KHTMLPart")) - parentWidget = qobject_cast(parent())->widget(); -#ifdef HAVE_KWEBKITPART - else if (parent()->inherits("KWebKitPart")) - parentWidget = qobject_cast(parent())->view(); -#endif - KRun::runCommand("kget --showDropTarget --hideMainWindow", "kget", "kget", parentWidget); + Q_UNUSED(job) + + const QString baseUrl = m_dolphinPartUrl.url(KUrl::AddTrailingSlash); + foreach (const KIO::UDSEntry &entry, entries) { + //skip all found dirs + if (!entry.isDir()) { + const QString name = entry.stringValue(KIO::UDSEntry::UDS_NAME); + m_linkList << baseUrl + name; } - } else { - OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus()); - kgetInterface.setDropTargetVisible(m_dropTargetAction->isChecked()); } } -void KGet_plug_in::slotShowLinks() -{ - showLinks(false); -} -void KGet_plug_in::slotShowSelectedLinks() -{ - showLinks(true); -} - -void KGet_plug_in::showLinks( bool selectedOnly ) -{ - QStringList linkList = getLinks(parent(), selectedOnly); - - if ( linkList.isEmpty() ) - { - KParts::ReadOnlyPart *part = qobject_cast(parent()); - KMessageBox::sorry(part ? part->widget() : 0, - i18n("There are no links in the active frame of the current HTML page."), - i18n("No Links")); - return; - } - - // Remove any duplicates links from the list... - linkList.removeDuplicates(); - - if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget") && - KToolInvocation::kdeinitExecWait("kget") != 0) - { - KParts::ReadOnlyPart *part = qobject_cast(parent()); - KMessageBox::sorry(part ? part->widget() : 0, - i18n("Unable to communicate with the KGet download manager."), - i18n("Communication Error")); - return; - } - - OrgKdeKgetMainInterface kgetInterface("org.kde.kget", "/KGet", QDBusConnection::sessionBus()); - kgetInterface.importLinks(linkList); -} KGetPluginFactory::KGetPluginFactory( QObject* parent ) :KPluginFactory("kget", "kget", parent) diff --git a/kget/extensions/konqueror/kget_plug_in.h b/kget/extensions/konqueror/kget_plug_in.h index 78a7a9e..ec45a40 100644 --- a/kget/extensions/konqueror/kget_plug_in.h +++ b/kget/extensions/konqueror/kget_plug_in.h @@ -11,11 +11,16 @@ #ifndef PLUGIN_KGET_PLUG_IN_H #define PLUGIN_KGET_PLUG_IN_H +#include #include #include class KToggleAction; +namespace KParts { + class ReadOnlyPart; +} + class KGet_plug_in : public KParts::Plugin { @@ -25,14 +30,37 @@ public: KToggleAction *m_dropTargetAction; virtual ~KGet_plug_in(); + enum PartType { + None = 0, + KHTMLType, + KWebkitType, + DolphinType + }; + private: - void showLinks( bool ); + void getLinks(bool selectedOnly = false); private slots: void slotShowDrop(); void slotShowLinks(); void slotShowSelectedLinks(); + void slotImportLinks(); + /** + * Only show the KGet Plugin in the DolphinPart, if the selected Url is ftp or sftp + */ + void slotCheckUrlDolphin(); + + /** + * Links of the DolphinPart, gotten by a listJob + */ + void slotEntries(KIO::Job *job, const KIO::UDSEntryList &entries); void showPopup(); + +private: + KParts::ReadOnlyPart *m_dolphinPart; + KUrl m_dolphinPartUrl; + PartType m_type; + QStringList m_linkList; }; diff --git a/kget/sounds/kget.notifyrc b/kget/sounds/kget.notifyrc index 3c9bdb6..b511fea 100644 --- a/kget/sounds/kget.notifyrc +++ b/kget/sounds/kget.notifyrc @@ -9,6 +9,7 @@ Comment[de]=KGet-Download-Verwaltung Comment[en_GB]=KGet Download Manager Comment[es]=Gestor de descargas KGet Comment[et]=KGeti allalaadimiste haldur +Comment[fr]=Gestionnaire de tlchargements KGet Comment[hr]=Upravitelj preuzimanja KGet Comment[it]=Gestore degli scaricamenti KGet Comment[kk]=KGet diff --git a/kopete/kopete/kopete.notifyrc b/kopete/kopete/kopete.notifyrc index 75327cb..9d7c1cf 100644 --- a/kopete/kopete/kopete.notifyrc +++ b/kopete/kopete/kopete.notifyrc @@ -2948,6 +2948,7 @@ Name[da]=Skriver en besked Name[de]=Nachricht wird geschrieben Name[en_GB]=Typing message Name[et]=Snumi kirjutamine +Name[fr]=Rdaction en cours Name[hr]=Pie poruku Name[it]=Messaggio in battitura Name[kk]= @@ -2971,6 +2972,7 @@ Comment[da]=En bruger er ved at skrive en besked Comment[de]=Ein Benutzer schreibt eine Nachricht Comment[en_GB]=An user is typing a message Comment[et]=Kasutaja kirjutab snumit +Comment[fr]=Un utilisateur crit un message Comment[hr]=Korisnik pie poruku Comment[it]=Un utente sta scrivendo un messaggio Comment[kk]= diff --git a/kopete/libkopete/avdevice/CMakeLists.txt b/kopete/libkopete/avdevice/CMakeLists.txt index ea3d27f..2186c97 100644 --- a/kopete/libkopete/avdevice/CMakeLists.txt +++ b/kopete/libkopete/avdevice/CMakeLists.txt @@ -15,6 +15,8 @@ endif (LIBV4L2_FOUND) set(kopete_videodevice_LIB_SRCS videodevice.cpp videoinput.cpp + dummyvideodevice.cpp + videodevicevector.cpp videodevicepool.cpp bayer.cpp sonix_compress.cpp ) diff --git a/kopete/libkopete/avdevice/dummyvideodevice.cpp b/kopete/libkopete/avdevice/dummyvideodevice.cpp new file mode 100644 index 0000000..91feaac --- /dev/null +++ b/kopete/libkopete/avdevice/dummyvideodevice.cpp @@ -0,0 +1,196 @@ +/* + dummyvideodevice.cpp - Dummy Video Device + + Copyright (c) 2009 by Alan Jones + + Kopete (c) 2002-2009 by the Kopete developers + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 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, see . * + ************************************************************************* +*/ + +#include "dummyvideodevice.h" +#include "videoinput.h" + +namespace Kopete { + +namespace AV { + +DummyVideoDevice::DummyVideoDevice() + { + //need to set a bunch of defaults for members + m_pixelformat = PIXELFORMAT_RGB32; + m_driver=VIDEODEV_DRIVER_NONE; + m_input.append(VideoInput()); + minwidth = 160; + maxwidth = 1280; + minheight = 120; + maxheight = 960; + //let's be opened by default seeing this is a fallback + opened = true; + setSize(320, 240); + } + +int DummyVideoDevice::open() + { + //wow - we always succeed in opening our dummy device + opened = true; + return EXIT_SUCCESS; + } + +bool DummyVideoDevice::isOpen() + { + //we'll track it just incase there is situations where it's expected not to be open + return opened; + } + +int DummyVideoDevice::checkDevice() + { + //again this is just incase anything ever relies on it failing when closed + if(isOpen()) + { + //need to check which, if any, of these need to be enabled for this to function properly + m_videocapture=false; + m_videochromakey=false; + m_videoscale=false; + m_videooverlay=false; + m_videoread=false; + m_videoasyncio=false; + m_videostream=false; + + m_driver=VIDEODEV_DRIVER_NONE; + return EXIT_SUCCESS; + } + return EXIT_FAILURE; + } + +int DummyVideoDevice::initDevice() + { + //again this is just incase anything ever relies on it failing when closed + if(isOpen()) + { + return EXIT_SUCCESS; + } + return EXIT_FAILURE; + } + +int DummyVideoDevice::setSize( int newwidth, int newheight) + { + if (isOpen()) + { + if(newwidth > maxwidth ) newwidth = maxwidth; + if(newheight > maxheight) newheight = maxheight; + if(newwidth < minwidth ) newwidth = minwidth; + if(newheight < minheight) newheight = minheight; + + currentwidth = newwidth; + currentheight = newheight; + + m_currentbuffer.width = currentwidth; + m_currentbuffer.height = currentheight; + m_currentbuffer.pixelformat = m_pixelformat; + + //let's fill the buffer up with something + //TODO: replace this with an .svg that says there is no camera available + m_currentbuffer.data.resize(currentwidth * currentheight * 4); + for (int i=0; iheight = m_currentbuffer.height; + imgbuffer->width = m_currentbuffer.width; + imgbuffer->pixelformat = m_currentbuffer.pixelformat; + imgbuffer->data = m_currentbuffer.data; + return EXIT_SUCCESS; + } + return EXIT_FAILURE; + } + +int DummyVideoDevice::getImage(QImage *qimage) + { + // do NOT delete qimage here, as it is received as a parameter + if (qimage->width() != width() || qimage->height() != height()) + *qimage = QImage(width(), height(), QImage::Format_RGB32); + + uchar *bits=qimage->bits(); + memcpy(bits,&m_currentbuffer.data[0], m_currentbuffer.data.size()); + + return EXIT_SUCCESS; + } + +int DummyVideoDevice::stopCapturing() + { + //again this is just incase anything ever relies on it failing when closed + if(isOpen()) + { + return EXIT_SUCCESS; + } + return EXIT_FAILURE; + } + +int DummyVideoDevice::close() + { + //we always manage to close it too - amazing :) + opened = false; + return EXIT_SUCCESS; + } + +} + +} diff --git a/kopete/libkopete/avdevice/dummyvideodevice.h b/kopete/libkopete/avdevice/dummyvideodevice.h new file mode 100644 index 0000000..5d1e61c --- /dev/null +++ b/kopete/libkopete/avdevice/dummyvideodevice.h @@ -0,0 +1,70 @@ +/* + dummyvideodevice.h - Kopete Dummy Video Device + + Copyright (c) 2009 by Alan Jones + + Kopete (c) 2002-2009 by the Kopete developers + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 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, see . * + ************************************************************************* +*/ + +#ifndef KOPETE_AVDUMMYVIDEODEVICE_H +#define KOPETE_AVDUMMYVIDEODEVICE_H + +#include "videodevice.h" + +namespace Kopete { + +namespace AV { + +/** +@author Kopete Developers +*/ + +class DummyVideoDevice : public VideoDevice +{ + +public: + DummyVideoDevice(); + virtual ~DummyVideoDevice() {} + + virtual int open(); + virtual bool isOpen(); + virtual int checkDevice(); + virtual int initDevice(); + + virtual int setSize( int newwidth, int newheight); + + virtual pixel_format setPixelFormat(pixel_format newformat); + + virtual int startCapturing(); + virtual int getFrame(); + virtual int getFrame(imagebuffer *imgbuffer); + virtual int getImage(QImage *qimage); + virtual int stopCapturing(); + virtual int close(); + + +private: + bool opened; +}; + +} + +} + +#endif diff --git a/kopete/libkopete/avdevice/videodevicepool.cpp b/kopete/libkopete/avdevice/videodevicepool.cpp index 4e6b859..094f42a 100644 --- a/kopete/libkopete/avdevice/videodevicepool.cpp +++ b/kopete/libkopete/avdevice/videodevicepool.cpp @@ -61,22 +61,15 @@ VideoDevicePool* VideoDevicePool::self() } VideoDevicePool::VideoDevicePool() -: m_current_device(-1) +: m_current_device(0) { connect( Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(const QString&)), SLOT(deviceAdded(const QString &)) ); connect( Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(const QString&)), SLOT(deviceRemoved(const QString &)) ); - /* NOTE: No locking needed as long as we don't connect with Qt::ConnectionType = Qt::DirectConnection - while the signals are emitted by other threads - */ - foreach( Solid::Device device, Solid::Device::listFromType(Solid::DeviceInterface::Video, QString()) ) - registerDevice( device ); } VideoDevicePool::~VideoDevicePool() { - foreach ( VideoDevice* vd, m_videodevices ) - delete vd; } @@ -87,39 +80,44 @@ VideoDevicePool::~VideoDevicePool() */ int VideoDevicePool::open(int device) { + /// @todo implement me kDebug() << "called with device" << device; - if (!m_videodevices.size() || (device >= m_videodevices.size())) + m_ready.lock(); + if (!m_videodevice.size()) + { + kDebug() << "open(): No devices found. Must scan for available devices." << m_current_device; + scanDevices(); + } + if (!m_videodevice.size() || (device >= m_videodevice.size())) { - kDebug() << "Device not found."; + kDebug() << "open(): Device not found. bailing out." << m_current_device; + m_ready.unlock(); return EXIT_FAILURE; } + int current_device = m_current_device; if (device < 0) { - kDebug() << "Trying to load saved device."; - device = getSavedDevice(); - if (device < 0) - { - if (m_current_device < 0) - device = 0; - else - device = m_current_device; - kDebug() << "Saved device is not available, using default device:" << device; - } + kDebug() << "Trying to load saved device (using default device if not available)"; + loadSelectedDevice(); // Set m_current_device to saved device (if device available) } + else + m_current_device = device; int isopen = EXIT_FAILURE; - if ((device != m_current_device) || !isOpen()) + if ((m_current_device != current_device) || !isOpen()) { if (isOpen()) { - if (EXIT_SUCCESS == m_videodevices[m_current_device]->close()) + if (EXIT_SUCCESS == m_videodevice[current_device].close()) m_clients--; else + { + m_ready.unlock(); return EXIT_FAILURE; + } } - isopen = m_videodevices[device]->open(); + isopen = m_videodevice[m_current_device].open(); if (isopen == EXIT_SUCCESS) { - m_current_device = device; loadDeviceConfig(); // Load and apply device parameters m_clients++; } @@ -130,82 +128,57 @@ int VideoDevicePool::open(int device) m_clients++; } kDebug() << "Number of clients: " << m_clients; + m_ready.unlock(); return isopen; } bool VideoDevicePool::isOpen() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->isOpen(); - else - return false; + return m_videodevice[currentDevice()].isOpen(); } /*! \fn VideoDevicePool::showDeviceCapabilities(int device) */ -int VideoDevicePool::showDeviceCapabilities(int device) +int VideoDevicePool::showDeviceCapabilities(unsigned int device) { - if (device < 0) - device = m_current_device; - if ((device >= 0) && (device < m_videodevices.size())) - return m_videodevices[device]->showDeviceCapabilities(); - else - return EXIT_FAILURE; + return m_videodevice[device].showDeviceCapabilities(); } int VideoDevicePool::width() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->width(); - else - return 0; + return m_videodevice[currentDevice()].width(); } int VideoDevicePool::minWidth() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->minWidth(); - else - return 0; + return m_videodevice[currentDevice()].minWidth(); } int VideoDevicePool::maxWidth() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->maxWidth(); - else - return 0; + return m_videodevice[currentDevice()].maxWidth(); } int VideoDevicePool::height() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->height(); - else - return 0; + return m_videodevice[currentDevice()].height(); } int VideoDevicePool::minHeight() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->minHeight(); - else - return 0; + return m_videodevice[currentDevice()].minHeight(); } int VideoDevicePool::maxHeight() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->maxHeight(); - else - return 0; + return m_videodevice[currentDevice()].maxHeight(); } int VideoDevicePool::setSize( int newwidth, int newheight) { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->setSize(newwidth, newheight); + if(m_videodevice.size()) + return m_videodevice[currentDevice()].setSize(newwidth, newheight); else { kDebug() << "VideoDevicePool::setSize() fallback for no device."; @@ -226,7 +199,7 @@ int VideoDevicePool::setSize( int newwidth, int newheight) int VideoDevicePool::close() { int ret = EXIT_FAILURE; - if ((m_current_device < 0) || (m_current_device >= m_videodevices.size())) + if (m_current_device >= m_videodevice.size()) { kDebug() << "Current device out of range."; } @@ -242,7 +215,7 @@ int VideoDevicePool::close() } else { - ret = m_videodevices[m_current_device]->close(); + ret = m_videodevice[m_current_device].close(); if (EXIT_SUCCESS == ret) m_clients--; } @@ -255,10 +228,9 @@ int VideoDevicePool::close() int VideoDevicePool::startCapturing() { kDebug() << "startCapturing() called."; - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->startCapturing(); - else - return EXIT_FAILURE; + if(m_videodevice.size()) + return m_videodevice[currentDevice()].startCapturing(); + return EXIT_FAILURE; } @@ -267,10 +239,9 @@ int VideoDevicePool::startCapturing() */ int VideoDevicePool::stopCapturing() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->stopCapturing(); - else - return EXIT_FAILURE; + if(m_videodevice.size()) + return m_videodevice[currentDevice()].stopCapturing(); + return EXIT_FAILURE; } @@ -283,8 +254,8 @@ int VideoDevicePool::stopCapturing() */ QList VideoDevicePool::getSupportedNumericControls() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->getSupportedNumericControls(); + if (currentDevice() < m_videodevice.size() ) + return m_videodevice[currentDevice()].getSupportedNumericControls(); else return QList(); } @@ -296,8 +267,8 @@ QList VideoDevicePool::getSupportedNumericControls() */ QList VideoDevicePool::getSupportedBooleanControls() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->getSupportedBooleanControls(); + if (currentDevice() < m_videodevice.size() ) + return m_videodevice[currentDevice()].getSupportedBooleanControls(); else return QList(); } @@ -309,8 +280,8 @@ QList VideoDevicePool::getSupportedBooleanControls() */ QList VideoDevicePool::getSupportedMenuControls() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->getSupportedMenuControls(); + if (currentDevice() < m_videodevice.size() ) + return m_videodevice[currentDevice()].getSupportedMenuControls(); else return QList(); } @@ -322,8 +293,8 @@ QList VideoDevicePool::getSupportedMenuControls() */ QList VideoDevicePool::getSupportedActionControls() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->getSupportedActionControls(); + if (currentDevice() < m_videodevice.size() ) + return m_videodevice[currentDevice()].getSupportedActionControls(); else return QList(); } @@ -339,8 +310,8 @@ QList VideoDevicePool::getSupportedActionControls() */ int VideoDevicePool::getControlValue(quint32 ctrl_id, qint32 * value) { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->getControlValue(ctrl_id, value); + if (currentDevice() < m_videodevice.size() ) + return m_videodevice[currentDevice()].getControlValue(ctrl_id, value); else return EXIT_FAILURE; } @@ -357,8 +328,8 @@ int VideoDevicePool::getControlValue(quint32 ctrl_id, qint32 * value) */ int VideoDevicePool::setControlValue(quint32 ctrl_id, qint32 value) { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->setControlValue(ctrl_id, value); + if (currentDevice() < m_videodevice.size() ) + return m_videodevice[currentDevice()].setControlValue(ctrl_id, value); else return EXIT_FAILURE; } @@ -370,10 +341,9 @@ int VideoDevicePool::setControlValue(quint32 ctrl_id, qint32 value) int VideoDevicePool::getFrame() { // kDebug() << "VideoDevicePool::getFrame() called."; - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->getFrame(); - else + if ((m_current_device < 0) || (m_current_device >= m_videodevice.size())) return EXIT_FAILURE; + return m_videodevice[currentDevice()].getFrame(); } /*! @@ -382,10 +352,65 @@ int VideoDevicePool::getFrame() int VideoDevicePool::getImage(QImage *qimage) { // kDebug() << "VideoDevicePool::getImage() called."; - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->getImage(qimage); + if(m_videodevice.size()) + return m_videodevice[currentDevice()].getImage(qimage); else - return EXIT_FAILURE; + { + kDebug() << "VideoDevicePool::getImage() fallback for no device."; + + // do NOT delete qimage here, as it is received as a parameter + if (qimage->width() != width() || qimage->height() != height()) + *qimage = QImage(width(), height(), QImage::Format_RGB32); + + uchar *bits=qimage->bits(); + switch(m_buffer.pixelformat) + { + case PIXELFORMAT_NONE : break; + case PIXELFORMAT_GREY : break; + case PIXELFORMAT_RGB332 : break; + case PIXELFORMAT_RGB555 : break; + case PIXELFORMAT_RGB555X: break; + case PIXELFORMAT_RGB565 : break; + case PIXELFORMAT_RGB565X: break; + case PIXELFORMAT_RGB24 : + { + kDebug() << "VideoDevicePool::getImage() fallback for no device - RGB24."; + int step=0; + for(int loop=0;loop < qimage->numBytes();loop+=4) + { + bits[loop] = m_buffer.data[step]; + bits[loop+1] = m_buffer.data[step+1]; + bits[loop+2] = m_buffer.data[step+2]; + bits[loop+3] = 255; + step+=3; + } + } + break; + case PIXELFORMAT_BGR24 : break; + { + int step=0; + for(int loop=0;loop < qimage->numBytes();loop+=4) + { + bits[loop] = m_buffer.data[step+2]; + bits[loop+1] = m_buffer.data[step+1]; + bits[loop+2] = m_buffer.data[step]; + bits[loop+3] = 255; + step+=3; + } + } + break; + case PIXELFORMAT_RGB32 : memcpy(bits,&m_buffer.data[0], m_buffer.data.size()); + break; + case PIXELFORMAT_BGR32 : break; + case PIXELFORMAT_YUYV : break; + case PIXELFORMAT_UYVY : break; + case PIXELFORMAT_YUV420P: break; + case PIXELFORMAT_YUV422P: break; + default: break; + } + } + kDebug() << "VideoDevicePool::getImage() exited successfuly."; + return EXIT_SUCCESS; } /*! @@ -394,142 +419,203 @@ int VideoDevicePool::getImage(QImage *qimage) int VideoDevicePool::selectInput(int newinput) { kDebug() << "VideoDevicePool::selectInput(" << newinput << ") called."; - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->selectInput(newinput); + if(m_videodevice.size()) + return m_videodevice[currentDevice()].selectInput(newinput); else - return EXIT_FAILURE; + return 0; } /*! \fn Kopete::AV::VideoDevicePool::fillDeviceKComboBox(KComboBox *combobox) */ -void VideoDevicePool::fillDeviceKComboBox(KComboBox *combobox) +int VideoDevicePool::fillDeviceKComboBox(KComboBox *combobox) { + /// @todo implement me kDebug() << "Called."; - if (combobox == NULL) - return; - combobox->clear(); - if (m_videodevices.size()) +// check if KComboBox is a valid pointer. + if (combobox != NULL) { - for (int loop = 0; loop < m_videodevices.size(); loop++) + combobox->clear(); + kDebug() << "Combobox cleaned."; + if(m_videodevice.size()) { - combobox->addItem(m_videodevices[loop]->m_name); - kDebug() << "Added device" << loop << ": " << m_videodevices[loop]->m_name; + for (int loop=0; loop < m_videodevice.size(); loop++) + { + combobox->addItem(m_videodevice[loop].m_name); + kDebug() << "Added device " << loop << ": " << m_videodevice[loop].m_name; + } + combobox->setCurrentIndex(currentDevice()); + combobox->setEnabled(true); + return EXIT_SUCCESS; } - combobox->setCurrentIndex(m_current_device); + combobox->setEnabled(false); } - combobox->setEnabled(m_videodevices.size()); + return EXIT_FAILURE; } /*! \fn Kopete::AV::VideoDevicePool::fillInputKComboBox(KComboBox *combobox) */ -void VideoDevicePool::fillInputKComboBox(KComboBox *combobox) +int VideoDevicePool::fillInputKComboBox(KComboBox *combobox) { + /// @todo implement me kDebug() << "Called."; - if (combobox == NULL) - return; - combobox->clear(); - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) + if (combobox != NULL) { - if (m_videodevices[m_current_device]->inputs() > 0) + combobox->clear(); + if ( !m_videodevice.isEmpty() && (currentDevice()>=0) && currentDevice() < m_videodevice.size() ) { - for (int loop = 0; loop < m_videodevices[m_current_device]->inputs(); loop++) + if(m_videodevice[currentDevice()].inputs()>0) { - combobox->addItem(m_videodevices[m_current_device]->m_input[loop].name); - kDebug() << "Added input" << loop << ": " << m_videodevices[m_current_device]->m_input[loop].name - << " (tuner: " << m_videodevices[m_current_device]->m_input[loop].hastuner << ")"; + for (int loop=0; loop < m_videodevice[currentDevice()].inputs(); loop++) + { + combobox->addItem(m_videodevice[currentDevice()].m_input[loop].name); + kDebug() << "Added input " << loop << ": " << m_videodevice[currentDevice()].m_input[loop].name << " (tuner: " << m_videodevice[currentDevice()].m_input[loop].hastuner << ")"; + } + combobox->setCurrentIndex(currentInput()); + combobox->setEnabled(true); + return EXIT_SUCCESS; } - combobox->setCurrentIndex(m_videodevices[m_current_device]->currentInput()); } + combobox->setEnabled(false); } - combobox->setEnabled(combobox->count()); + return EXIT_FAILURE; } /*! \fn Kopete::AV::VideoDevicePool::fillStandardKComboBox(KComboBox *combobox) */ -void VideoDevicePool::fillStandardKComboBox(KComboBox *combobox) +int VideoDevicePool::fillStandardKComboBox(KComboBox *combobox) { + /// @todo implement me kDebug() << "Called."; - if (combobox == NULL) - return; - combobox->clear(); - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) + if (combobox != NULL) { - if (m_videodevices[m_current_device]->inputs() > 0) + combobox->clear(); + if ( !m_videodevice.isEmpty() && currentDevice() < m_videodevice.size() ) { - for (unsigned int loop = 0; loop < 25; loop++) + if(m_videodevice[currentDevice()].inputs()>0) { - if (m_videodevices[m_current_device]->m_input[currentInput()].m_standards & (1 << loop)) + for (unsigned int loop=0; loop < 25; loop++) { - combobox->addItem(m_videodevices[m_current_device]->signalStandardName(1 << loop)); - kDebug() << "Added signal standard" << loop << ": " << m_videodevices[m_current_device]->signalStandardName(1 << loop); + if ( (m_videodevice[currentDevice()].m_input[currentInput()].m_standards) & (1 << loop) ) + combobox->addItem(m_videodevice[currentDevice()].signalStandardName( 1 << loop)); +/* + case STANDARD_PAL_B1 : return V4L2_STD_PAL_B1; break; + case STANDARD_PAL_G : return V4L2_STD_PAL_G; break; + case STANDARD_PAL_H : return V4L2_STD_PAL_H; break; + case STANDARD_PAL_I : return V4L2_STD_PAL_I; break; + case STANDARD_PAL_D : return V4L2_STD_PAL_D; break; + case STANDARD_PAL_D1 : return V4L2_STD_PAL_D1; break; + case STANDARD_PAL_K : return V4L2_STD_PAL_K; break; + case STANDARD_PAL_M : return V4L2_STD_PAL_M; break; + case STANDARD_PAL_N : return V4L2_STD_PAL_N; break; + case STANDARD_PAL_Nc : return V4L2_STD_PAL_Nc; break; + case STANDARD_PAL_60 : return V4L2_STD_PAL_60; break; + case STANDARD_NTSC_M : return V4L2_STD_NTSC_M; break; + case STANDARD_NTSC_M_JP : return V4L2_STD_NTSC_M_JP; break; + case STANDARD_NTSC_443 : return V4L2_STD_NTSC; break; // Using workaround value because my videodev2.h header seems to not include this standard in struct __u64 v4l2_std_id + case STANDARD_SECAM_B : return V4L2_STD_SECAM_B; break; + case STANDARD_SECAM_D : return V4L2_STD_SECAM_D; break; + case STANDARD_SECAM_G : return V4L2_STD_SECAM_G; break; + case STANDARD_SECAM_H : return V4L2_STD_SECAM_H; break; + case STANDARD_SECAM_K : return V4L2_STD_SECAM_K; break; + case STANDARD_SECAM_K1 : return V4L2_STD_SECAM_K1; break; + case STANDARD_SECAM_L : return V4L2_STD_SECAM_L; break; + case STANDARD_SECAM_LC : return V4L2_STD_SECAM; break; // Using workaround value because my videodev2.h header seems to not include this standard in struct __u64 v4l2_std_id + case STANDARD_ATSC_8_VSB : return V4L2_STD_ATSC_8_VSB; break; // ATSC/HDTV Standard officially not supported by V4L2 but exists in videodev2.h + case STANDARD_ATSC_16_VSB : return V4L2_STD_ATSC_16_VSB; break; // ATSC/HDTV Standard officially not supported by V4L2 but exists in videodev2.h + case STANDARD_PAL_BG : return V4L2_STD_PAL_BG; break; + case STANDARD_PAL_DK : return V4L2_STD_PAL_DK; break; + case STANDARD_PAL : return V4L2_STD_PAL; break; + case STANDARD_NTSC : return V4L2_STD_NTSC; break; + case STANDARD_SECAM_DK : return V4L2_STD_SECAM_DK; break; + case STANDARD_SECAM : return V4L2_STD_SECAM; break; + case STANDARD_525_60 : return V4L2_STD_525_60; break; + case STANDARD_625_50 : return V4L2_STD_625_50; break; + case STANDARD_ALL : return V4L2_STD_ALL; break; + + combobox->insertItem(m_videodevice[currentDevice()].m_input[loop].name); + kDebug() << "StandardKCombobox: Added input " << loop << ": " << m_videodevice[currentDevice()].m_input[loop].name << " (tuner: " << m_videodevice[currentDevice()].m_input[loop].hastuner << ")";*/ } - + combobox->setCurrentIndex(0); // FIXME: set to actual signal standard + combobox->setEnabled(combobox->count()); + return EXIT_SUCCESS; } - combobox->setCurrentIndex(0); // FIXME: set to actual signal standard - } + } + combobox->setEnabled(false); + } + return EXIT_FAILURE; +} + +/*! + \fn Kopete::AV::VideoDevicePool::scanDevices() + */ +int VideoDevicePool::scanDevices() +{ + /// @todo implement me + + if (m_videodevice.isEmpty()) { + kDebug() << "called"; +#if defined(__linux__) && defined(ENABLE_AV) + foreach (Solid::Device device, + Solid::Device::listFromType(Solid::DeviceInterface::Video, QString())) { + registerDevice( device ); + } + +#endif + kDebug() << "exited successfuly"; + } else { + kDebug() << "Not scanning: initial device list already loaded"; } - combobox->setEnabled(combobox->count()); + return EXIT_SUCCESS; } -bool VideoDevicePool::registerDevice( Solid::Device & device ) +void VideoDevicePool::registerDevice( Solid::Device & device ) { - kDebug() << "called, UDI is:\n " << device.udi(); + kDebug() << "New video device at " << device.udi(); const Solid::Device * vendorDevice = &device; - while (vendorDevice->isValid() && vendorDevice->vendor().isEmpty()) - vendorDevice = new Solid::Device(vendorDevice->parentUdi()); - /* NOTE: The device we register has usually an empty vendor string and a less meaningfull product string. - So we go up to the first parent device that has a non-empty vendor string, - because we find the expected strings describing the device there. - */ - if (vendorDevice->isValid()) - kDebug() << "vendor:" << vendorDevice->vendor() << ", product:" << vendorDevice->product(); - else - kDebug() << "vendor:" << device.vendor() << ", product:" << device.product(); - - if (device.isValid()) + while ( vendorDevice->isValid() && vendorDevice->vendor().isEmpty() ) + { + vendorDevice = new Solid::Device( vendorDevice->parentUdi() ); + } + if ( vendorDevice->isValid() ) { - Solid::Video * solidVideoDevice = device.as(); - if (solidVideoDevice) + kDebug() << "vendor: " << vendorDevice->vendor() << ", product: " << vendorDevice->product(); + } + Solid::Video * solidVideoDevice = device.as(); + if ( solidVideoDevice ) { + QStringList protocols = solidVideoDevice->supportedProtocols(); + if ( protocols.contains( "video4linux" ) ) { - QStringList protocols = solidVideoDevice->supportedProtocols(); - if (protocols.contains("video4linux")) + QStringList drivers = solidVideoDevice->supportedDrivers( "video4linux" ); + if ( drivers.contains( "video4linux" ) ) { - QStringList drivers = solidVideoDevice->supportedDrivers("video4linux"); - if (drivers.contains("video4linux")) + kDebug() << "V4L device path is" << solidVideoDevice->driverHandle( "video4linux" ).toString(); + VideoDevice videodevice; + videodevice.setUdi( device.udi() ); + videodevice.setFileName(solidVideoDevice->driverHandle( "video4linux" ).toString()); + kDebug() << "Found device " << videodevice.fileName(); + videodevice.open(); + if(videodevice.isOpen()) { - VideoDevice* videodevice = new VideoDevice; - videodevice->setUdi( device.udi() ); - videodevice->setFileName(solidVideoDevice->driverHandle("video4linux").toString()); - kDebug() << "V4L device path is" << solidVideoDevice->driverHandle("video4linux").toString(); - if (EXIT_SUCCESS == videodevice->open()) - { - bool cap = videodevice->canCapture(); - videodevice->close(); - if (cap) - { - if (m_videodevices.size() == 0) - m_current_device = 0; - m_videodevices.push_back(videodevice); - kDebug() << "Device is a valid video device, adding it to video device pool."; - return true; - } - else - kDebug() << "Device does not support capturing."; - } - else - kDebug() << "Device could not be opened."; - delete videodevice; + kDebug() << "File " << videodevice.fileName() << " was opened successfuly"; + videodevice.close(); + m_videodevice.push_back(videodevice); } } } - else - kDebug() << "Device is not a video device."; } - else - kDebug() << "Not a valid Solid device: device is not available in the system."; +} + +/*! + \fn Kopete::AV::VideoDevicePool::hasDevices() + */ +bool VideoDevicePool::hasDevices() +{ + /// @todo implement me + if(m_videodevice.size()) + return true; return false; } @@ -539,7 +625,7 @@ bool VideoDevicePool::registerDevice( Solid::Device & device ) int VideoDevicePool::size() { /// @todo implement me - return m_videodevices.size(); + return m_videodevice.size(); } /*! @@ -556,8 +642,8 @@ int VideoDevicePool::currentDevice() */ QString VideoDevicePool::currentDeviceUdi() { - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->udi(); + if (m_videodevice.size() && (m_current_device >= 0)) + return m_videodevice[m_current_device].udi(); else return QString(); } @@ -568,10 +654,7 @@ QString VideoDevicePool::currentDeviceUdi() int VideoDevicePool::currentInput() { /// @todo implement me - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->currentInput(); - else - return -1; + return m_videodevice[currentDevice()].currentInput(); } /*! @@ -580,20 +663,17 @@ int VideoDevicePool::currentInput() int VideoDevicePool::inputs() { /// @todo implement me - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) - return m_videodevices[m_current_device]->inputs(); - else - return 0; + return m_videodevice[currentDevice()].inputs(); } /*! - \fn int Kopete::AV::VideoDevicePool::getSavedDevice() - \brief Returns the index of the saved device + \fn void Kopete::AV::VideoDevicePool::loadSelectedDevice() + \brief Loads and selects the saved device */ -int VideoDevicePool::getSavedDevice() +void VideoDevicePool::loadSelectedDevice() { kDebug() << "called"; - if (m_videodevices.size()) + if (hasDevices()) { KConfigGroup config(KGlobal::config(), "Video Device Settings"); QString currentdevice = config.readEntry("Current Device", QString()); @@ -601,14 +681,14 @@ int VideoDevicePool::getSavedDevice() if (!currentdevice.isEmpty()) { kDebug() << "Saved device:" << currentdevice; - QVector::iterator vditerator; - for( vditerator = m_videodevices.begin(); vditerator != m_videodevices.end(); ++vditerator ) + VideoDeviceVector::iterator vditerator; + for( vditerator = m_videodevice.begin(); vditerator != m_videodevice.end(); ++vditerator ) { - if ((*vditerator)->udi() == currentdevice) + if ((*vditerator).udi() == currentdevice) { - int devIndex = std::distance (m_videodevices.begin(), vditerator); - kDebug() << "Saved device is available, device index is" << devIndex; - return devIndex; + m_current_device = std::distance (m_videodevice.begin(), vditerator); + kDebug() << "Saved device is available, setting device-index to" << m_current_device; + return; } } kDebug() << "Saved device is not available."; @@ -616,7 +696,6 @@ int VideoDevicePool::getSavedDevice() else kDebug() << "No device saved."; } - return -1; } /*! @@ -628,21 +707,21 @@ int VideoDevicePool::getSavedDevice() void VideoDevicePool::loadDeviceConfig() { kDebug() << "called"; - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) + if (hasDevices()) { KConfigGroup config(KGlobal::config(), "Video Device Settings"); // Load input and apply - const QString key_currentinput = QString::fromLocal8Bit( "Device %1 Current Input" ).arg( m_videodevices[m_current_device]->udi() ); + const QString key_currentinput = QString::fromLocal8Bit( "Device %1 Current Input" ).arg( m_videodevice[m_current_device].udi() ); const int currentinput = config.readEntry(key_currentinput, 0); kDebug() << "Setting input to" << currentinput; - if (currentinput != m_videodevices[m_current_device]->currentInput()) - m_videodevices[m_current_device]->selectInput(currentinput); + if (currentinput != m_videodevice[m_current_device].currentInput()) + m_videodevice[m_current_device].selectInput(currentinput); // Load video-controls and apply quint32 ctrl_id; qint32 ctrl_value; QString ctrl_key; bool ok = false; - const QString key_control_start = QString::fromLocal8Bit( "Device %1 Input %2 Control " ).arg( m_videodevices[m_current_device]->udi() ).arg( m_videodevices[m_current_device]->currentInput() ); + const QString key_control_start = QString::fromLocal8Bit( "Device %1 Input %2 Control " ).arg( m_videodevice[m_current_device].udi() ).arg( m_videodevice[m_current_device].currentInput() ); QStringList ctrl_keys = config.keyList().filter(key_control_start); kDebug() << "Found" << ctrl_keys.size() << "saved values for video-controls"; foreach (ctrl_key, ctrl_keys) @@ -659,7 +738,7 @@ void VideoDevicePool::loadDeviceConfig() if (ok && !tmpstr.isEmpty()) { kDebug() << "Setting control" << ctrl_id << "to value" << ctrl_value; - m_videodevices[m_current_device]->setControlValue(ctrl_id, ctrl_value); + m_videodevice[m_current_device].setControlValue(ctrl_id, ctrl_value); } else kDebug() << "Saved value for control" << ctrl_id << "is invalid:" << tmpstr; @@ -680,23 +759,23 @@ void VideoDevicePool::loadDeviceConfig() void VideoDevicePool::saveCurrentDeviceConfig() { kDebug() << "called"; - if ((m_current_device >= 0) && (m_current_device < m_videodevices.size())) + if (hasDevices()) { KConfigGroup config(KGlobal::config(), "Video Device Settings"); // Save current device: - kDebug() << "Current device:" << m_videodevices[m_current_device]->udi(); - config.writeEntry( "Current Device", m_videodevices[m_current_device]->udi() ); + kDebug() << "Current device:" << m_videodevice[m_current_device].udi(); + config.writeEntry( "Current Device", m_videodevice[m_current_device].udi() ); // Save current device name (for debugging only): - kDebug() << "Current device name:" << m_videodevices[m_current_device]->m_name; - const QString name = QString::fromLocal8Bit( "Device %1 Name" ).arg( m_videodevices[m_current_device]->udi() ); - config.writeEntry( name, m_videodevices[m_current_device]->m_name ); + kDebug() << "Current device name:" << m_videodevice[m_current_device].m_name; + const QString name = QString::fromLocal8Bit( "Device %1 Name" ).arg( m_videodevice[m_current_device].udi() ); + config.writeEntry( name, m_videodevice[m_current_device].m_name ); // Open device if closed: bool wasClosed = false; - if (!m_videodevices[m_current_device]->isOpen()) + if (!m_videodevice[m_current_device].isOpen()) { kDebug() << "Device is currently closed, will be opened."; wasClosed = true; - if (EXIT_SUCCESS != m_videodevices[m_current_device]->open()) + if (EXIT_SUCCESS != m_videodevice[m_current_device].open()) { kDebug() << "Failed to open the device. Saving aborted."; config.sync(); @@ -704,18 +783,18 @@ void VideoDevicePool::saveCurrentDeviceConfig() } } // Save current input: - kDebug() << "Current input:" << m_videodevices[m_current_device]->currentInput(); - const QString key_currentinput = QString::fromLocal8Bit( "Device %1 Current Input" ).arg( m_videodevices[m_current_device]->udi() ); - config.writeEntry( key_currentinput, m_videodevices[m_current_device]->currentInput() ); + kDebug() << "Current input:" << m_videodevice[m_current_device].currentInput(); + const QString key_currentinput = QString::fromLocal8Bit( "Device %1 Current Input" ).arg( m_videodevice[m_current_device].udi() ); + config.writeEntry( key_currentinput, m_videodevice[m_current_device].currentInput() ); // --- Save values of the controls ---: qint32 ctrl_value; - const QString key_control_start = QString::fromLocal8Bit( "Device %1 Input %2 Control " ).arg( m_videodevices[m_current_device]->udi() ).arg( m_videodevices[m_current_device]->currentInput() ); + const QString key_control_start = QString::fromLocal8Bit( "Device %1 Input %2 Control " ).arg( m_videodevice[m_current_device].udi() ).arg( m_videodevice[m_current_device].currentInput() ); // Save values of the numeric controls: - QList numCtrls = m_videodevices[m_current_device]->getSupportedNumericControls(); + QList numCtrls = m_videodevice[m_current_device].getSupportedNumericControls(); NumericVideoControl numCtrl; foreach (numCtrl, numCtrls) { - if (EXIT_SUCCESS == m_videodevices[m_current_device]->getControlValue(numCtrl.id, &ctrl_value)) + if (EXIT_SUCCESS == m_videodevice[m_current_device].getControlValue(numCtrl.id, &ctrl_value)) { kDebug() << "Numeric control:" << numCtrl.id << "value" << ctrl_value; config.writeEntry( key_control_start + QString::number(numCtrl.id), ctrl_value ); @@ -724,11 +803,11 @@ void VideoDevicePool::saveCurrentDeviceConfig() kDebug() << "Error: couldn't get current value for numeric control" << numCtrl.id; } // Save values of the boolean controls: - QList boolCtrls = m_videodevices[m_current_device]->getSupportedBooleanControls(); + QList boolCtrls = m_videodevice[m_current_device].getSupportedBooleanControls(); BooleanVideoControl boolCtrl; foreach (boolCtrl, boolCtrls) { - if (EXIT_SUCCESS == m_videodevices[m_current_device]->getControlValue(boolCtrl.id, &ctrl_value)) + if (EXIT_SUCCESS == m_videodevice[m_current_device].getControlValue(boolCtrl.id, &ctrl_value)) { kDebug() << "Boolean control:" << boolCtrl.id << "value" << ctrl_value; config.writeEntry( key_control_start + QString::number(boolCtrl.id), ctrl_value ); @@ -737,11 +816,11 @@ void VideoDevicePool::saveCurrentDeviceConfig() kDebug() << "Error: couldn't get current value for boolean control" << numCtrl.id; } // Save values of the menu controls: - QList menuCtrls = m_videodevices[m_current_device]->getSupportedMenuControls(); + QList menuCtrls = m_videodevice[m_current_device].getSupportedMenuControls(); MenuVideoControl menuCtrl; foreach (menuCtrl, menuCtrls) { - if (EXIT_SUCCESS == m_videodevices[m_current_device]->getControlValue(menuCtrl.id, &ctrl_value)) + if (EXIT_SUCCESS == m_videodevice[m_current_device].getControlValue(menuCtrl.id, &ctrl_value)) { kDebug() << "Menu-control:" << menuCtrl.id << "value" << ctrl_value; config.writeEntry( key_control_start + QString::number(menuCtrl.id), ctrl_value ); @@ -753,7 +832,7 @@ void VideoDevicePool::saveCurrentDeviceConfig() // Close device again (if it was closed before): if (wasClosed) { - if (EXIT_SUCCESS == m_videodevices[m_current_device]->close()) + if (EXIT_SUCCESS == m_videodevice[m_current_device].close()) kDebug() << "Device successfully closed."; else kDebug() << "Error: failed to close the device."; @@ -765,47 +844,47 @@ void VideoDevicePool::saveCurrentDeviceConfig() void VideoDevicePool::deviceAdded( const QString & udi ) { - kDebug() << "called with UDI" << udi; + kDebug() << "("<< udi << ") called"; Solid::Device dev( udi ); if ( dev.is() ) { - kDebug() << "Device is a video device, trying to register it."; - if ( registerDevice( dev ) ) - emit deviceRegistered( udi ); + registerDevice( dev ); + emit deviceRegistered( udi ); } - else - kDebug() << "Device is not a video device"; } void VideoDevicePool::deviceRemoved( const QString & udi ) { - kDebug() << "called with UDI" << udi; + kDebug() << "("<< udi << ") called"; int i = 0; - foreach ( VideoDevice* vd, m_videodevices ) + m_ready.lock(); + foreach ( VideoDevice vd, m_videodevice ) { - if ( vd->udi() == udi ) + if ( vd.udi() == udi ) { - kDebug() << "Video device with UDI" << udi << "has been removed!"; - delete m_videodevices[i]; // NOTE: device is closed in destructor - m_videodevices.remove( i ); + kDebug() << "Video device '" << udi << "' has been removed!"; + // not sure if this is safe but at this point the device node is gone already anyway + m_videodevice.remove( i ); if (m_current_device == i) { - if (m_videodevices.size()) - m_current_device = 0; - else - m_current_device = -1; + m_current_device = 0; m_clients = 0; } else if (m_current_device > i) { m_current_device--; } + m_ready.unlock(); emit deviceUnregistered( udi ); + /* NOTE: do not emit deviceUnregistered( udi ) with mutex locked ! => potential deadlock ! */ return; } else + { i++; + } } + m_ready.unlock(); } } // namespace AV diff --git a/kopete/libkopete/avdevice/videodevicepool.h b/kopete/libkopete/avdevice/videodevicepool.h index 8c6c8fd..f83842a 100644 --- a/kopete/libkopete/avdevice/videodevicepool.h +++ b/kopete/libkopete/avdevice/videodevicepool.h @@ -25,6 +25,8 @@ #include "videoinput.h" #include #include +#include +#include #include #include "videodevice.h" #include "kopete_export.h" @@ -32,6 +34,11 @@ #include #include +// Uncomment this line and comment out the include and using lines to +// revert to standard vector if you hit issues. It should all be fine though. +// typedef QVector VideoDeviceVector; +#include "videodevicevector.h" +using Kopete::AV::VideoDeviceVector; namespace Kopete { @@ -64,11 +71,14 @@ public: int readFrame(); int getImage(QImage *qimage); int selectInput(int newinput); + int scanDevices(); + void registerDevice( Solid::Device & dev ); + bool hasDevices(); int size(); ~VideoDevicePool(); - void fillDeviceKComboBox(KComboBox *combobox); - void fillInputKComboBox(KComboBox *combobox); - void fillStandardKComboBox(KComboBox *combobox); + int fillDeviceKComboBox(KComboBox *combobox); + int fillInputKComboBox(KComboBox *combobox); + int fillStandardKComboBox(KComboBox *combobox); QString currentDeviceUdi(); int currentDevice(); int currentInput(); @@ -101,14 +111,14 @@ protected slots: protected: int xioctl(int request, void *arg); int errnoReturn(const char* s); - bool registerDevice( Solid::Device & dev ); - int showDeviceCapabilities(int device = -1); - int getSavedDevice(); + int showDeviceCapabilities(unsigned int device); + void loadSelectedDevice(); void loadDeviceConfig(); // Load configuration parameters; int m_current_device; - QVector m_videodevices; /*!< Vector of pointers to the available video devices */ + VideoDeviceVector m_videodevice; // Vector to be filled with found devices struct imagebuffer m_buffer; // only used when no devices were found + QMutex m_ready; private: VideoDevicePool(); diff --git a/kopete/libkopete/avdevice/videodevicevector.cpp b/kopete/libkopete/avdevice/videodevicevector.cpp new file mode 100644 index 0000000..bc04011 --- /dev/null +++ b/kopete/libkopete/avdevice/videodevicevector.cpp @@ -0,0 +1,62 @@ +/* + videodevicevector.cpp - Kopete Video Device List Abstration + + Copyright (c) 2009 by Alan Jones + + Kopete (c) 2002-2009 by the Kopete developers + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public * + * License as published by the Free Software Foundation; either * + * version 3 of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ************************************************************************* +*/ + +#include "videodevicevector.h" + +namespace Kopete { + +namespace AV { + +VideoDevice& VideoDeviceVector::operator[] (int i) + { + if (i>=size()) + { + //we're outside the range so let's return a default camera not available VideoDevice + return fallback; + } + + //if we've made it here then we're within range + return QVector::operator[](i); + } + +const VideoDevice& VideoDeviceVector::operator[] (int i) const + { + return at(i); + } + +const VideoDevice& VideoDeviceVector::at(int i) const + { + if (i>=size()) + { + //we're outside the range so let's return a default camera not available VideoDevice + return fallback; + } + + //if we've made it here then we're within range + return QVector::operator[](i); + } + +} + +} diff --git a/kopete/libkopete/avdevice/videodevicevector.h b/kopete/libkopete/avdevice/videodevicevector.h new file mode 100644 index 0000000..6b64c47 --- /dev/null +++ b/kopete/libkopete/avdevice/videodevicevector.h @@ -0,0 +1,63 @@ +/* + videodevicevector.h - Kopete Video Device List Abstration + + Copyright (c) 2009 by Alan Jones + + Kopete (c) 2002-2009 by the Kopete developers + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public * + * License as published by the Free Software Foundation; either * + * version 3 of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ************************************************************************* +*/ + +#ifndef KOPETE_AVVIDEODEVICEVECTOR_H +#define KOPETE_AVVIDEODEVICEVECTOR_H + +#include "videodevice.h" +#include "dummyvideodevice.h" + +namespace Kopete { + +namespace AV { + +/** +@author Kopete Developers +*/ + +class VideoDeviceVector : public QVector +{ + +public: + VideoDeviceVector() {} + ~VideoDeviceVector() {} + + VideoDevice& operator[] (int i); + + const VideoDevice& operator[] (int i) const; + + const VideoDevice& at(int i) const; + +private: + + DummyVideoDevice fallback; +}; + +} + +} + + + +#endif diff --git a/kopete/libkopete/ui/avatarselectorwidget.cpp b/kopete/libkopete/ui/avatarselectorwidget.cpp index b18ba2b..ddb7e11 100644 --- a/kopete/libkopete/ui/avatarselectorwidget.cpp +++ b/kopete/libkopete/ui/avatarselectorwidget.cpp @@ -118,6 +118,7 @@ AvatarSelectorWidget::AvatarSelectorWidget(QWidget *parent) #ifndef VIDEOSUPPORT_DISABLED VideoDevicePool* devicePool = VideoDevicePool::self(); + devicePool->scanDevices();//We've to be sure that this has been done if( devicePool->size() == 0 ){ d->mainWidget.buttonFromWebcam->hide(); }