[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Patch] keys to tweak audio



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