diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1032916 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 4.3) +project(amipathy C) + +set(CMAKE_C_STANDARD 99) + +if(CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") + add_executable(amipathy_amiga + deps/nanocobs/cobs.c + amiga/main.c + ) + set(CMAKE_C_COMPILER /opt/amiga/bin/m68k-amigaos-gcc) + target_compile_options(amipathy_amiga PRIVATE "-w") +else() + add_executable(amipathy_pc + deps/nanocobs/cobs.c + pc/main.c + ) + target_link_libraries(amipathy_pc PRIVATE X11) +endif() \ No newline at end of file diff --git a/amiga/setmouse.c b/amiga/setmouse.c new file mode 100644 index 0000000..adaa9b0 --- /dev/null +++ b/amiga/setmouse.c @@ -0,0 +1,117 @@ +/* + * Set_Mouse.c + * + * This example sets the mouse at x=100 and y=200 + * + * Compile with SAS C 5.10: LC -b1 -cfistq -v -y -L + * Requires Kickstart 36 or greater. + * + * Run from CLI only + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#ifdef LATTICE +int CXBRK(void) { return(0); } /* Disable SAS CTRL/C handling */ +int chkabort(void) { return(0); } /* really */ +#endif + +struct IntuitionBase *Intuit; + +void main(void) +{ +struct IOStdReq *InputIO; /* I/O request block */ +struct MsgPort *InputMP; /* Message port */ +struct InputEvent *FakeEvent; /* InputEvent pointer */ +struct IEPointerPixel *NeoPix; /* New mouse position pointer */ +struct Screen *PubScreen; /* Screen pointer */ + +if (InputMP = CreateMsgPort()) + { + if (FakeEvent = AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC)) + { + if (NeoPix = AllocMem(sizeof(struct IEPointerPixel),MEMF_PUBLIC)) + { + if (InputIO = CreateIORequest(InputMP,sizeof(struct IOStdReq))) + { + if (!OpenDevice("input.device",NULL, + (struct IORequest *)InputIO,NULL)) + { + /* Open Intuition library */ + if (Intuit=(struct IntuitionBase *) + OpenLibrary("intuition.library",36L)) + { + /* Get pointer to screen and lock screen */ + if (PubScreen=(struct Screen *)LockPubScreen(NULL)) + { + /* Set up IEPointerPixel fields */ + /* WB screen */ + NeoPix->iepp_Screen=(struct Screen *)PubScreen; + /* put pointer at x = 100 */ + NeoPix->iepp_Position.X = 100; + /* put pointer at y = 200 */ + NeoPix->iepp_Position.Y = 200; + + /* Set up InputEvent fields */ + /* IEPointerPixel */ + FakeEvent->ie_EventAddress = (APTR)NeoPix; + FakeEvent->ie_NextEvent = NULL; + /* new mouse pos */ + FakeEvent->ie_Class = IECLASS_NEWPOINTERPOS; + /* on pixel */ + FakeEvent->ie_SubClass = IESUBCLASS_PIXEL; + FakeEvent->ie_Code = IECODE_NOBUTTON; + /* absolute positioning */ + FakeEvent->ie_Qualifier = NULL; + + /* InputEvent */ + InputIO->io_Data = (APTR)FakeEvent; + InputIO->io_Length = sizeof(struct InputEvent); + InputIO->io_Command = IND_WRITEEVENT; + DoIO((struct IORequest *)InputIO); + /* Unlock screen */ + UnlockPubScreen(NULL,PubScreen); + } + else + printf("Could not get pointer to screen\n"); + /* Close intuition library */ + CloseLibrary(Intuit); + } + else + /* Can't open V36 (or higher) intuition.library */ + printf("Error:Can't open V36 intuition.library\n"); + + CloseDevice((struct IORequest *)InputIO); + } + else + printf("Error: Could not open input.device\n"); + + DeleteIORequest(InputIO); + } + else + printf("Error: Could not create IORequest\n"); + + FreeMem(NeoPix,sizeof(struct IEPointerPixel)); + } + else + printf("Error: Could not allocate memory for NeoPix\n"); + + FreeMem(FakeEvent,sizeof(struct InputEvent)); + } + else + printf("Error: Could not allocate memory for FakeEvent\n"); + + DeleteMsgPort(InputMP); + } +else + printf("Error: Could not create message port\n"); +} diff --git a/pc/main.c b/pc/main.c new file mode 100644 index 0000000..42a2c1d --- /dev/null +++ b/pc/main.c @@ -0,0 +1,182 @@ +#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; +} \ No newline at end of file