[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Patch] keys to tweak audio
- To: tech_(_at_)_openbsd_(_dot_)_org
- Subject: [Patch] keys to tweak audio
- From: Alexey Vatchenko <avv_(_at_)_mail_(_dot_)_zp_(_dot_)_ua>
- Date: Tue, 14 Mar 2006 18:32:46 +0200
Hi!
I've added support for Audio mute, volume up and volume down keyboard keys.
Works in console yet. Tested on my laptop (Acer TravelMate 4654LMi) and
with PS/2 keyboard connected to my workstation. Both run OpenBSD 3.8.
cd /usr/src/sys && patch -p0 < audio_keys.diff
Any comments are welcome!
--
%cat ~/doc/personal.txt
mailto: avv_(_at_)_mail_(_dot_)_zp_(_dot_)_ua
Index: dev/audio.c
===================================================================
RCS file: /cvs/src/sys/dev/audio.c,v
retrieving revision 1.46
diff -u -c -r1.46 audio.c
*** dev/audio.c 2 Jun 2005 19:04:18 -0000 1.46
--- dev/audio.c 14 Mar 2006 13:57:52 -0000
***************
*** 213,218 ****
--- 213,222 ----
struct filterops audioread_filtops =
{ 1, NULL, filt_audiordetach, filt_audioread};
+ /* Mixer manipulation using keyboard */
+ static int wskbd_get_mixerdev(struct audio_softc *sc, int dir, int *index);
+ int wskbd_set_mixervolume(int dir);
+
int
audioprobe(parent, match, aux)
struct device *parent;
***************
*** 3102,3105 ****
--- 3106,3258 ----
struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
return AUDIO_FILTWRITE(sc);
+ }
+
+ static int
+ wskbd_get_mixerdev(struct audio_softc *sc, int dir, int *index)
+ {
+ mixer_devinfo_t mi;
+ int mixer_class;
+ int error;
+
+ /* looking for ``outputs'' */
+ for (mi.index = 0; ; mi.index++) {
+ error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
+ if (error != 0)
+ return (-1);
+
+ if (mi.type == AUDIO_MIXER_CLASS &&
+ strcmp(mi.label.name, AudioCoutputs) == 0) {
+ mixer_class = mi.mixer_class;
+ break;
+ }
+ }
+
+ /* looking for ``outputs.master'' */
+ mi.index++;
+ for (;; mi.index++) {
+ error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
+ if (error != 0)
+ return (-1);
+
+ if (mi.type == AUDIO_MIXER_VALUE &&
+ mi.mixer_class == mixer_class &&
+ strcmp(mi.label.name, AudioNmaster) == 0) {
+ if (dir == 0) {
+ /* looking for ``outputs.master.mute'' */
+ if (mi.next < 0)
+ return (-1);
+
+ mi.index = mi.next;
+ error = sc->hw_if->query_devinfo(
+ sc->hw_hdl, &mi);
+ if (error != 0)
+ return (-1);
+
+ if (mi.type != AUDIO_MIXER_ENUM ||
+ strcmp(mi.label.name, AudioNmute) != 0)
+ return (-1);
+ }
+
+ *index = mi.index;
+ return 0;
+ }
+ }
+
+ return (-1);
+ }
+
+ int
+ wskbd_set_mixervolume(int dir)
+ {
+ struct audio_softc *sc;
+ mixer_devinfo_t mi;
+ mixer_ctrl_t ct;
+ int l, r;
+ int error;
+
+ if (audio_cd.cd_ndevs == 0 || (sc = *audio_cd.cd_devs) == NULL) {
+ DPRINTF(("wskbd_set_mixervolume: audio_cd\n"));
+ return (ENXIO);
+ }
+
+ error = wskbd_get_mixerdev(sc, dir, &ct.dev);
+ if (error == -1) {
+ DPRINTF(("wskbd_set_mixervolume: wskbd_get_mixerdev\n"));
+ return (ENXIO);
+ }
+
+ if (dir == 0) {
+ /*
+ * Mute.
+ * Use mixer_ioctl() for writing. It does many things for us.
+ */
+ ct.type = AUDIO_MIXER_ENUM;
+ error = sc->hw_if->get_port(sc->hw_hdl, &ct);
+ if (error != 0) {
+ DPRINTF(("wskbd_set_mixervolume:"
+ " get_port: %d\n", error));
+ return (error);
+ }
+
+ ct.un.ord ^= 1; /* XXX - toggle */
+
+ error = mixer_ioctl(MIXER_DEVICE,
+ AUDIO_MIXER_WRITE, (caddr_t)&ct, FWRITE, NULL);
+ if (error != 0) {
+ DPRINTF(("wskbd_set_mixervolume:"
+ " mixer_ioctl: %d\n", error));
+ return (error);
+ }
+
+ } else {
+ mi.index = ct.dev;
+ error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
+ if (error != 0) {
+ DPRINTF(("wskbd_set_mixervolume:"
+ " query_devinfo: %d\n", error));
+ return (error);
+ }
+
+ ct.type = AUDIO_MIXER_VALUE;
+
+ error = au_get_lr_value(sc, &ct, &l, &r);
+ if (error != 0) {
+ DPRINTF(("wskbd_set_mixervolume:"
+ " au_get_lr_value: %d\n", error));
+ return (error);
+ }
+
+ if (dir > 0) {
+ /*
+ * Raise volume
+ */
+ if (l > (AUDIO_MAX_GAIN - mi.un.v.delta) ||
+ r > (AUDIO_MAX_GAIN - mi.un.v.delta))
+ return (0);
+
+ l += mi.un.v.delta;
+ r += mi.un.v.delta;
+
+ } else {
+ /*
+ * Lower volume
+ */
+ if (l < (AUDIO_MIN_GAIN + mi.un.v.delta) ||
+ r < (AUDIO_MIN_GAIN + mi.un.v.delta))
+ return (0);
+
+ l -= mi.un.v.delta;
+ r -= mi.un.v.delta;
+ }
+
+ error = au_set_lr_value(sc, &ct, l, r);
+ if (error != 0) {
+ DPRINTF(("wskbd_set_mixervolume:"
+ " au_set_lr_value: %d\n", error));
+ return (error);
+ }
+ }
+
+ return (0);
}
Index: dev/pckbc/wskbdmap_mfii.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/wskbdmap_mfii.c,v
retrieving revision 1.30
diff -u -c -r1.30 wskbdmap_mfii.c
*** dev/pckbc/wskbdmap_mfii.c 9 May 2005 05:08:57 -0000 1.30
--- dev/pckbc/wskbdmap_mfii.c 14 Mar 2006 13:57:55 -0000
***************
*** 141,147 ****
--- 141,150 ----
KC(127), KS_Pause, /* Break */
KC(156), KS_KP_Enter,
KC(157), KS_Cmd1, KS_Control_R,
+ KC(160), KS_AudioMute,
KC(170), KS_Print_Screen,
+ KC(174), KS_AudioLower,
+ KC(176), KS_AudioRaise,
KC(181), KS_KP_Divide,
KC(183), KS_Print_Screen,
KC(184), KS_Cmd2, KS_Alt_R, KS_Multi_key,
Index: dev/wscons/wskbd.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.46
diff -u -c -r1.46 wskbd.c
*** dev/wscons/wskbd.c 14 Aug 2005 11:00:15 -0000 1.46
--- dev/wscons/wskbd.c 14 Mar 2006 13:57:56 -0000
***************
*** 294,299 ****
--- 294,301 ----
void wskbd_update_layout(struct wskbd_internal *, kbd_t);
+ int wskbd_set_mixervolume(int dir);
+
void
wskbd_update_layout(struct wskbd_internal *id, kbd_t enc)
{
***************
*** 1610,1615 ****
--- 1612,1632 ----
gindex = MOD_ONESET(id, MOD_ANYSHIFT);
ksym = group[gindex];
}
+ }
+
+ /* Process Audio tunning keys */
+ switch (ksym) {
+ case KS_AudioMute:
+ (void) wskbd_set_mixervolume(0);
+ return (0);
+
+ case KS_AudioLower:
+ (void) wskbd_set_mixervolume(-1);
+ return (0);
+
+ case KS_AudioRaise:
+ (void) wskbd_set_mixervolume(1);
+ return (0);
}
/* Process compose sequence and dead accents */
Index: dev/wscons/wsksymdef.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsksymdef.h,v
retrieving revision 1.28
diff -u -c -r1.28 wsksymdef.h
*** dev/wscons/wsksymdef.h 15 May 2005 11:29:15 -0000 1.28
--- dev/wscons/wsksymdef.h 14 Mar 2006 13:57:56 -0000
***************
*** 602,607 ****
--- 602,611 ----
#define KS_Pause 0xf3c1
#define KS_Print_Screen 0xf3c2
+ #define KS_AudioMute 0xf3d1
+ #define KS_AudioLower 0xf3d2
+ #define KS_AudioRaise 0xf3d3
+
/*
* Group 4 (command)
*/
Visit your host, monkey.org