#include #include #include #include #include #include #include #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 [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; }