aboutsummaryrefslogblamecommitdiff
path: root/lib/output.cpp
blob: 0d0e4de99ec52a0b49523041f33142dc8e89221c (plain) (tree)































































































































































































                                                                                    
// Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com>
//
// Use, modification and distribution is allowed without limitation,
// warranty, or liability of any kind.
//

#include <QtGui>
#include <QObject>
#include <QStringList>
#include <QApplication>
#include <QTimer>

#include "output.h"
#include "visualization.h"

#include <stdio.h>

// static methods

static QList<OutputFactory*> *factories = 0;
static QStringList files;
static QTimer *timer = 0;

static void checkFactories()
{
    if ( ! factories )
    {
        files.clear();
        factories = new QList<OutputFactory *>;

        QDir pluginsDir ( qApp->applicationDirPath() );
        pluginsDir.cdUp();
        pluginsDir.cd ( "lib/qmmp/Output" );
        foreach ( QString fileName, pluginsDir.entryList ( QDir::Files ) )
        {
            QPluginLoader loader ( pluginsDir.absoluteFilePath ( fileName ) );
            QObject *plugin = loader.instance();
            if ( loader.isLoaded() )
            {
                qDebug ( "Output: plugin loaded - %s", qPrintable ( fileName ) );
            }
            OutputFactory *factory = 0;
            if ( plugin )
                factory = qobject_cast<OutputFactory *> ( plugin );

            if ( factory )
            {
                Output::registerFactory ( factory );
                files << pluginsDir.absoluteFilePath(fileName);
            }
        }
    }
}

void Output::registerFactory ( OutputFactory *fact )
{
    factories->append ( fact );
}

Output *Output::create ( QObject *parent )
{
    Output *output = 0;

    checkFactories();
    if ( factories->isEmpty () )
    {
        qDebug("Output: unable to find output plugins");
        return output;
    }
    QSettings settings ( QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat );
    QString pluginFileName =
        settings.value("Output/plugin_file","libalsa.so").toString();
    int j = 0;
    for (int i = 0; i < factories->size(); ++i)
    {
        if (files.at(i).section('/',-1) == pluginFileName)
            j = i;
    }
    OutputFactory *fact = factories->at ( j );
    if ( fact )
    {
        output = fact->create ( parent );
    }
    switch ((int) output->volumeControl())
    {
    case Output::Standard:
        {
            break;
        }
    case Output::Custom:
        {
            timer = new QTimer(output);
            connect(timer, SIGNAL(timeout()), output, SLOT(checkVolume()));
            timer->start(125);
            break;
        }
    case Output::Disabled:
        {
            break;
        }
    }
    return output;
}

QList<OutputFactory*> *Output::outputFactories()
{
    checkFactories();
    return factories;
}

QStringList Output::outputFiles()
{
    checkFactories();
    return files;
}

Output::Output ( QObject* parent, VolumeType vt) : QThread (parent), r (stackSize())
{
    qRegisterMetaType<OutputState>("OutputState");
    m_vol = vt;
}


Output::~Output()
{}

void Output::error ( const QString &e )
{
    emit stateChanged ( OutputState ( e ) );
}


void Output::addVisual ( Visualization *v )
{
    if ( visuals.indexOf ( v ) == -1 )
    {
        visuals.append ( v );
    }
}


void Output::removeVisual ( Visualization *v )
{
    visuals.removeAll ( v );
}

void Output::dispatchVisual ( Buffer *buffer, unsigned long written,
                              int chan, int prec )
{
    if ( ! buffer || !visuals.size())
        return;
    Visualization *visual = 0;
    foreach (visual , visuals );
    {
        visual->mutex()->lock ();
        visual->add ( buffer, written, chan, prec );
        visual->mutex()->unlock();
    }
}


void Output::prepareVisuals()
{
    //Visual *visual = visuals.first();
    /*while (visual) {
    visual->mutex()->lock();
    visual->prepare();
    visual->mutex()->unlock();

    visual = visuals.next();
    }*/
}

void Output::dispatch(OutputState::Type st)
{
    emit stateChanged ( OutputState(st) );
}

void Output::dispatch(long s, unsigned long w, int b, int f, int p, int c)
{
    emit stateChanged ( OutputState(s, w, b, f, p, c) );
}

void Output::dispatch ( const OutputState &st )
{
    emit stateChanged ( st );
}

void Output::dispatchVolume(int L, int R)
{
    emit stateChanged ( OutputState(L, R) );
}