115 lines
2.4 KiB
C
115 lines
2.4 KiB
C
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <X11/Xlib.h>
|
|
|
|
#include "event.h"
|
|
#include "read_events.h"
|
|
|
|
args_cancel_thread_read* init_args_read(int fd, event *user_event, Display *display)
|
|
{
|
|
args_cancel_thread_read *ret = (args_cancel_thread_read *) malloc(sizeof(args_cancel_thread_read));
|
|
ret->fd = fd;
|
|
ret->user_event = user_event;
|
|
ret->display = display;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void cancel_read_events(args_cancel_thread_read *arg)
|
|
{
|
|
int fd = arg->fd;
|
|
/* flush the middle button */
|
|
unsigned char data[3];
|
|
read(fd, data, sizeof(data));
|
|
read(fd, data, sizeof(data));
|
|
|
|
free(arg->user_event);
|
|
close(fd);
|
|
XCloseDisplay(arg->display);
|
|
free(arg);
|
|
}
|
|
|
|
void write_event(event *new_event, FILE *file)
|
|
{
|
|
fwrite(new_event, sizeof(event), 1, file);
|
|
fflush(file);
|
|
}
|
|
|
|
int listen(FILE *file)
|
|
{
|
|
event *user_event = new_event();
|
|
|
|
Display *display = XOpenDisplay(0);
|
|
Window root_window = DefaultRootWindow(display);
|
|
|
|
XEvent event;
|
|
|
|
int bytes;
|
|
unsigned char data[3];
|
|
const char *pDevice = "/dev/input/mice";
|
|
|
|
int left = 0;
|
|
int right = 0;
|
|
int middle = 0;
|
|
|
|
int fd = open(pDevice, O_RDWR);
|
|
if (fd == -1)
|
|
{
|
|
printf("ERROR Opening %s\n", pDevice);
|
|
return -1;
|
|
}
|
|
|
|
pthread_cleanup_push(cancel_read_events, init_args_read(fd, user_event, display));
|
|
|
|
while (1)
|
|
{
|
|
/* Read Mouse */
|
|
bytes = read(fd, data, sizeof(data));
|
|
|
|
if (bytes > 0)
|
|
{
|
|
left = data[0] & 0x1;
|
|
right = data[0] & 0x2;
|
|
middle = data[0] & 0x4;
|
|
|
|
XQueryPointer(
|
|
display,
|
|
root_window,
|
|
&event.xbutton.root,
|
|
&event.xbutton.subwindow,
|
|
&event.xbutton.x_root,
|
|
&event.xbutton.y_root,
|
|
&event.xbutton.x,
|
|
&event.xbutton.y,
|
|
&event.xbutton.state
|
|
);
|
|
|
|
/* printf("%d - %d\n", event.xmotion.x, event.xmotion.y); */
|
|
|
|
if (left || right) {
|
|
mouse_button type_button = M_NONE;
|
|
if (left) type_button |= M_LEFT;
|
|
if (right) type_button |= M_RIGHT;
|
|
if (middle) type_button |= M_MIDDLE;
|
|
|
|
mouse_event_coord(user_event, type_button, event.xmotion.x, event.xmotion.y);
|
|
write_event(user_event, file);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* flush the middle button */
|
|
bytes = read(fd, data, sizeof(data));
|
|
bytes = read(fd, data, sizeof(data));
|
|
|
|
free(user_event);
|
|
close(fd);
|
|
XCloseDisplay(display);
|
|
|
|
pthread_cleanup_pop(1);
|
|
return 0;
|
|
}
|