On Wed, Apr 30, 2014 at 01:06:48AM +0200, Alexandre Ratchov wrote: > This diff attempts to "unify" volume keys; it makes pckbd and ukbd > volume keys behave like all other volume keys (acpithinkpad, > acpiasus, macppc/abtn and similar drivers): simply adjust the > hardware volume without passing keystroke events to upper layers > (i.e. "consume" the keystroke). > > If your volume keys tend to mess the volume while in X (example > mplayer), try this diff and see if it makes things better (or > worse). > > +#ifdef WSDISPLAY_COMPAT_RAWKBD > + rc = pckbd_decode(sc->id, data, &type, &key, sc->rawkbd); > +#else > + rc = pckbd_decode(sc-id, data, &type, &key, 0); ^^^^^^ a new diff with the typo fixed, thanks to Kent R. Spillner
Index: dev/pckbc/pckbd.c =================================================================== RCS file: /cvs/src/sys/dev/pckbc/pckbd.c,v retrieving revision 1.37 diff -u -p -r1.37 pckbd.c --- dev/pckbc/pckbd.c 23 Mar 2014 11:48:23 -0000 1.37 +++ dev/pckbc/pckbd.c 19 May 2014 07:31:57 -0000 @@ -177,7 +177,7 @@ int pckbd_init(struct pckbd_internal *, void pckbd_input(void *, int); static int pckbd_decode(struct pckbd_internal *, int, - u_int *, int *); + u_int *, int *, int); static int pckbd_led_encode(int); struct pckbd_internal pckbd_consdata; @@ -788,7 +788,8 @@ pckbd_scancode_translate(struct pckbd_in } static int -pckbd_decode(struct pckbd_internal *id, int datain, u_int *type, int *dataout) +pckbd_decode(struct pckbd_internal *id, int datain, u_int *type, + int *dataout, int raw) { int key; int releasing; @@ -832,8 +833,8 @@ pckbd_decode(struct pckbd_internal *id, id->t_lastchar = 0; *type = WSCONS_EVENT_KEY_UP; } else { - /* Always ignore typematic keys */ - if (key == id->t_lastchar) + /* Always ignore typematic keys, except in raw-mode */ + if (key == id->t_lastchar && !raw) return 0; id->t_lastchar = key; *type = WSCONS_EVENT_KEY_DOWN; @@ -894,16 +895,25 @@ void pckbd_input(void *vsc, int data) { struct pckbd_softc *sc = vsc; - int rc, type, key; + int rc, type, key, consumed; data = pckbd_scancode_translate(sc->id, data); if (data == 0) return; - rc = pckbd_decode(sc->id, data, &type, &key); +#ifdef WSDISPLAY_COMPAT_RAWKBD + rc = pckbd_decode(sc->id, data, &type, &key, sc->rawkbd); +#else + rc = pckbd_decode(sc->id, data, &type, &key, 0); +#endif + consumed = (rc != 0) ? wskbd_volkey(sc->sc_wskbddev, type, key) : 0; #ifdef WSDISPLAY_COMPAT_RAWKBD if (sc->rawkbd) { + if (consumed) { + sc->sc_rawcnt = 0; + return; + } sc->sc_rawbuf[sc->sc_rawcnt++] = (char)data; if (rc != 0 || sc->sc_rawcnt == sizeof(sc->sc_rawbuf)) { @@ -911,15 +921,10 @@ pckbd_input(void *vsc, int data) sc->sc_rawcnt); sc->sc_rawcnt = 0; } - - /* - * Pass audio keys to wskbd_input anyway. - */ - if (rc == 0 || (key != 160 && key != 174 && key != 176)) - return; + return; } #endif - if (rc != 0) + if (rc != 0 && !consumed) wskbd_input(sc->sc_wskbddev, type, key); } @@ -1024,7 +1029,7 @@ pckbd_cngetc(void *v, u_int *type, int * if (val == 0) continue; - if (pckbd_decode(t, val, type, data)) + if (pckbd_decode(t, val, type, data, 0)) return; } } Index: dev/usb/hidkbd.c =================================================================== RCS file: /cvs/src/sys/dev/usb/hidkbd.c,v retrieving revision 1.12 diff -u -p -r1.12 hidkbd.c --- dev/usb/hidkbd.c 12 May 2014 09:50:44 -0000 1.12 +++ dev/usb/hidkbd.c 19 May 2014 07:31:58 -0000 @@ -412,6 +412,9 @@ hidkbd_decode(struct hidkbd *kbd, struct for (i = j = 0; i < nkeys; i++) { key = ibuf[i]; c = hidkbd_trtab[key & CODEMASK]; + if (wskbd_volkey(kbd->sc_wskbddev, (key & RELEASE) ? + WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN, c)) + continue; if (c == NN) continue; if (c & 0x80) @@ -426,24 +429,7 @@ hidkbd_decode(struct hidkbd *kbd, struct } s = spltty(); wskbd_rawinput(kbd->sc_wskbddev, cbuf, j); - - /* - * Pass audio keys to wskbd_input anyway. - */ - for (i = 0; i < nkeys; i++) { - key = ibuf[i]; - switch (key & CODEMASK) { - case 127: - case 128: - case 129: - wskbd_input(kbd->sc_wskbddev, - key & RELEASE ? WSCONS_EVENT_KEY_UP : - WSCONS_EVENT_KEY_DOWN, key & CODEMASK); - break; - } - } splx(s); - return; } #endif @@ -451,6 +437,10 @@ hidkbd_decode(struct hidkbd *kbd, struct s = spltty(); for (i = 0; i < nkeys; i++) { key = ibuf[i]; + if (wskbd_volkey(kbd->sc_wskbddev, (key & RELEASE) ? + WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN, + hidkbd_trtab[key & CODEMASK])) + continue; wskbd_input(kbd->sc_wskbddev, key&RELEASE ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN, key&CODEMASK); Index: dev/wscons/wskbd.c =================================================================== RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v retrieving revision 1.78 diff -u -p -r1.78 wskbd.c --- dev/wscons/wskbd.c 15 May 2014 09:29:38 -0000 1.78 +++ dev/wscons/wskbd.c 19 May 2014 07:32:00 -0000 @@ -700,6 +700,38 @@ wskbd_input(struct device *dev, u_int ty } /* + * Check if the given key is a multimedia key to mute or + * increase/decrease speaker volume. If it is, then invoke the + * appropriate audio mixer bits and return 1 (means key is consumed), + * else return 0. + */ +int +wskbd_volkey(struct device *dev, u_int type, int key) +{ + switch (key) { + case 160: +#if NAUDIO > 0 + if (type == WSCONS_EVENT_KEY_DOWN) + wskbd_set_mixervolume(0, 1); +#endif + return 1; + case 174: +#if NAUDIO > 0 + if (type == WSCONS_EVENT_KEY_DOWN) + wskbd_set_mixervolume(-1, 1); +#endif + return 1; + case 176: +#if NAUDIO > 0 + if (type == WSCONS_EVENT_KEY_DOWN) + wskbd_set_mixervolume(1, 1); +#endif + return 1; + } + return 0; +} + +/* * Keyboard is generating events. Turn this keystroke into an * event and put it in the queue. If the queue is full, the * keystroke is lost (sorry!). @@ -1679,25 +1711,6 @@ wskbd_translate(struct wskbd_internal *i } else { gindex = MOD_ONESET(id, MOD_ANYSHIFT); ksym = group[gindex]; - } - } - - /* Submit Audio keys for hotkey processing */ - if (KS_GROUP(ksym) == KS_GROUP_Function) { - switch (ksym) { -#if NAUDIO > 0 - case KS_AudioMute: - wskbd_set_mixervolume(0, 1); - return (0); - case KS_AudioLower: - wskbd_set_mixervolume(-1, 1); - return (0); - case KS_AudioRaise: - wskbd_set_mixervolume(1, 1); - return (0); -#endif - default: - break; } } Index: dev/wscons/wskbdvar.h =================================================================== RCS file: /cvs/src/sys/dev/wscons/wskbdvar.h,v retrieving revision 1.2 diff -u -p -r1.2 wskbdvar.h --- dev/wscons/wskbdvar.h 14 Mar 2002 01:27:03 -0000 1.2 +++ dev/wscons/wskbdvar.h 19 May 2014 07:32:00 -0000 @@ -91,6 +91,7 @@ int wskbddevprint(void *, const char *); * Callbacks from the keyboard driver to the wskbd interface driver. */ void wskbd_input(struct device *kbddev, u_int type, int value); +int wskbd_volkey(struct device *kbddev, u_int type, int value); /* for WSDISPLAY_COMPAT_RAWKBD */ void wskbd_rawinput(struct device *, u_char *, int);