Thinkpad Fn-F8: Toggle Touchpad - working in oS 12.1

Installation of oS 12.1 with KDE on a Thinkpad T520 up to know really nice!

Linux 3.1.9-1.4-desktop x86_64
openSUSE 12.1 (x86_64)
KDE: 4.7.2 (4.7.2) “release 5”

With the help of khotkeys all Thinkpad hotkeys worked - all but one: Fn-F8 !

Trying to assign Fn-F8, which is recognized as XF86TouchpadToggle by xev, is not supported by Qt, and therefore leads to a message like “the key you pressed is not supported by Qt” (Sorry, don’t know the exact message in English since I installed DE language support) in the synaptics applet.

This pulls us back to basics: acpi_hotkey

Unfortunately a previous solution Thinkpad Fn-F8: Toggle Touchpad Example does not work any more since I was not able to get the display settings and credentials for X11 fixed in /usr/lib/acpid/thinkpad_handler.
Because of this probably all attempts with xvkbd failed as well.

Searching for a solution (I need to get this touchpad disabled while typing text and especially while scrolling with the Thinkstick ) I found acpi_fakekey. However here also a apparently deprecated method using /dev/input/event0 (which is the keyboard on my machine) was used.

So finally I found a solution using /dev/uinput that I would like to share.
It still kind of strange: We intercept the Fn-F8 key event, which is ignored by Qt and inject instead an Ctrl-Alt-T event into Qt, which is mapped by the synaptic applet in KDE.

/* 	$Id: acpi_fake_alt-ctrl-t.c,v 1.8 2012/03/10 20:11:01 root Exp $	 */

#ifndef lint
static char vcid] = "$Id: acpi_fake_alt-ctrl-t.c,v 1.8 2012/03/10 20:11:01 root Exp $";
#endif /* lint */

   Boundary conditions:
   - KDE environment
   - synaptics driver active
   - ALT-CTRL-T defined as ToggleTouchpad command in synaptics applet
   - Fn-F8 ignored by Qt (thats why can't simply redefine it)

   Feed in the three keys acc. /usr/include/linux/input.h

/* based on

   acpi_fakekey.c nach

   changed to use /dev/uinput based on


#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <syslog.h>

int main() {
        int fd;
        int key;
        struct input_event event;
	struct uinput_user_dev dev;

	openlog("fake_alt-ctrl-t: ", LOG_PID, LOG_SYSLOG);
	syslog(LOG_NOTICE, "faking ALT-CTRL-T");
	fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
	if (fd < 0) {
		syslog(LOG_NOTICE, "%m");
	memset(&dev, 0, sizeof(dev));
	strncpy(, "ACPI Virtual Keyboard Device", UINPUT_MAX_NAME_SIZE); = 4; = BUS_USB; = 1; // dummy = 1; // dummy

	ioctl(fd, UI_SET_EVBIT, EV_KEY);

	// we somehow need to 'enable' the keys we want to use
	ioctl(fd, UI_SET_KEYBIT, KEY_T);

	write(fd, &dev, sizeof(dev));

	if (ioctl(fd, UI_DEV_CREATE)) {
	  syslog(LOG_NOTICE, "%m");
	  return EXIT_FAILURE;

	if (!fd) {
	  syslog(LOG_NOTICE, "%m");
	  return 2;


        event.type = EV_KEY;
        event.value = 1;

        event.code = KEY_LEFTCTRL;
        write(fd, &event, sizeof event);
        event.code = KEY_LEFTALT;
        write(fd, &event, sizeof event);
        event.code = KEY_T;
        write(fd, &event, sizeof event);

        event.value = 0;
        event.code = KEY_T;
        write(fd, &event, sizeof event);
        event.code = KEY_LEFTALT;
        write(fd, &event, sizeof event);
        event.code = KEY_LEFTCTRL;
        write(fd, &event, sizeof event);

       	ioctl(fd, UI_DEV_DESTROY);
	close (fd);



This program is called in usr/lib/acpid/thinkpad_handler as follows:

# XF86ToggleTouchpad
if  "$WHAT" = "00000080" -a "$SERIAL" = "00001008" ]; then
        # Fn+F8