crypto: Rename check_key_file() -> check_private_key_file().
[paraslash.git] / oss_mix.c
1 /*
2  * Copyright (C) 1998 Andre Noll <maan@tuebingen.mpg.de>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file oss_mix.c The OSS mixer plugin. */
8
9 #include <sys/soundcard.h>
10 #include <sys/ioctl.h>
11 #include <regex.h>
12
13 #include "para.h"
14 #include "error.h"
15 #include "mix.h"
16 #include "fd.h"
17 #include "string.h"
18
19 struct oss_mixer_channel {
20         const char *name;
21         int id;
22 };
23
24 static const struct oss_mixer_channel channels[] = {
25         {.name = "volume", .id = SOUND_MIXER_VOLUME},
26         {.name = "bass", .id = SOUND_MIXER_BASS},
27         {.name = "treble", .id = SOUND_MIXER_TREBLE},
28         {.name = "synth", .id = SOUND_MIXER_SYNTH},
29         {.name = "pcm", .id = SOUND_MIXER_PCM},
30         {.name = "speaker", .id = SOUND_MIXER_SPEAKER},
31         {.name = "line", .id = SOUND_MIXER_LINE},
32         {.name = "mic", .id = SOUND_MIXER_MIC},
33         {.name = "cd", .id = SOUND_MIXER_CD},
34         {.name = "imix", .id = SOUND_MIXER_IMIX},
35         {.name = "altpcm", .id = SOUND_MIXER_ALTPCM},
36         {.name = "reclev", .id = SOUND_MIXER_RECLEV},
37         {.name = "igain", .id = SOUND_MIXER_IGAIN},
38         {.name = "ogain", .id = SOUND_MIXER_OGAIN},
39 };
40
41 /** Iterate over all defined mixer channels. */
42 #define FOR_EACH_CHANNEL(i) for ((i) = 0; (i) < ARRAY_SIZE(channels); (i)++)
43
44 struct mixer_handle {
45         int fd;
46         int id;
47 };
48
49 static int oss_mix_open(const char *dev, struct mixer_handle **handle)
50 {
51         int ret;
52         struct mixer_handle *h;
53
54         *handle = NULL;
55         if (!dev)
56                 dev = "/dev/mixer";
57         PARA_INFO_LOG("opening %s\n", dev);
58         ret = para_open(dev, O_RDWR, 42);
59         if (ret < 0) {
60                 PARA_ERROR_LOG("could not open %s\n", dev);
61                 return ret;
62         }
63         h = para_malloc(sizeof(*h));
64         h->fd = ret;
65         *handle = h;
66         return 1;
67 }
68
69 static char *oss_mix_get_channels(__a_unused struct mixer_handle *handle)
70 {
71         int i;
72         char *list = NULL;
73
74         FOR_EACH_CHANNEL(i) {
75                 const char *name = channels[i].name;
76                 char *tmp = list;
77                 list = make_message("%s%s%s",
78                         list? list : "",
79                         list? ", " : "",
80                         name);
81                 free(tmp);
82         }
83         return list;
84 }
85
86 static int oss_mix_set_channel(struct mixer_handle *handle,
87                 const char *mixer_channel)
88 {
89         int i;
90
91         if (!mixer_channel) {
92                 handle->id = SOUND_MIXER_VOLUME; /* default */
93                 return 0;
94         }
95         FOR_EACH_CHANNEL(i) {
96                 if (strcasecmp(channels[i].name, mixer_channel))
97                         continue;
98                 handle->id = i;
99                 return 1;
100         }
101         return -E_BAD_CHANNEL;
102 }
103
104 static int oss_mix_get(struct mixer_handle *handle)
105 {
106         int val, fd = handle->fd, id = handle->id;
107
108         if (ioctl(fd, MIXER_READ(id), &val) < 0)
109                 return -ERRNO_TO_PARA_ERROR(errno);
110         /* take the mean value of left and right */
111         return (val % 256 + (val >> 8)) / 2;
112 }
113
114 static int oss_mix_set(struct mixer_handle *handle, int val)
115 {
116         int fd = handle->fd, id = handle->id, tmp = (val << 8) + val;
117
118         if (ioctl(fd, MIXER_WRITE(id), &tmp) < 0)
119                 return -ERRNO_TO_PARA_ERROR(errno);
120         return 1;
121 }
122
123 static void oss_mix_close(struct mixer_handle **handle)
124 {
125         struct mixer_handle *h;
126
127         if (!handle)
128                 return;
129         h = *handle;
130         if (h) {
131                 if (h->fd >= 0)
132                         close(h->fd);
133                 free(h);
134         }
135         *handle = NULL;
136 }
137
138 /**
139  * The init function of the OSS mixer.
140  *
141  * \param self The structure to initialize.
142  *
143  * \sa struct \ref mixer, \ref alsa_mix_init().
144  */
145 void oss_mix_init(struct mixer *self)
146 {
147         self->open = oss_mix_open;
148         self->get_channels = oss_mix_get_channels;
149         self->set_channel = oss_mix_set_channel;
150         self->get = oss_mix_get;
151         self->set = oss_mix_set;
152         self->close = oss_mix_close;
153 }