182 lines
4.1 KiB
C
182 lines
4.1 KiB
C
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include "../deps/nanocobs/cobs.h"
|
|
#include "../packet.h"
|
|
|
|
// 0 is little, 1 is big
|
|
#define srcend 0
|
|
#define tgtend 1
|
|
|
|
unsigned int w = 800;
|
|
unsigned int h = 600;
|
|
bool grabbed = false;
|
|
|
|
Display* dpy = NULL;
|
|
int screen;
|
|
Window root;
|
|
Window mousearea;
|
|
Window root_return, child_return;
|
|
int root_x, root_y, win_x, win_y;
|
|
unsigned int mask_return;
|
|
bool mb0, mb1;
|
|
unsigned int delay = 8333;
|
|
|
|
uint32_t scrapmem;
|
|
void* mbmap[] = {
|
|
&mb0,
|
|
&scrapmem,
|
|
&mb1,
|
|
&scrapmem,
|
|
&scrapmem, &scrapmem, &scrapmem, &scrapmem,
|
|
&scrapmem, &scrapmem, &scrapmem, &scrapmem,
|
|
&scrapmem, &scrapmem, &scrapmem, &scrapmem,
|
|
&scrapmem, &scrapmem, &scrapmem, &scrapmem,
|
|
&scrapmem, &scrapmem, &scrapmem, &scrapmem
|
|
};
|
|
|
|
void togglePtrLock() {
|
|
if (grabbed) {
|
|
XUngrabPointer(dpy, CurrentTime);
|
|
XStoreName(dpy, mousearea, "Mouse Area - Press F11 to lock");
|
|
} else {
|
|
int result =
|
|
XGrabPointer(dpy, mousearea, True,
|
|
PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
|
|
GrabModeAsync, GrabModeAsync,
|
|
mousearea, None, CurrentTime
|
|
);
|
|
if (result != GrabSuccess) printf("couldn't reserve control of the mouse pointer\n");
|
|
XStoreName(dpy, mousearea, "Mouse Area - Press F11 to unlock");
|
|
}
|
|
grabbed = !grabbed;
|
|
}
|
|
|
|
uint32_t byteSwap32(uint32_t n) {
|
|
#if srcend != tgtend
|
|
n = (n&0xFFFF0000)>>16|(n&0x0000FFFF)<<16;
|
|
n = (n&0xFF00FF00)>>8|(n&0x00FF00FF)<<8;
|
|
#endif
|
|
return n;
|
|
}
|
|
|
|
uint16_t byteSwap16(uint16_t n) {
|
|
#if srcend != tgtend
|
|
return ((n>>8)|(n<<8));
|
|
#else
|
|
return n;
|
|
#endif
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
printf("Amipathy Client v1\n"
|
|
"by bonkmaykr/madarao\n"
|
|
);
|
|
|
|
if (argc < 2 || argc > 3) {
|
|
printf(
|
|
"\nusage: amipathy <file> [rate]\n\n"
|
|
"The file should be a path to a TTY or serial device.\n"
|
|
"For example: amipathy /dev/ttyUSB0\n"
|
|
"Rate is the number of times the mouse info is written per second.\n"
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (argc > 2) delay = 1000000 / atoi(argv[2]);
|
|
|
|
FILE* com = fopen(argv[1], "r+b");
|
|
|
|
if (!com) {
|
|
printf("Can't open %s\n", argv[1]);
|
|
return 1;
|
|
}
|
|
|
|
dpy = XOpenDisplay(NULL);
|
|
screen = DefaultScreen(dpy);
|
|
root = DefaultRootWindow(dpy);
|
|
mousearea = XCreateSimpleWindow(
|
|
dpy, root,
|
|
0, 0, w, h, 0,
|
|
BlackPixel(dpy, screen),
|
|
BlackPixel(dpy, screen)
|
|
);
|
|
XStoreName(dpy, mousearea, "Mouse Area - Press F11 to unlock");
|
|
XMapWindow(dpy, mousearea);
|
|
|
|
togglePtrLock();
|
|
|
|
Atom wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
XSetWMProtocols(dpy, mousearea, &wm_delete, 1);
|
|
XSelectInput(dpy, mousearea,
|
|
ExposureMask |
|
|
KeyPressMask |
|
|
ButtonPressMask |
|
|
ButtonReleaseMask |
|
|
PointerMotionMask |
|
|
StructureNotifyMask
|
|
);
|
|
XEvent event;
|
|
bool first = true;
|
|
while (true) {
|
|
while (XPending(dpy)) {
|
|
XNextEvent(dpy, &event);
|
|
if (event.type == ClientMessage &&
|
|
(Atom)event.xclient.data.l[0] == wm_delete)
|
|
goto exit;
|
|
if (event.type == ButtonPress)
|
|
*(bool*)mbmap[event.xbutton.button-1] = true;
|
|
if (event.type == ButtonRelease)
|
|
*(bool*)mbmap[event.xbutton.button-1] = false;
|
|
}
|
|
if (XQueryPointer(dpy, mousearea,
|
|
&root_return, &child_return,
|
|
&root_x, &root_y,
|
|
&win_x, &win_y,
|
|
&mask_return)) {
|
|
if (!first) printf("\x1b[1F\x1b[2K");
|
|
printf("root=(%d, %d) win=(%d, %d) btn=(%d, %d)\n",
|
|
root_x, root_y, win_x, win_y, mb0, mb1);
|
|
struct packet p;
|
|
static const uint8_t delimit = 0x00;
|
|
p.magic = 0xFF;
|
|
p.x = byteSwap16((uint16_t)win_x);
|
|
p.y = byteSwap16((uint16_t)win_y);
|
|
p.mouse0 = mb0 ? 0xFF : 0x00;
|
|
p.mouse1 = mb1 ? 0xFF : 0x00;
|
|
p.sum = 0;
|
|
p.sum += p.magic;
|
|
p.sum += p.x;
|
|
p.sum += p.y;
|
|
p.sum += p.mouse0;
|
|
p.sum += p.mouse1;
|
|
uint8_t cobsbuf[sizeof(p)*2];
|
|
size_t cobslen = 0;
|
|
const cobs_ret_t cobsresult = cobs_encode(
|
|
&p, sizeof(p),
|
|
cobsbuf, sizeof(p)*2, &cobslen
|
|
);
|
|
if (cobsresult != COBS_RET_SUCCESS) {
|
|
printf("failed to encode packet!\n");
|
|
continue;
|
|
}
|
|
fwrite(&cobsbuf, cobslen, 1, com);
|
|
fwrite(&delimit, 1, 1, com);
|
|
fflush(com);
|
|
}
|
|
else abort();
|
|
|
|
usleep(delay);
|
|
first = false;
|
|
}
|
|
|
|
exit:
|
|
fclose(com);
|
|
XDestroyWindow(dpy, mousearea);
|
|
XCloseDisplay(dpy);
|
|
return 0;
|
|
} |