diff options
author | William Grant <wgrant@ubuntu.com> | 2008-10-16 21:39:40 +0200 |
---|---|---|
committer | Christoph Brill <egore911@egore911.de> | 2008-10-16 21:39:40 +0200 |
commit | 934bc0012f948c52aadc8eda912f7728fb7394a2 (patch) | |
tree | b192da5488d99bdda8e530f6801fb8670bb57dce /tools | |
parent | 641b26da531b38313ecc68badac1a3ccfd6fc7af (diff) |
[syndaemon] switch over to input properties
This patch switches the daemon to use input properties. One can still
use the SHMConfig as fallback.
Signed-off-by: Christoph Brill <egore911@egore911.de>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/syndaemon.c | 228 |
1 files changed, 196 insertions, 32 deletions
diff --git a/tools/syndaemon.c b/tools/syndaemon.c index d4cfd4c..30abc77 100644 --- a/tools/syndaemon.c +++ b/tools/syndaemon.c @@ -22,6 +22,7 @@ * * Authors: * Peter Osterlund (petero2@telia.com) + * William Grant (wgrant@ubuntu.com) */ #ifdef HAVE_CONFIG_H @@ -42,9 +43,13 @@ #include <sys/time.h> #include <sys/stat.h> +#include <X11/Xatom.h> +#include <X11/extensions/XInput.h> + #include "synaptics.h" static SynapticsSHM *synshm; +static int using_synshm; static int pad_disabled; static int disable_taps_only; static int ignore_modifier_combos; @@ -69,15 +74,113 @@ usage(void) fprintf(stderr, " -k Ignore modifier keys when monitoring keyboard activity.\n"); fprintf(stderr, " -K Like -k but also ignore Modifier+Key combos.\n"); fprintf(stderr, " -R Don't use the XRecord extension.\n"); + fprintf(stderr, " -S Use SHMConfig even if input device properties are available.\n"); exit(1); } +static XDevice +*device_is_touchpad(Display *display, XDeviceInfo deviceinfo) +{ + XDevice *device; + Atom *props; + int nprops; + char *name; + + device = XOpenDevice(display, deviceinfo.id); + if (!device) + return NULL; + + props = XListDeviceProperties(display, device, &nprops); + while (nprops--) { + name = XGetAtomName(display, props[nprops]); + if (!strcmp(name, "Synaptics Off")) { + free(name); + XFree(props); + return device; + } + free(name); + } + + XFree(props); + XCloseDevice(display, device); + return NULL; +} + +static int +get_touchpad_off(Display *display) +{ + int numdevices, i; + XDeviceInfo *devicelist; + XDevice *device; + Atom realtype, prop; + int realformat; + unsigned long nitems, bytes_after; + unsigned char *data; + int result; + + if (using_synshm) + return synshm->touchpad_off; + + devicelist = XListInputDevices (display, &numdevices); + + prop = XInternAtom(display, "Synaptics Off", False); + + for (i = 0; i < numdevices; i++) { + if ((devicelist[i].use >= IsXExtensionDevice) && + (device = device_is_touchpad(display, devicelist[i]))) { + XGetDeviceProperty(display, device, prop, 0, 1, False, + XA_INTEGER, &realtype, &realformat, &nitems, + &bytes_after, &data); + if (nitems < 1) { + fprintf(stderr, "Touchpad didn't return status information.\n"); + exit(2); + } + + result = data[0]; + XFree(devicelist); + XFree(data); + XCloseDevice(display, device); + return result; + } + } + XFree(devicelist); + return 1; +} + +static void +set_touchpad_off(Display *display, int value) +{ + int numdevices, i; + XDeviceInfo *devicelist; + XDevice *device; + Atom realtype, prop; + + if (using_synshm) { + synshm->touchpad_off = value; + return; + } + + devicelist = XListInputDevices (display, &numdevices); + + prop = XInternAtom(display, "Synaptics Off", False); + + for (i = 0; i < numdevices; i++) { + if ((devicelist[i].use >= IsXExtensionDevice) && + (device = device_is_touchpad(display, devicelist[i]))) { + XChangeDeviceProperty(display, device, prop, XA_INTEGER, 8, PropModeReplace, + (unsigned char *)&value, 1); + XCloseDevice(display, device); + } + } + XFree(devicelist); +} + static int -enable_touchpad(void) +enable_touchpad(Display *display) { int ret = 0; if (pad_disabled) { - synshm->touchpad_off = 0; + set_touchpad_off(display, 0); pad_disabled = 0; ret = 1; } @@ -87,7 +190,10 @@ enable_touchpad(void) static void signal_handler(int signum) { - enable_touchpad(); + Display *display = XOpenDisplay(NULL); + enable_touchpad(display); + XCloseDisplay(display); + if (pid_file) unlink(pid_file); kill(getpid(), signum); @@ -161,18 +267,54 @@ keyboard_activity(Display *display) * Return non-zero if any physical touchpad button is currently pressed. */ static int -touchpad_buttons_active(void) +touchpad_buttons_active(Display *display) { int i; - if (synshm->left || synshm->right || synshm->up || synshm->down) - return 1; - for (i = 0; i < 8; i++) - if (synshm->multi[i]) + if (using_synshm) { + if (synshm->left || synshm->right || synshm->up || synshm->down) return 1; - if (synshm->guest_left || synshm->guest_mid || synshm->guest_right) - return 1; - return 0; + for (i = 0; i < 8; i++) + if (synshm->multi[i]) + return 1; + if (synshm->guest_left || synshm->guest_mid || synshm->guest_right) + return 1; + return 0; + } + else { + XDevice *device; + XDeviceInfo *devicelist; + XDeviceState *state; + XButtonState *buttonstate; + XInputClass *class; + int numdevices, classno, buttonno; + int pressed = 0; + + devicelist = XListInputDevices (display, &numdevices); + for (i = 0; i < numdevices; i++) + if ((devicelist[i].use >= IsXExtensionDevice) && + (device = device_is_touchpad(display, devicelist[i]))) { + state = XQueryDeviceState(display, device); + class = state->data; + + for (classno = 0; classno < state->num_classes; classno++) + { + if (class->class == ButtonClass) + { + buttonstate = (XButtonState *)class; + for (buttonno = 1; buttonno <= buttonstate->num_buttons; buttonno++) + if (buttonstate->buttons[buttonno / 8] & (1 << (buttonno % 8))) + pressed = 1; + } + class = (XInputClass *)((char *) class + class->length); + } + XFree(state); + XCloseDevice(display, device); + break; + } + XFree(devicelist); + return pressed; + } } static double @@ -196,23 +338,20 @@ main_loop(Display *display, double idle_time, int poll_delay) current_time = get_time(); if (keyboard_activity(display)) last_activity = current_time; - if (touchpad_buttons_active()) + if (touchpad_buttons_active(display)) last_activity = 0.0; if (current_time > last_activity + idle_time) { /* Enable touchpad */ - if (enable_touchpad()) { + if (enable_touchpad(display)) { if (!background) printf("Enable\n"); } } else { /* Disable touchpad */ - if (!pad_disabled && !synshm->touchpad_off) { + if (!pad_disabled && !get_touchpad_off(display)) { if (!background) printf("Disable\n"); pad_disabled = 1; - if (disable_taps_only) - synshm->touchpad_off = 2; - else - synshm->touchpad_off = 1; + set_touchpad_off(display, disable_taps_only ? 2 : 1); } } @@ -426,7 +565,7 @@ void record_main_loop(Display* display, double idle_time) { } if (ret == 0 && pad_disabled) { /* timeout => enable event */ - enable_touchpad(); + enable_touchpad(display); if (!background) printf("enable touchpad\n"); } @@ -448,7 +587,7 @@ main(int argc, char *argv[]) /* Parse command line parameters */ - while ((c = getopt(argc, argv, "i:m:dtp:kKR?")) != EOF) { + while ((c = getopt(argc, argv, "i:m:dtp:kKRS?")) != EOF) { switch(c) { case 'i': idle_time = atof(optarg); @@ -475,6 +614,9 @@ main(int argc, char *argv[]) case 'R': use_xrecord = 0; break; + case 'S': + using_synshm = 1; + break; default: usage(); break; @@ -490,20 +632,42 @@ main(int argc, char *argv[]) exit(2); } - /* Connect to the shared memory area */ - if ((shmid = shmget(SHM_SYNAPTICS, sizeof(SynapticsSHM), 0)) == -1) { - if ((shmid = shmget(SHM_SYNAPTICS, 0, 0)) == -1) { - fprintf(stderr, "Can't access shared memory area. SHMConfig disabled?\n"); - exit(2); - } else { - fprintf(stderr, "Incorrect size of shared memory area. Incompatible driver version?\n"); + if (!using_synshm) { + XDeviceInfo *devicelist; + XDevice *device; + int numdevices, i; + + using_synshm = 1; + + devicelist = XListInputDevices (display, &numdevices); + for (i =0; i < numdevices; i++) + if ((devicelist[i].use >= IsXExtensionDevice) && + (device = device_is_touchpad(display, devicelist[i]))) { + XCloseDevice(display, device); + using_synshm = 0; + break; + } + XFree(devicelist); + } + + + if (using_synshm) { + /* Connect to the shared memory area */ + if ((shmid = shmget(SHM_SYNAPTICS, sizeof(SynapticsSHM), 0)) == -1) { + if ((shmid = shmget(SHM_SYNAPTICS, 0, 0)) == -1) { + fprintf(stderr, "Can't access shared memory area. SHMConfig disabled?\n"); + exit(2); + } else { + fprintf(stderr, "Incorrect size of shared memory area. Incompatible driver version?\n"); + exit(2); + } + } + + if ((synshm = (SynapticsSHM*) shmat(shmid, NULL, 0)) == NULL) { + perror("shmat"); exit(2); } } - if ((synshm = (SynapticsSHM*) shmat(shmid, NULL, 0)) == NULL) { - perror("shmat"); - exit(2); - } /* Install a signal handler to restore synaptics parameters on exit */ install_signal_handler(); @@ -534,7 +698,7 @@ main(int argc, char *argv[]) if (use_xrecord && check_xrecord(display)) { record_main_loop(display, idle_time); } else -#endif HAVE_XRECORD +#endif /* HAVE_XRECORD */ { setup_keyboard_mask(display, ignore_modifier_keys); |