On 13/07/11(Wed) 15:51, Miod Vallat wrote:
> > Index: dev/usb/ukbd.c
> 
> > @@ -227,6 +234,25 @@ ukbd_attach(struct device *parent, struc
> >     if (hidkbd_attach(self, kbd, 1, qflags, repid, desc, dlen) != 0)
> >             return;
> >  
> > +   /* check for apple keyboards that need Fn-key help */
> > +   if (uha->uaa->vendor == USB_VENDOR_APPLE) {
> > +           uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
> > +           d = hid_start_parse(desc, size, hid_input);
> > +           while (hid_get_item(d, &h)) {
> > +                   if (HID_GET_USAGE_PAGE(h.usage) == 0x00ff &&
> > +                       HID_GET_USAGE(h.usage) == 0x0003 &&
> > +                       h.kind == hid_input && (h.flags & HIO_VARIABLE)) {
> 
> Any reason not to use hid_locate() here?
> 
> > +                           sc->sc_apple_fn = 1;
> > +                           sc->sc_apple_fn_loc = h.loc;
> > +                           sc->sc_munge = ukbd_apple_munge;
> > +#ifdef DIAGNOSTIC
> > +                           printf(", apple Fn-key help\n");
> > +#endif
> 
> I think this is not worth adding a message (and it will confuse dmesg
> output because of the newline).

Updated diff using hid_locate and the right values for volume up/down.

I also added an "ifdef macppc" block because G4 laptops use different
F-keys for sound control. So if someone plug a "new" Apple USB keyboard
to a macppc these keys wont work, but who want to do that?

Ok?

Index: ukbd.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ukbd.c,v
retrieving revision 1.55
diff -u -p -r1.55 ukbd.c
--- ukbd.c      3 Jul 2011 15:47:17 -0000       1.55
+++ ukbd.c      31 Oct 2011 15:20:22 -0000
@@ -132,6 +132,8 @@ struct ukbd_softc {
 
        u_char                  sc_dying;
 
+       struct hid_location     sc_apple_fn;
+
        void                    (*sc_munge)(void *, uint8_t *, u_int);
 };
 
@@ -182,6 +184,7 @@ struct ukbd_translation {
 #ifdef __loongson__
 void   ukbd_gdium_munge(void *, uint8_t *, u_int);
 #endif
+void   ukbd_apple_munge(void *, uint8_t *, u_int);
 uint8_t        ukbd_translate(const struct ukbd_translation *, size_t, 
uint8_t);
 
 int
@@ -227,6 +230,14 @@ ukbd_attach(struct device *parent, struc
        if (hidkbd_attach(self, kbd, 1, qflags, repid, desc, dlen) != 0)
                return;
 
+       if (uha->uaa->vendor == USB_VENDOR_APPLE) {
+               if (hid_locate(desc, dlen, HID_USAGE2(HUP_APPLE, HUG_FN_KEY),
+                   uha->reportid, hid_input, &sc->sc_apple_fn, &qflags)) {
+                       if (qflags & HIO_VARIABLE)
+                               sc->sc_munge = ukbd_apple_munge;
+               }
+       }
+
        if (uha->uaa->vendor == USB_VENDOR_TOPRE &&
            uha->uaa->product == USB_PRODUCT_TOPRE_HHKB) {
                /* ignore country code on purpose */
@@ -437,6 +448,56 @@ ukbd_translate(const struct ukbd_transla
                if (table->original == keycode)
                        return table->translation;
        return 0;
+}
+
+void
+ukbd_apple_munge(void *vsc, uint8_t *ibuf, u_int ilen)
+{
+       struct ukbd_softc *sc = vsc;
+       struct hidkbd *kbd = &sc->sc_kbd;
+       uint8_t *pos, *spos, *epos, xlat;
+
+       static const struct ukbd_translation apple_fn_trans[] = {
+               { 40, 73 },     /* return -> insert */
+               { 42, 76 },     /* backspace -> delete */
+#ifdef notyet
+               { 58, 0 },      /* F1 -> screen brightness down */
+               { 59, 0 },      /* F2 -> screen brightness up */
+               { 60, 0 },      /* F3 */
+               { 61, 0 },      /* F4 */
+               { 62, 0 },      /* F5 -> keyboard backlight down */
+               { 63, 0 },      /* F6 -> keyboard backlight up */
+               { 64, 0 },      /* F7 -> audio back */
+               { 65, 0 },      /* F8 -> audio pause/play */
+               { 66, 0 },      /* F9 -> audio next */
+#endif
+#ifdef __macppc__
+               { 60, 127 },    /* F3 -> audio mute */
+               { 61, 129 },    /* F4 -> audio lower */
+               { 62, 128 },    /* F5 -> audio raise */
+#else
+               { 67, 127 },    /* F10 -> audio mute */
+               { 68, 129 },    /* F11 -> audio lower */
+               { 69, 128 },    /* F12 -> audio raise */
+#endif
+               { 79, 77 },     /* right -> end */
+               { 80, 74 },     /* left -> home */
+               { 81, 78 },     /* down -> page down */
+               { 82, 75 }      /* up -> page up */
+       };
+
+       if (!hid_get_data(ibuf, &sc->sc_apple_fn))
+               return;
+
+       spos = ibuf + kbd->sc_keycodeloc.pos / 8;
+       epos = spos + kbd->sc_nkeycode;
+
+       for (pos = spos; pos != epos; pos++) {
+               xlat = ukbd_translate(apple_fn_trans,
+                   nitems(apple_fn_trans), *pos);
+               if (xlat != 0)
+                       *pos = xlat;
+       }
 }
 
 #ifdef __loongson__
Index: usbhid.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbhid.h,v
retrieving revision 1.13
diff -u -p -r1.13 usbhid.h
--- usbhid.h    9 Dec 2009 21:27:19 -0000       1.13
+++ usbhid.h    31 Oct 2011 15:23:05 -0000
@@ -88,11 +88,13 @@ typedef struct usb_hid_descriptor {
 #define HUP_SCALE              0x008c
 #define HUP_CAMERA_CONTROL     0x0090
 #define HUP_ARCADE             0x0091
+#define HUP_APPLE              0x00ff 
 #define HUP_MICROSOFT          0xff00
 
 /* Usages, generic desktop */
 #define HUG_POINTER            0x0001
 #define HUG_MOUSE              0x0002
+#define HUG_FN_KEY             0x0003
 #define HUG_JOYSTICK           0x0004
 #define HUG_GAME_PAD           0x0005
 #define HUG_KEYBOARD           0x0006

Reply via email to