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);