summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Grant <wgrant@ubuntu.com>2008-10-16 21:39:40 +0200
committerChristoph Brill <egore911@egore911.de>2008-10-16 21:39:40 +0200
commit934bc0012f948c52aadc8eda912f7728fb7394a2 (patch)
treeb192da5488d99bdda8e530f6801fb8670bb57dce
parent641b26da531b38313ecc68badac1a3ccfd6fc7af (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>
-rw-r--r--configure.ac2
-rw-r--r--tools/syndaemon.c228
2 files changed, 197 insertions, 33 deletions
diff --git a/configure.ac b/configure.ac
index 23c9f26..5727881 100644
--- a/configure.ac
+++ b/configure.ac
@@ -110,7 +110,7 @@ CFLAGS="$CFLAGS $XORG_CFLAGS "' -I$(top_srcdir)/src'
AC_SUBST([CFLAGS])
# Checks for libraries.
-PKG_CHECK_MODULES(XLIB, x11) # needed for syndaemon
+PKG_CHECK_MODULES(XLIB, x11 xi) # needed for syndaemon
PKG_CHECK_MODULES(XRECORD, xtst, AC_DEFINE([HAVE_XRECORD],[],[Use XRecord]), true)
# Checks for header files.
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);