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 makes scrolling tmux a lot more fun.

ok?

diff --git a/sys/arch/arm64/dev/apldc.c b/sys/arch/arm64/dev/apldc.c
index 82a17df59b5..a4db46d8a92 100644
--- a/sys/arch/arm64/dev/apldc.c
+++ b/sys/arch/arm64/dev/apldc.c
@@ -1066,6 +1066,21 @@ struct apldckbd_softc {
        struct apldchidev_softc *sc_hidev;
        struct hidkbd           sc_kbd;
        int                     sc_spl;
+       struct hid_location     sc_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 +1137,9 @@ apldckbd_attach(struct device *parent, struct device 
*self, void *aux)
 
        printf("\n");
 
+       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 +1151,40 @@ 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) {
+               apldckbd_munge(sc, &packet[1], packetlen - 1);
                hidkbd_input(kbd, &packet[1], packetlen - 1);
+       }
 }
 
 int
-- 
2.37.3

Reply via email to