~ubuntu-branches/ubuntu/feisty/kdetv/feisty

« back to all changes in this revision

Viewing changes to kdetv/plugins/mixer/oss/kdetv_oss.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-09-17 23:25:16 UTC
  • Revision ID: james.westby@ubuntu.com-20050917232516-9wdsn3ckagbqieh8
Tags: upstream-0.8.8
ImportĀ upstreamĀ versionĀ 0.8.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Copyright (C) 2002 George Staikos <staikos@kde.org>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Library General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Library General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Library General Public License
 
16
 * along with this library; see the file COPYING.LIB.  If not, write to
 
17
 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 
18
 * Boston, MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
 
 
22
#include <qwidget.h>
 
23
#include <klocale.h>
 
24
#include "kdetv_oss.h"
 
25
#include <kdebug.h>
 
26
#include <kconfig.h>
 
27
#include <kmessagebox.h>
 
28
#include <assert.h>
 
29
#include <qlabel.h>
 
30
#include <qlayout.h>
 
31
#include <qcombobox.h>
 
32
#include <qframe.h>
 
33
 
 
34
 
 
35
#include <sys/ioctl.h>
 
36
#include <errno.h>
 
37
#include <fcntl.h>
 
38
#include <sys/types.h>
 
39
#include <unistd.h>
 
40
#include <stdlib.h>
 
41
 
 
42
#if defined(__linux__)
 
43
#include <sys/soundcard.h>
 
44
#elif defined(__FreeBSD__)
 
45
#include "machine/soundcard.h"
 
46
#elif defined(__NetBSD__)
 
47
#include <soundcard.h>
 
48
#endif
 
49
 
 
50
 
 
51
const char *const devNames[] = SOUND_DEVICE_LABELS;
 
52
 
 
53
 
 
54
QWidget *KdetvOSS::configWidget(QWidget *parent, const char *name)
 
55
{
 
56
    QFrame *w = new QFrame(parent, name);
 
57
    QGridLayout *g = new QGridLayout(w, 7, 7);
 
58
 
 
59
        g->addMultiCellWidget(new QLabel(i18n("Physical mixer:"), w), 0, 0, 0, 2);
 
60
        _cfg_devs = new QComboBox(w, "Device List");
 
61
        g->addMultiCellWidget(_cfg_devs, 0, 0, 3, 7);
 
62
 
 
63
        _cfg_devs->clear();
 
64
        _cfg_devs->insertStringList(_devlist);
 
65
 
 
66
        connect(_cfg_devs, SIGNAL(activated(const QString&)), 
 
67
            this, SLOT(deviceChanged(const QString&)));
 
68
 
 
69
        g->addMultiCellWidget(new QLabel(i18n("Mixer device:"), w), 1, 1, 0, 2);
 
70
        _cfg_mixers = new QComboBox(w, "Mixer List");
 
71
        g->addMultiCellWidget(_cfg_mixers, 1, 1, 3, 7);
 
72
 
 
73
        _cfg_mixers->clear();
 
74
        _cfg_mixers->insertStringList(_mixerMap[_devlist[0]]);
 
75
        //kdDebug() << "Mixer size: " << _mixers.count()
 
76
        //        << " Dev size: " << _devlist.count() << endl;
 
77
 
 
78
        if (!_dev.isEmpty()) {
 
79
                for (int i = 0; i < _cfg_devs->count(); i++) {
 
80
                        if (_cfg_devs->text(i) == _dev) {
 
81
                                _cfg_devs->setCurrentItem(i);
 
82
                                _cfg_devs->setEditText(_dev);
 
83
                                break;
 
84
                        }
 
85
                }
 
86
        } else {
 
87
        KMessageBox::error(0L,
 
88
                           i18n("No mixers found. Check you OSS driver installation."),
 
89
                           i18n("No OSS Mixers Found"));
 
90
        delete w;
 
91
        return NULL;
 
92
    }
 
93
 
 
94
        if (!_currentMixer.isEmpty()) {
 
95
                for (int i = 0; i < _cfg_mixers->count(); i++) {
 
96
                        if (_cfg_mixers->text(i) == _currentMixer) {
 
97
                                _cfg_mixers->setCurrentItem(i);
 
98
                                _cfg_mixers->setEditText(_currentMixer);
 
99
                                break;
 
100
                        }
 
101
                }
 
102
        }
 
103
 
 
104
        //kdDebug() << "Kdetv OSS plugin: Created a configuration widget!" << endl;
 
105
        return w;
 
106
}
 
107
 
 
108
 
 
109
KdetvOSS::KdetvOSS(Kdetv *ktv, QObject *parent, const char* name)
 
110
    : KdetvMixerPlugin(ktv, "ossmixer", parent,name), _muted(false)
 
