anyscroll/anyscroll.c

147 lines
3.0 KiB
C
Raw Normal View History

2021-04-12 21:16:16 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <unistd.h>
2021-04-12 23:01:43 +00:00
#include <X11/extensions/XInput2.h>
#include <pthread.h>
2021-04-13 10:51:46 +00:00
#include <math.h>
2021-04-12 21:16:16 +00:00
static Display *dpy;
static int scr, sw, sh;
2021-04-12 23:21:44 +00:00
static int sx = -1, sy = -1;
2021-04-12 21:16:16 +00:00
static Window root;
static int tx, ty;
static int vx, vy;
static const int direction = -1; // direction to scroll in. 1 is natural, -1 is in direction of movement
static const int pixels_to_scroll = 8; // number of pixels to move before one scroll event
2021-04-12 23:21:44 +00:00
static void scroll(int v) {
2021-04-13 10:51:46 +00:00
v = v * direction;
printf("scrolling with v of %d\n", v);
2021-04-13 10:51:46 +00:00
2021-04-12 23:21:44 +00:00
int btn;
if (v > 0) btn = 4;
else if (v < 0) btn = 5;
else return;
int times = abs(v);
2021-04-13 10:51:46 +00:00
for (int i = 0; i < times; i++) {
tx++;
if (tx % pixels_to_scroll == 0) {
XTestFakeButtonEvent(dpy, btn, True, CurrentTime);
XFlush(dpy);
XTestFakeButtonEvent(dpy, btn, False, CurrentTime);
XFlush(dpy);
}
2021-04-12 23:21:44 +00:00
}
}
2021-04-12 23:01:43 +00:00
static void select_events(Display *dpy, Window win) {
2021-04-13 10:51:46 +00:00
XIEventMask evmasks[1];
unsigned char mask1[(XI_LASTEVENT + 7)/8];
2021-04-12 23:01:43 +00:00
2021-04-13 10:51:46 +00:00
memset(mask1, 0, sizeof(mask1));
2021-04-12 23:01:43 +00:00
2021-04-13 10:51:46 +00:00
XISetMask(mask1, XI_RawButtonPress);
XISetMask(mask1, XI_RawButtonRelease);
2021-04-12 23:01:43 +00:00
2021-04-13 10:51:46 +00:00
evmasks[0].deviceid = XIAllMasterDevices;
evmasks[0].mask_len = sizeof(mask1);
evmasks[0].mask = mask1;
2021-04-12 23:01:43 +00:00
2021-04-13 10:51:46 +00:00
XISelectEvents(dpy, win, evmasks, 1);
XFlush(dpy);
2021-04-12 21:16:16 +00:00
}
2021-04-12 23:01:43 +00:00
static void getmousepos(int *px, int *py) {
Window r, child;
int rx, ry;
unsigned int mask;
XQueryPointer(dpy, root, &r, &child, px, py, &rx, &ry, &mask);
2021-04-12 21:16:16 +00:00
}
2021-04-12 23:01:43 +00:00
static void* loop() {
int px, py, lx, ly, dx, dy;
while (1) {
lx = px, ly = py;
2021-04-12 23:01:43 +00:00
getmousepos(&px, &py);
dx = px - lx;
dy = py - ly;
2021-04-12 23:21:44 +00:00
if (sx != -1 && sy != -1) scroll(dy);
2021-04-12 23:01:43 +00:00
2021-04-13 10:51:46 +00:00
if (dx != 0 | dy != 0) {
//printf("%d, %d with deltas (%d, %d)\n", sx, sy, dx, dy);
2021-04-13 10:51:46 +00:00
}
sleep(0.1);
2021-04-12 23:01:43 +00:00
}
}
static void mouse_down(XIRawEvent *xev) {
getmousepos(&sx, &sy);
}
static void mouse_up(XIRawEvent *xev) {
sx = -1;
sy = -1;
}
int main(int argc, const char **argv) {
XInitThreads();
2021-04-12 21:16:16 +00:00
for (int i = 1; i < argc; i++) {
if (argv[i][1] == 'h') {
fprintf(stdout, "there is no help to be given\n");
}
}
if (!(dpy = XOpenDisplay(0x0))) return 1;
scr = DefaultScreen(dpy);
root = XDefaultRootWindow(dpy);
sw = DisplayWidth(dpy, scr);
sh = DisplayHeight(dpy, scr);
2021-04-13 10:51:46 +00:00
fprintf(stdout, "waiting for events...\n");
2021-04-12 21:16:16 +00:00
XEvent ev;
2021-04-12 23:01:43 +00:00
XIEvent *xi_event;
XIRawEvent *xev;
XGenericEventCookie *cookie = &ev.xcookie;
select_events(dpy, root);
2021-04-12 21:16:16 +00:00
2021-04-12 23:01:43 +00:00
pthread_t id[2];
pthread_create(&id[0], NULL, loop, &argv);
2021-04-12 21:16:16 +00:00
for (;;) {
2021-04-12 23:01:43 +00:00
if (XCheckTypedEvent(dpy, GenericEvent ,&ev)) {
if (cookie->type != GenericEvent || !XGetEventData(dpy, cookie)) {
continue;
}
2021-04-12 21:16:16 +00:00
2021-04-12 23:01:43 +00:00
xi_event = (XIEvent *) cookie->data;
xev = (XIRawEvent *) xi_event;
switch (cookie->evtype) {
case XI_RawButtonPress:
if (xev->detail == 2) mouse_down(xev);
2021-04-13 10:51:46 +00:00
break;
2021-04-12 23:01:43 +00:00
case XI_RawButtonRelease:
if (xev->detail == 2) mouse_up(xev);
2021-04-13 10:51:46 +00:00
break;
2021-04-12 23:01:43 +00:00
}
//if (t - CurrentTime < 500) {
// XFreeEventData(dpy, cookie);
//}
2021-04-12 23:01:43 +00:00
}
2021-04-13 10:51:46 +00:00
} // there is no way out of this loop lol
2021-04-12 21:16:16 +00:00
XCloseDisplay(dpy);
return 0;
}