You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.3 KiB
155 lines
4.3 KiB
/*****************************************************************************
|
|
* Copyright (C) 2019 VLC authors and VideoLAN
|
|
*
|
|
* 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 "audio_device_model.hpp"
|
|
#include "player/player_controller.hpp"
|
|
#include <vlc_player.h>
|
|
#include <vlc_aout.h>
|
|
|
|
extern "C" {
|
|
|
|
static void on_player_aout_device_changed(audio_output_t *,const char *device, void *data)
|
|
{
|
|
AudioDeviceModel* that = static_cast<AudioDeviceModel*>(data);
|
|
QMetaObject::invokeMethod(that, [that, device=QString::fromUtf8(device)](){
|
|
that->updateCurrent(device);
|
|
}, Qt::QueuedConnection);
|
|
}
|
|
|
|
}
|
|
|
|
static const struct vlc_player_aout_cbs player_aout_cbs = {
|
|
nullptr,
|
|
nullptr,
|
|
on_player_aout_device_changed
|
|
};
|
|
|
|
AudioDeviceModel::AudioDeviceModel(vlc_player_t *player, QObject *parent)
|
|
: QAbstractListModel(parent)
|
|
, m_player(player)
|
|
{
|
|
{
|
|
vlc_player_locker locker{m_player};
|
|
m_player_aout_listener = vlc_player_aout_AddListener(m_player, &player_aout_cbs, this);
|
|
}
|
|
|
|
m_aout = vlc_player_aout_Hold(m_player);
|
|
if (m_aout)
|
|
m_inputs = aout_DevicesList(m_aout, &m_ids, &m_names);
|
|
}
|
|
|
|
AudioDeviceModel::~AudioDeviceModel()
|
|
{
|
|
for (int i=0; i<m_inputs; i++)
|
|
{
|
|
free(m_ids[i]);
|
|
free(m_names[i]);
|
|
}
|
|
|
|
free(m_ids);
|
|
free(m_names);
|
|
|
|
vlc_player_locker locker{m_player};
|
|
vlc_player_aout_RemoveListener(m_player, m_player_aout_listener);
|
|
|
|
if (m_aout)
|
|
aout_Release(m_aout);
|
|
}
|
|
|
|
Qt::ItemFlags AudioDeviceModel::flags(const QModelIndex &) const
|
|
{
|
|
return Qt::ItemIsUserCheckable;
|
|
}
|
|
|
|
int AudioDeviceModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid())
|
|
return 0;
|
|
|
|
return m_inputs > 0 ? m_inputs : 0;
|
|
}
|
|
|
|
QVariant AudioDeviceModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
int row = index.row();
|
|
if (!index.isValid())
|
|
return QVariant();
|
|
if (row < 0 || row >= m_inputs)
|
|
return QVariant();
|
|
|
|
const char *name = m_names[row];
|
|
if (role == Qt::DisplayRole)
|
|
return qfu(name);
|
|
else if (role == Qt::CheckStateRole)
|
|
return QVariant::fromValue<bool>((!m_current.isEmpty() && (m_ids[row] == m_current)) ||
|
|
(m_current.isEmpty() && m_ids[row] && m_ids[row][0] == '\0' )) ;
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
bool AudioDeviceModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
{
|
|
int row = index.row();
|
|
if (!index.isValid())
|
|
return false;
|
|
if (row < 0 || row >= m_inputs)
|
|
return false;
|
|
if (role != Qt::CheckStateRole)
|
|
return false;
|
|
if (!value.canConvert<bool>())
|
|
return false;
|
|
bool select = value.toBool();
|
|
if (select)
|
|
{
|
|
aout_DeviceSet(m_aout, m_ids[row]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void AudioDeviceModel::updateCurrent(QString current)
|
|
{
|
|
if (current == m_current)
|
|
return;
|
|
std::swap(current, m_current);
|
|
|
|
int oldIndex = -1;
|
|
int currentIndex = -1;
|
|
|
|
for(int i=0; i<m_inputs; i++)
|
|
{
|
|
if(m_ids[i] == m_current){
|
|
currentIndex = i;
|
|
}
|
|
if(m_ids[i] == current){
|
|
oldIndex = i;
|
|
}
|
|
}
|
|
|
|
if(oldIndex >= 0)
|
|
emit dataChanged(index(oldIndex), index(oldIndex), { Qt::DisplayRole, Qt::CheckStateRole });
|
|
if(currentIndex >= 0)
|
|
emit dataChanged(index(currentIndex), index(currentIndex), { Qt::DisplayRole, Qt::CheckStateRole });
|
|
}
|
|
|
|
QHash<int, QByteArray> AudioDeviceModel::roleNames() const
|
|
{
|
|
return QHash<int, QByteArray>{
|
|
{Qt::DisplayRole, "display"},
|
|
{Qt::CheckStateRole, "checked"}
|
|
};
|
|
}
|
|
|