111
{
 
112
        kdDebug() << "Kdetv OSS plugin loaded successfully." << endl;
 
113
        
 
114
        _fd = -1;
 
115
        _dev = "";
 
116
        _devnum = 0;  
 
117
        QString dev;
 
118
 
 
119
    dev = "/dev/mixer%1";
 
120
        if (!access("/dev/sound/mixer", R_OK|W_OK)) {
 
121
                // we are using devfs, so change the device divining string 
 
122
                dev = "/dev/sound/mixer%1";     
 
123
                _devlist << "/dev/sound/mixer";
 
124
        }
 
125
        if (!access("/dev/mixer", R_OK|W_OK)) {
 
126
                _devlist << "/dev/mixer";
 
127
        }
 
128
        for (int i = 0; i < 9; i++) {
 
129
                if (!access(dev.arg(i).local8Bit(), R_OK|W_OK)) {
 
130
                        _devlist << dev.arg(i);
 
131
                }
 
132
        }
 
133
 
 
134
        if (!access("/dev/dsp", R_OK|W_OK)) {
 
135
                _devlist << "/dev/dsp";
 
136
        }
 
137
    dev = "/dev/dsp%1";
 
138
        for (int i = 0; i < 9; i++) {
 
139
                if (!access(dev.arg(i).local8Bit(), R_OK|W_OK)) {
 
140
                        _devlist << dev.arg(i);
 
141
                }
 
142
        }
 
143
 
 
144
        probeDevices();
 
145
        if (_fd != -1)
 
146
        close(_fd);
 
147
 
 
148
        _cfg->setGroup("Mixer");
 
149
        _dev = _cfg->readEntry("Device", "");
 
150
        _currentMixer = _cfg->readEntry("Mixer", "");
 
151
        if (!_devlist.contains(_dev)) {
 
152
                _dev = "";
 
153
                _currentMixer = "";
 
154
        }
 
155
 
 
156
        if (!_devlist.isEmpty()) {
 
157
                if (_dev.isEmpty())
 
158
                        _dev = _devlist[0];
 
159
                _fd = open(_dev.latin1(), O_RDWR);
 
160
                if (_fd != -1) {
 
161
                        _mixers = _mixerMap[_dev];
 
162
                        setMixer(_currentMixer.isEmpty() ? i18n("Vol") 
 
163
                     : _currentMixer);
 
164
                }
 
165
        }
 
166
        
 
167
        preMuteLevels.left = -1;
 
168
        preMuteLevels.right = -1;
 
169
}
 
170
 
 
171
 
 
172
KdetvOSS::~KdetvOSS()
 
173
{
 
174
        kdDebug() << "Kdetv OSS plugin unloaded." << endl;
 
175
        if (_fd != -1)
 
176
        close(_fd);
 
177
}
 
178
 
 
179
 
 
180
void KdetvOSS::saveConfig()
 
181
{
 
182
        if (-1 != _fd) {
 
183
                close(_fd);
 
184
        }
 
185
 
 
186
        QString nd = _cfg_devs->currentText();
 
187
        _fd = open(nd.local8Bit(), O_RDWR);
 
188
 
 
189
        if (_fd != -1) {
 
190
                _dev = nd;
 
191
                setMixer(_cfg_mixers->currentText());
 
192
                _mixers = _mixerMap[_dev];
 
193
                _cfg->setGroup("Mixer");
 
194
                _cfg->writeEntry("Device", nd);
 
195
                _cfg->writeEntry("Mixer", _currentMixer);
 
196
                _cfg->sync();
 
197
                kdDebug() << "OSS successfully opened mixer " << _dev
 
198
                  << " (" << _currentMixer << ")" << endl;
 
199
        }
 
200
        volume();
 
201
        emit volumeChanged(_left, _right);
 
202
}
 
203
 
 
204
 
 
205
void KdetvOSS::deviceChanged(const QString& dev)
 
206
{
 
207
        _cfg_mixers->clear();
 
208
        _cfg_mixers->insertStringList(_mixerMap[dev]);
 
209
}
 
210
 
 
211
 
 
212
int KdetvOSS::setMixer(const QString& mixer)
 
213
{
 
214
        for (int i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
 
215
                if (mixer == devNames[i]) {
 
216
                        kdDebug() << "OSS Plugin switched to mixer: " << devNames[i] << endl;
 
217
                        _devnum = i;
 
218
                        _currentMixer = mixer;
 
219
                        volume();
 
220
                        return 0;
 
221
                }
 
222
        }
 
223
 
 
224
        return -1;
 
225
}
 
226
 
 
227
 
 
228
int KdetvOSS::probeDevices()
 
