From 56e0a7b6668ad7c51cd4528b2ade73b54f531435 Mon Sep 17 00:00:00 2001 From: tobhe Date: Thu, 15 Sep 2022 14:45:49 +0000 Subject: [PATCH] Add support for Apple fn key combinations. Based on Apple fn key handling in ukbd(4). ok miod@ --- sys/arch/arm64/dev/apldc.c | 50 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/sys/arch/arm64/dev/apldc.c b/sys/arch/arm64/dev/apldc.c index 1db551988e6..09a03c734da 100644 --- a/sys/arch/arm64/dev/apldc.c +++ b/sys/arch/arm64/dev/apldc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apldc.c,v 1.2 2022/09/03 08:44:56 kettenis Exp $ */ +/* $OpenBSD: apldc.c,v 1.3 2022/09/15 14:45:49 tobhe Exp $ */ /* * Copyright (c) 2022 Mark Kettenis * @@ -1066,6 +1066,22 @@ struct apldckbd_softc { struct apldchidev_softc *sc_hidev; struct hidkbd sc_kbd; int sc_spl; + struct hid_location sc_fn; + int sc_has_fn; +}; + +struct apldckbd_translation { + uint8_t original; + uint8_t translation; +}; + +static const struct apldckbd_translation apldckbd_trans_table[] = { + { 40, 73 }, /* return -> insert */ + { 42, 76 }, /* backspace -> delete */ + { 79, 77 }, /* right -> end */ + { 80, 74 }, /* left -> home */ + { 81, 78 }, /* down -> page down */ + { 82, 75 } /* up -> page up */ }; void apldckbd_cngetc(void *, u_int *, int *); @@ -1122,6 +1138,9 @@ apldckbd_attach(struct device *parent, struct device *self, void *aux) printf("\n"); + sc->sc_has_fn = hid_locate(aa->aa_desc, aa->aa_desclen, + HID_USAGE2(HUP_APPLE, HUG_FN_KEY), 1, hid_input, &sc->sc_fn, NULL); + if (kbd->sc_console_keyboard) { extern struct wskbd_mapdata ukbd_keymapdata; @@ -1133,14 +1152,41 @@ apldckbd_attach(struct device *parent, struct device *self, void *aux) hidkbd_attach_wskbd(kbd, KB_US | KB_DEFAULT, &apldckbd_accessops); } +void +apldckbd_munge(void *v, uint8_t *ibuf, size_t ilen) +{ + struct apldckbd_softc *sc = v; + struct hidkbd *kbd = &sc->sc_kbd; + uint8_t *pos, *spos, *epos; + const struct apldckbd_translation *tbl; + size_t tsize; + + if (!hid_get_data(ibuf, ilen, &sc->sc_fn)) + return; + + spos = ibuf + kbd->sc_keycodeloc.pos / 8; + epos = spos + kbd->sc_nkeycode; + + for (pos = spos; pos != epos; pos++) { + tbl = apldckbd_trans_table; + tsize = nitems(apldckbd_trans_table); + for (; tsize != 0; tbl++, tsize--) + if (tbl->original == *pos) + *pos = tbl->translation; + } +} + void apldckbd_intr(struct device *self, uint8_t *packet, size_t packetlen) { struct apldckbd_softc *sc = (struct apldckbd_softc *)self; struct hidkbd *kbd = &sc->sc_kbd; - if (kbd->sc_enabled) + if (kbd->sc_enabled) { + if (sc->sc_has_fn) + apldckbd_munge(sc, &packet[1], packetlen - 1); hidkbd_input(kbd, &packet[1], packetlen - 1); + } } int -- 2.20.1