mirror of
https://github.com/X11Libre/xf86-input-synaptics.git
synced 2026-04-14 11:54:16 +00:00
Added "syndaemon", a program that monitors keyboard activity
and disables touchpad tapping when the keyboard is being used.
This commit is contained in:
16
Makefile
16
Makefile
@@ -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
194
syndaemon.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user