Hey Peter, I'm guessing that proxying this property in the driver will make it easier for generalized preference panes to be created based on Xinput. I seem to recall filing a bug somewhere a couple years ago about the lack of GUI surrounding this option in Gnome's preferences, so this gets a big:
Acked-by: Jeremy Huddleston <[email protected]> Reviewed-by: Jeremy Huddleston <[email protected]> --Jeremy On May 17, 2011, at 22:00, Peter Hutterer wrote: > On Apple keyboards, the multimedia function keys are overlaid with the F > keys. F1 is also BrightnessDown, F10 is Mute, etc. The kernel provides a > tweak to enable/disable this. > > /sys/module/hid_apple/parameters/fnmode > 0 .. keyboard sends Fx keys > 1 .. keyboard sends multimedia keys > > Signed-off-by: Peter Hutterer <[email protected]> > --- > include/evdev-properties.h | 3 + > src/Makefile.am | 3 +- > src/apple.c | 168 ++++++++++++++++++++++++++++++++++++++++++++ > src/evdev.c | 1 + > src/evdev.h | 1 + > 5 files changed, 175 insertions(+), 1 deletions(-) > create mode 100644 src/apple.c > > diff --git a/include/evdev-properties.h b/include/evdev-properties.h > index 16f2af7..8887cd1 100644 > --- a/include/evdev-properties.h > +++ b/include/evdev-properties.h > @@ -75,4 +75,7 @@ > /* CARD32 */ > #define EVDEV_PROP_THIRDBUTTON_THRESHOLD "Evdev Third Button Emulation > Threshold" > > +/* BOOL, 1 value, true → send function keys, false → send multimedia keys */ > +#define EVDEV_PROP_APPLE_FNMODE "Evdev Apple Function Keys" > + > #endif > diff --git a/src/Makefile.am b/src/Makefile.am > index d1efe53..b3a5671 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -37,5 +37,6 @@ AM_CPPFLAGS =-I$(top_srcdir)/include > emuMB.c \ > emuThird.c \ > emuWheel.c \ > - draglock.c > + draglock.c \ > + apple.c > > diff --git a/src/apple.c b/src/apple.c > new file mode 100644 > index 0000000..1a82e2a > --- /dev/null > +++ b/src/apple.c > @@ -0,0 +1,168 @@ > +/* > + * Copyright © 2011 Red Hat, Inc. > + * > + * Permission to use, copy, modify, distribute, and sell this software > + * and its documentation for any purpose is hereby granted without > + * fee, provided that the above copyright notice appear in all copies > + * and that both that copyright notice and this permission notice > + * appear in supporting documentation, and that the name of Red Hat > + * not be used in advertising or publicity pertaining to distribution > + * of the software without specific, written prior permission. Red > + * Hat makes no representations about the suitability of this software > + * for any purpose. It is provided "as is" without express or implied > + * warranty. > + * > + * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, > + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN > + * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR > + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS > + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, > + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN > + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + * > + * Authors: > + * Peter Hutterer ([email protected]) > + */ > + > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <evdev.h> > +#include <evdev-properties.h> > +#include <errno.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +#include <unistd.h> > + > +#include <exevents.h> > +#include <xf86.h> > +#include <xf86Xinput.h> > +#include <X11/Xatom.h> > + > +/* Apple-specific controls. > + * > + * On Apple keyboards, the multimedia function keys are overlaid with the F > + * keys. F1 is also BrightnessDown, F10 is Mute, etc. The kernel provides a > + * tweak to enable/disable this. > + * > + * /sys/module/hid_apple/parameters/fnmode > + * 0 .. keyboard sends Fx keys > + * 1 .. keyboard sends multimedia keys > + */ > + > +#define FNMODE_PATH "/sys/module/hid_apple/parameters/fnmode" > +#define APPLE_VENDOR 0x5ac > +#define APPLE_KEYBOARD 0x220 > + > +static Atom prop_fnmode; > +static Bool fnmode_readonly; /* set if we can only read fnmode */ > + > + > +/** > + * @retval 0 fnmode is set to function keys > + * @retval 1 fnmode is set to multimedia keys > + * @retval -1 Error, see errno > + */ > +static int > +get_fnmode(void) > +{ > + int fd; > + char retvalue; > + > + fd = open(FNMODE_PATH, O_RDWR); > + if (fd < 0) > + { > + if (errno == EACCES) > + { > + fnmode_readonly = TRUE; > + fd = open(FNMODE_PATH, O_RDONLY); > + } > + } > + > + if (fd < 0) > + return -1; > + > + if (read(fd, &retvalue, 1) != 1) > + return -1; > + > + close(fd); > + > + if (retvalue != '0' && retvalue != '1') > + { > + xf86Msg(X_ERROR, "Invalid fnmode value: %c\n", retvalue); > + errno = EINVAL; > + return -1; > + } > + > + return retvalue == '1'; > +} > + > +/** > + * @param fnmode 0 for function keys, 1 for multimedia keys > + * @return 0 on success, -1 otherwise (check errno) > + */ > +static int > +set_fnmode(Bool fnmode) > +{ > + int fd; > + char mode; > + > + fd = open(FNMODE_PATH, O_WRONLY); > + if (fd < 0) > + return -1; > + > + mode = fnmode ? '1' : '0'; > + > + if (write(fd, &mode, 1) != 1) > + return -1; > + > + close(fd); > + > + return 0; > +} > + > +static int > +EvdevAppleSetProperty(DeviceIntPtr dev, Atom atom, > + XIPropertyValuePtr val, BOOL checkonly) > +{ > + if (atom == prop_fnmode) > + { > + if (val->format != 8 || val->type != XA_INTEGER) > + return BadMatch; > + > + if (fnmode_readonly) > + return BadAccess; > + > + if (!checkonly) > + set_fnmode(*(CARD8*)val->data); > + } > + > + return Success; > +} > + > +void > +EvdevAppleInitProperty(DeviceIntPtr dev) > +{ > + InputInfoPtr pInfo = dev->public.devicePrivate; > + EvdevPtr pEvdev = pInfo->private; > + char fnmode; > + > + if (pEvdev->id_vendor != APPLE_VENDOR || > + pEvdev->id_product != APPLE_KEYBOARD) > + return; > + > + fnmode = get_fnmode(); > + if (fnmode == -1) > + { > + xf86IDrvMsg(pInfo, X_ERROR, "Failed to get fnmode (%s)\n", > strerror(errno)); > + return; > + } > + > + prop_fnmode = MakeAtom(EVDEV_PROP_APPLE_FNMODE, > strlen(EVDEV_PROP_APPLE_FNMODE), TRUE); > + XIChangeDeviceProperty(dev, prop_fnmode, XA_INTEGER, 8, > + PropModeReplace, 1, &fnmode, FALSE); > + XISetDevicePropertyDeletable(dev, prop_fnmode, FALSE); > + XIRegisterPropertyHandler(dev, EvdevAppleSetProperty, NULL, NULL); > +} > diff --git a/src/evdev.c b/src/evdev.c > index d93adb4..38868c4 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -1359,6 +1359,7 @@ EvdevInit(DeviceIntPtr device) > Evdev3BEmuInitProperty(device); > EvdevWheelEmuInitProperty(device); > EvdevDragLockInitProperty(device); > + EvdevAppleInitProperty(device); > > return Success; > } > diff --git a/src/evdev.h b/src/evdev.h > index 1741e59..6434c3f 100644 > --- a/src/evdev.h > +++ b/src/evdev.h > @@ -243,4 +243,5 @@ void EvdevMBEmuInitProperty(DeviceIntPtr); > void Evdev3BEmuInitProperty(DeviceIntPtr); > void EvdevWheelEmuInitProperty(DeviceIntPtr); > void EvdevDragLockInitProperty(DeviceIntPtr); > +void EvdevAppleInitProperty(DeviceIntPtr); > #endif > -- > 1.7.4.4 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
