Added "syndaemon", a program that monitors keyboard activity

and disables touchpad tapping when the keyboard is being used.
This commit is contained in:
Peter Osterlund
2003-11-02 11:30:46 +01:00
parent 282572e2ff
commit 91c7a9f800
2 changed files with 207 additions and 3 deletions

View File

@@ -45,13 +45,16 @@ DRIVER = synaptics
$(RM) $@
$(CC) -c $(CFLAGS) $(_NOOP_) $*.c
all:: $(DRIVER)_drv.o synclient
all:: $(DRIVER)_drv.o synclient syndaemon
install: $(BINDIR)/synclient $(INSTALLED_X)/lib/modules/input/$(DRIVER)_drv.o
install: $(BINDIR)/synclient $(BINDIR)/syndaemon $(INSTALLED_X)/lib/modules/input/$(DRIVER)_drv.o
$(BINDIR)/synclient : synclient
cp $< $@
$(BINDIR)/syndaemon : syndaemon
cp $< $@
$(INSTALLED_X)/lib/modules/input/$(DRIVER)_drv.o : $(DRIVER)_drv.o
cp $< $@
@@ -65,15 +68,22 @@ synclient.o : synclient.c
synclient : synclient.o
$(CC) -o $@ $< -lm
syndaemon.o : syndaemon.c
$(CC) $(CFLAGSCLIENT) -c -o $@ $<
syndaemon : syndaemon.o
$(CC) -o $@ $< -lm -L$(INSTALLED_X)/lib -lXext -lX11
testprotokoll: testprotokoll.c
$(CC) -o testprotokoll testprotokoll.c
synaptics.o : synaptics.h ps2comm.h linux_input.h
ps2comm.o : ps2comm.h
synclient.o : synaptics.h
syndeamon.o : synaptics.h
clean::
$(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut synclient "#"*
$(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut synclient syndaemon "#"*
tags::
etags -o TAGS *.c *.h

194
syndaemon.c Normal file
View File

@@ -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;
}