diff options
author | Peter Osterlund <petero2@telia.com> | 2003-11-02 11:30:46 +0100 |
---|---|---|
committer | Peter Osterlund <petero2@telia.com> | 2006-04-09 04:01:20 +0200 |
commit | 91c7a9f8004eeed3f3c86863ae4c3c8112045fc4 (patch) | |
tree | cf465627278e3eb3b0694f9002c75e0375830c66 /syndaemon.c | |
parent | 282572e2ffd9ce3119dc750591b5633d854f1d67 (diff) |
Added "syndaemon", a program that monitors keyboard activity
and disables touchpad tapping when the keyboard is being used.
Diffstat (limited to 'syndaemon.c')
-rw-r--r-- | syndaemon.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/syndaemon.c b/syndaemon.c new file mode 100644 index 0000000..3759a08 --- /dev/null +++ b/syndaemon.c @@ -0,0 +1,194 @@ +#include <X11/Xlib.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/time.h> + +#include "synaptics.h" + +static SynapticsSHM *synshm; +static int pad_disabled; +static int saved_tap_time; + + +static void usage() +{ + fprintf(stderr, "Usage: syndaemon [-i idle-time]\n"); + fprintf(stderr, " -i How many seconds to wait after the last key press before\n"); + fprintf(stderr, " enabling the touchpad.\n"); + exit(1); +} + +static void signal_handler(int signum) +{ + if (pad_disabled) { + synshm->tap_time = saved_tap_time; + pad_disabled = 0; + } + kill(getpid(), signum); +} + +static void install_signal_handler() +{ + static int signals[] = { + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, + SIGBUS, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, + SIGALRM, SIGTERM, SIGPWR + }; + int i; + struct sigaction act; + sigset_t set; + + sigemptyset(&set); + act.sa_handler = signal_handler; + act.sa_mask = set; + act.sa_flags = SA_ONESHOT; + + for (i = 0; i < sizeof(signals) / sizeof(int); i++) { + if (sigaction(signals[i], &act, 0) == -1) { + perror("sigaction"); + exit(2); + } + } +} + +/** + * Return non-zero if the keyboard state has changed since the last call. + */ +static int keyboard_activity(Display *display) +{ + #define KEYMAP_SIZE 32 + static char old_key_state[KEYMAP_SIZE]; + char key_state[KEYMAP_SIZE]; + int i; + + XQueryKeymap(display, key_state); + + for (i = 0; i < KEYMAP_SIZE; i++) { + if (key_state[i] != old_key_state[i]) { + for (i = 0; i < KEYMAP_SIZE; i++) + old_key_state[i] = key_state[i]; + return 1; + } + } + return 0; +} + +/** + * Return non-zero if any physical touchpad button is currently pressed. + */ +static int touchpad_buttons_active() +{ + int i; + + if (synshm->left || synshm->right || synshm->up || synshm->down) + return 1; + for (i = 0; i < 8; i++) + if (synshm->multi[i]) + return 1; + return 0; +} + +static double get_time() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; +} + +static void main_loop(Display *display, double idle_time) +{ + const int poll_delay = 20000; /* 20 ms */ + double last_activity = 0.0; + double current_time; + + pad_disabled = 0; + keyboard_activity(display); + + for (;;) { + current_time = get_time(); + if (keyboard_activity(display)) + last_activity = current_time; + if (touchpad_buttons_active()) + last_activity = 0.0; + + if (current_time > last_activity + idle_time) { /* Enable touchpad */ + if (pad_disabled) { + printf("Enable\n"); + synshm->tap_time = saved_tap_time; + pad_disabled = 0; + } + } else { /* Disable touchpad */ + if (!pad_disabled) { + printf("Disable\n"); + saved_tap_time = synshm->tap_time; + synshm->tap_time = 0; + pad_disabled = 1; + } else { + /* Already disabled. Update saved_tap_time if needed */ + if (synshm->tap_time) { + printf("Updating tap_time\n"); + saved_tap_time = synshm->tap_time; + } + } + } + + usleep(poll_delay); + } +} + +int main(int argc, char *argv[]) +{ + double idle_time = 3.0; + Display *display; + int c; + int shmid; + + /* Parse command line parameters */ + while ((c = getopt(argc, argv, "i:")) != EOF) { + switch(c) { + case 'i': + idle_time = atof(optarg); + break; + default: + usage(); + break; + } + } + if (idle_time <= 0.0) + usage(); + + /* Open a connection to the X server */ + display = XOpenDisplay(NULL); + if (!display) { + fprintf(stderr, "Can't open display.\n"); + 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"); + 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(); + + /* Run the main loop */ + main_loop(display, idle_time); + + return 0; +} |