36
36
#define KMIXPA_APP_CAPTURE 3
37
37
#define KMIXPA_WIDGET_MAX KMIXPA_APP_CAPTURE
39
#define KMIXPA_EVENT_KEY "sink-input-by-media-role:event"
39
41
static unsigned int refcount = 0;
40
42
static pa_glib_mainloop *s_mainloop = NULL;
41
43
static pa_context *s_context = NULL;
191
193
s.index = s.device_index = i->index;
192
s.name = QString(i->name).replace(' ', '_');
194
s.name = QString::fromUtf8(i->name).replace(' ', '_');
193
195
s.description = QString::fromUtf8(i->description);
194
196
s.icon_name = QString::fromUtf8(pa_proplist_gets(i->proplist, PA_PROP_DEVICE_ICON_NAME));
195
197
s.volume = i->volume;
244
246
s.index = s.device_index = i->index;
245
s.name = QString(i->name).replace(' ', '_');
247
s.name = QString::fromUtf8(i->name).replace(' ', '_');
246
248
s.description = QString::fromUtf8(i->description);
247
249
s.icon_name = QString::fromUtf8(pa_proplist_gets(i->proplist, PA_PROP_DEVICE_ICON_NAME));
248
250
s.volume = i->volume;
309
311
if ((t = pa_proplist_gets(i->proplist, "module-stream-restore.id"))) {
310
if (strcmp(t, "sink-input-by-media-role:event") == 0) {
312
if (strcmp(t, KMIXPA_EVENT_KEY) == 0) {
311
313
kWarning(67100) << "Ignoring sink-input due to it being designated as an event and thus handled by the Event slider";
316
QString prefix = QString("%1: ").arg(i18n("Unknown Application"));
318
QString appname = i18n("Unknown Application");
317
319
if (clients.contains(i->client))
318
prefix = QString("%1: ").arg(clients[i->client]);
320
appname = clients[i->client];
322
QString prefix = QString("%1: ").arg(appname);
321
325
s.index = i->index;
322
326
s.device_index = i->sink;
323
327
s.description = prefix + QString::fromUtf8(i->name);
324
s.name = QString("stream:") + i->index;
328
s.name = QString("stream:") + QString::number(i->index); //appname.replace(' ', '_').toLower();
325
329
s.icon_name = getIconNameFromProplist(i->proplist);
326
330
s.volume = i->volume;
327
331
s.channel_map = i->channel_map;
328
332
s.mute = !!i->mute;
329
s.stream_restore_rule = t;
333
s.stream_restore_rule = QString::fromUtf8(t);
331
335
translateMasksAndMaps(s);
373
QString prefix = QString("%1: ").arg(i18n("Unknown Application"));
377
QString appname = i18n("Unknown Application");
374
378
if (clients.contains(i->client))
375
prefix = QString("%1: ").arg(clients[i->client]);
379
appname = clients[i->client];
381
QString prefix = QString("%1: ").arg(appname);
378
384
s.index = i->index;
379
385
s.device_index = i->source;
380
386
s.description = prefix + QString::fromUtf8(i->name);
381
s.name = QString("stream:") + i->index;
387
s.name = QString("stream:") + QString::number(i->index); //appname.replace(' ', '_').toLower();
382
388
s.icon_name = getIconNameFromProplist(i->proplist);
383
389
//s.volume = i->volume;
384
390
s.volume = captureDevices[i->source].volume;
385
391
s.channel_map = i->channel_map;
386
392
//s.mute = !!i->mute;
387
393
s.mute = captureDevices[i->source].mute;
388
s.stream_restore_rule = pa_proplist_gets(i->proplist, "module-stream-restore.id");
394
s.stream_restore_rule = QString::fromUtf8(pa_proplist_gets(i->proplist, "module-stream-restore.id"));
390
396
translateMasksAndMaps(s);
447
454
rule.volume.values[0] = PA_VOLUME_NORM;
448
455
rule.mute = false;
449
456
rule.device = "";
450
s_RestoreRules["sink-input-by-media-role:event"] = rule;
452
devinfo s = create_role_devinfo("sink-input-by-media-role:event");
453
outputRoles[s.index] = s;
454
kDebug(67100) << "Initialising restore rule for new user: " << s.description;
456
if (s_mixers.contains(KMIXPA_APP_PLAYBACK))
457
s_RestoreRules[KMIXPA_EVENT_KEY] = rule;
458
kDebug(67100) << "Initialising restore rule for new user: " << i18n("Event Sounds");
461
if (s_mixers.contains(KMIXPA_APP_PLAYBACK)) {
462
// If we have rules, it will be created below... but if no rules
463
// then we add it here.
464
if (!outputRoles.contains(PA_INVALID_INDEX)) {
465
devinfo s = create_role_devinfo(KMIXPA_EVENT_KEY);
466
outputRoles[s.index] = s;
457
468
s_mixers[KMIXPA_APP_PLAYBACK]->addWidget(s.index);
460
if (s_mixers.contains(KMIXPA_APP_PLAYBACK))
461
471
s_mixers[KMIXPA_APP_PLAYBACK]->triggerUpdate();
465
kDebug(67100) << "Got some info about restore rule: " << i->name << i->device;
478
QString name = QString::fromUtf8(i->name);
479
kDebug(67100) << QString("Got some info about restore rule: '%1' (Device: %2)").arg(name).arg(i->device ? i->device : "None");
466
480
restoreRule rule;
467
481
rule.channel_map = i->channel_map;
468
482
rule.volume = i->volume;
469
483
rule.mute = !!i->mute;
470
484
rule.device = i->device;
471
s_RestoreRules[i->name] = rule;
473
// We only want to know about Sound Events for now...
474
if (strcmp(i->name, "sink-input-by-media-role:event") == 0) {
475
devinfo s = create_role_devinfo(i->name);
476
bool is_new = !outputRoles.contains(s.index);
477
outputRoles[s.index] = s;
479
if (is_new && s_mixers.contains(KMIXPA_APP_PLAYBACK))
480
s_mixers[KMIXPA_APP_PLAYBACK]->addWidget(s.index);
486
if (rule.channel_map.channels < 1 && name == KMIXPA_EVENT_KEY) {
487
// Stream restore rules may not have valid volumes/channel maps (as these are optional)
488
// but we need a valid volume+channelmap for our events sounds so fix it up.
489
rule.channel_map.channels = 1;
490
rule.channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
491
rule.volume.channels = 1;
492
rule.volume.values[0] = PA_VOLUME_NORM;
495
s_RestoreRules[name] = rule;
497
if (s_mixers.contains(KMIXPA_APP_PLAYBACK)) {
498
// We only want to know about Sound Events for now...
499
if (name == KMIXPA_EVENT_KEY) {
500
devinfo s = create_role_devinfo(name);
501
bool is_new = !outputRoles.contains(s.index);
502
outputRoles[s.index] = s;
505
s_mixers[KMIXPA_APP_PLAYBACK]->addWidget(s.index);
788
814
Volume v(dev.chanMask, PA_VOLUME_NORM, PA_VOLUME_MUTED, true, false);
789
815
setVolumeFromPulse(v, dev);
790
816
MixDevice* md = new MixDevice( _mixer, dev.name, dev.description, dev.icon_name, ms);
791
md->setEthereal(true);
792
817
md->addPlaybackVolume(v);
793
818
md->setMuted(dev.mute);
794
819
m_mixDevices.append(md);
1096
1121
restoreRule &rule = s_RestoreRules[iter->stream_restore_rule];
1097
1122
pa_ext_stream_restore_info info;
1098
info.name = iter->stream_restore_rule.toAscii().constData();
1123
info.name = iter->stream_restore_rule.toUtf8().constData();
1099
1124
info.channel_map = rule.channel_map;
1100
1125
info.volume = genVolumeForPulse(*iter, md->playbackVolume());
1101
info.device = rule.device.isEmpty() ? NULL : rule.device.toAscii().constData();
1126
info.device = rule.device.isEmpty() ? NULL : rule.device.toUtf8().constData();
1102
1127
info.mute = (md->isMuted() ? 1 : 0);
1104
1129
pa_operation* o;
1154
1179
// Lookup the stream index.
1155
1180
uint32_t stream_index = PA_INVALID_INDEX;
1156
const char* stream_restore_rule = NULL;
1181
QString stream_restore_rule = "";
1157
1182
devmap::iterator iter;
1158
1183
devmap *map = get_widget_map(m_devnum);
1159
1184
for (iter = map->begin(); iter != map->end(); ++iter) {
1160
1185
if (iter->name == id) {
1161
1186
stream_index = iter->index;
1162
stream_restore_rule = iter->stream_restore_rule.isEmpty() ? NULL : iter->stream_restore_rule.toAscii().constData();
1187
stream_restore_rule = iter->stream_restore_rule;
1172
1197
if (destId.isEmpty()) {
1173
1198
// We want to remove any specific device in the stream restore rule.
1174
if (!stream_restore_rule || !s_RestoreRules.contains(stream_restore_rule)) {
1199
if (stream_restore_rule.isEmpty() || !s_RestoreRules.contains(stream_restore_rule)) {
1175
1200
kWarning(67100) << "Mixer_PULSE::moveStream(): Trying to set Automatic on a stream with no rule";
1177
1202
restoreRule &rule = s_RestoreRules[stream_restore_rule];
1178
1203
pa_ext_stream_restore_info info;
1179
info.name = stream_restore_rule;
1204
info.name = stream_restore_rule.toUtf8().constData();
1180
1205
info.channel_map = rule.channel_map;
1181
1206
info.volume = rule.volume;
1182
1207
info.device = NULL;
1193
1218
pa_operation* o;
1194
1219
if (KMIXPA_APP_PLAYBACK == m_devnum) {
1195
if (!(o = pa_context_move_sink_input_by_name(s_context, stream_index, destId.toAscii().constData(), NULL, NULL))) {
1220
if (!(o = pa_context_move_sink_input_by_name(s_context, stream_index, destId.toUtf8().constData(), NULL, NULL))) {
1196
1221
kWarning(67100) << "pa_context_move_sink_input_by_name() failed";
1200
if (!(o = pa_context_move_source_output_by_name(s_context, stream_index, destId.toAscii().constData(), NULL, NULL))) {
1225
if (!(o = pa_context_move_source_output_by_name(s_context, stream_index, destId.toUtf8().constData(), NULL, NULL))) {
1201
1226
kWarning(67100) << "pa_context_move_source_output_by_name() failed";