vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| 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@mail.zp.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) */ |