229
{
 
230
        QStringList killList;
 
231
 
 
232
        if (_fd != -1) {
 
233
                close(_fd);
 
234
        }
 
235
 
 
236
        for (QStringList::ConstIterator it = _devlist.constBegin(); it != _devlist.constEnd(); ++it) {
 
237
                _fd = open((*it).local8Bit(), O_RDWR);
 
238
                if (_fd == -1) {
 
239
                        killList << *it;
 
240
                        continue;
 
241
                }
 
242
 
 
243
                _mixerMap[*it].clear();
 
244
 
 
245
                if (-1 != ioctl(_fd, SOUND_MIXER_READ_DEVMASK, &_mask)) {
 
246
 
 
247
                        for (int i = 0; i < SOUND_MIXER_NRDEVICES; i++)
 
248
                                if (_mask & (1 << i)) {
 
249
                                        kdDebug() << "OSS Plugin found a mixer for " << *it << " (" << i << "): " << devNames[i] << endl;
 
250
                                        _mixerMap[*it] << devNames[i];
 
251
                                }
 
252
                }
 
253
 
 
254
                if (_mixerMap[*it].isEmpty()) {
 
255
                        killList << *it;
 
256
                }
 
257
 
 
258
                close(_fd);
 
259
        }
 
260
 
 
261
        for (QStringList::ConstIterator it = killList.constBegin(); it != killList.constEnd(); ++it)
 
262
                _devlist.remove(*it);
 
263
 
 
264
        _fd = -1;
 
265
 
 
266
        if (!_dev.isEmpty()) {
 
267
                _fd = open(_dev.latin1(), O_RDWR);
 
268
                if (_fd == -1) {
 
269
                        _fd = -1;
 
270
                } else {
 
271
                        _mixers = _mixerMap[_dev];
 
272
                        if (_mixers.count() > 0) {
 
273
                                setMixer(_mixers[0]);
 
274
                        }
 
275
                }
 
276
        }
 
277
 
 
278
        return 0;
 
279
}
 
280
 
 
281
 
 
282
int KdetvOSS::setVolume(int left, int right)
 
283
{
 
284
        // Unmute if already muted...
 
285
        if (_muted) {
 
286
                _muted = false;
 
287
                preMuteLevels.right = preMuteLevels.left = -1;
 
288
        }
 
289
        
 
290
        //kdDebug() << "KdetvOSS::setVolume: Left = " << left << ", right = "
 
291
        //                << right << endl;
 
292
        int vol = left + (right << 8);
 
293
        
 
294
        if (_fd == -1)
 
295
                return -1;
 
296
        
 
297
        if (-1 == ioctl(_fd, MIXER_WRITE(_devnum), &vol))
 
298
                return -1;
 
299
        
 
300
        _left = left;
 
301
        _right = right;
 
302
        
 
303
        return 0;
 
304
}
 
305
 
 
306
 
 
307
int KdetvOSS::volume()
 
308
{
 
309
        int vol;
 
310
        
 
311
        if (_muted)  {
 
312
                vol = preMuteLevels.left + (preMuteLevels.right << 8);
 
313
        } else {
 
314
                if (_fd == -1)
 
315
                        return -1;
 
316
 
 
317
                if (-1 == ioctl(_fd, MIXER_READ(_devnum), &vol)) {
 
318
                        return -1;
 
319
                }
 
320
 
 
321
                _left = vol & 0xff;
 
322
                _right = (vol >> 8) & 0xff;
 
323
        }
 
324
        
 
325
        return vol;
 
326
}
 
327
 
 
328
 
 
329
int KdetvOSS::volumeLeft()
 
330
{
 
331
        return volume() & 0xff;
 
332
}
 
333
 
 
334
 
 
335
int KdetvOSS::volumeRight()
 
336
{
 
337
        return (volume() >> 8) & 0xff;
 
338
}
 
339
 
 
340
 
 
341
int KdetvOSS::setMuted(bool mute)
 
342
{  
 
343
    if (mute)  {
 
344
        // If we are already muted, ignore the request.
 
345
                if (mute != _muted) {
 
346
                        preMuteLevels.right = _right;
 
347
                        preMuteLevels.left = _left;
 
348
        
 
349
                        int vol = 0;
 
350
        
 
351
                        if (_fd == -1)
 
352
                                return -1;
 
353
 
 
354
                        if (-1 == ioctl(_fd, MIXER_WRITE(_devnum), &vol))
 
355
                                return -1;
 
356
                }
 
357
                _muted = mute;
 
358
        } else {
 
359
                _muted = mute;
 
360
        
 
361
                if (preMuteLevels.left != -1 &&  preMuteLevels.right != -1) {
 
362
                        setVolume (preMuteLevels.left,  preMuteLevels.right);
 
363
                        preMuteLevels.right = preMuteLevels.left = -1;
 
364
                }       
 
365
        } 
 
366
        
 
367
        return 0;
 
368
}
 
369
 
 
370
bool KdetvOSS::muted()
 
371
{
 
372
        return _muted;
 
373
}
 
374
 
 
375
 
 
376
extern "C" {
 
377
        KdetvOSS* create_oss(Kdetv *ktv)
 
378
    {
 
379
                return new KdetvOSS(ktv, 0, "OSS plugin");
 
380
        }
 
381
}
 
382
 
 
383
#include "kdetv_oss.moc"