On Wed, Sep 14, 2022 at 11:56:48AM +0000, Miod Vallat wrote:
> > Hey,
> >
> > the diff below adds FN key combos for Page Up, Page Down and some more
> > on the M2 keyboard. Most of the logic was copied from ukbd.
>
> This means most of the munging logic should move from ukbd into hidkbd,
> but that can be done later.
Right, that was also my idea. For now I'd be happy to have them working
at all.
>
> If you don't want to do this yet, you need to address two points:
> - the result of the hid_locate() call should be checked.
> - because of this, invocation of apldckbd_munge() should only happen if
> that call had succeeded.
>
Updated diff below.
diff --git a/sys/arch/arm64/dev/apldc.c b/sys/arch/arm64/dev/apldc.c
index 1db551988e6..0ffac192b3f 100644
--- a/sys/arch/arm64/dev/apldc.c
+++ b/sys/arch/arm64/dev/apldc.c
@@ -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.37.2