diff options
-rw-r--r-- | 3de.c | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | plat.c | 70 | ||||
-rw-r--r-- | plat.h | 2 |
4 files changed, 72 insertions, 3 deletions
@@ -72,6 +72,7 @@ int entrypoint(int argc, const char** argv, Arena* a) { return error_out_of_memory; } preload_assets(&preload); + cfg_mouse(app, 0); while (app->o) { fps_begin(&f); while (f.now >= f.next) { @@ -4,7 +4,7 @@ linker = gcc cflags = -I./ -g -DDEBUG -Dplat_x11 -Dplat_x86 \ -Dplat_posix -Dallocation_default_alignment=8 \ -Wall -Wextra -pedantic -std=c90 -lflags = -lX11 +lflags = -lX11 -lXi int_dir = intermediate data_dir = data target = 3de @@ -256,6 +256,7 @@ int main(int argc, const char** argv) { #include <X11/Xlib.h> #include <X11/Xutil.h> +#include <X11/extensions/XInput2.h> #include <stdlib.h> @@ -264,6 +265,8 @@ typedef struct { Window wi; GC gc; int w, h; + int rmx, rmy; + int ms; unsigned long begin, end; XImage* bb; Colour* bbp; @@ -425,8 +428,32 @@ void app_begin(App* a) { i->h = mini(wa.height, max_pc_window_h); break; case MotionNotify: - a->mx = e.xmotion.x / a->s; - a->my = e.xmotion.y / a->s; + if (i->ms) { + a->mx = e.xmotion.x / a->s; + a->my = e.xmotion.y / a->s; + } + break; + case GenericEvent: + if (!i->ms) { + if ( + XGetEventData(d, &e.xcookie) && + e.xcookie.evtype == XI_RawMotion + ) { + XIRawEvent* re = e.xcookie.data; + if (re->valuators.mask_len) { + const double* values = re->raw_values; + if (XIMaskIsSet(re->valuators.mask, 0)) { + i->rmx += (int)values[0]; + } + if (XIMaskIsSet(re->valuators.mask, 1)) { + i->rmy += (int)values[1]; + } + a->mx = i->rmx / a->s; + a->my = i->rmy / a->s; + } + XFreeEventData(d, &e.xcookie); + } + } break; default: break; @@ -496,4 +523,43 @@ void app_end(App* a) { a->fps = 1000000000 / (i->end - i->begin); } +void cfg_mouse(App* a, int show) { + App_Internal* i = (App_Internal*)(&a[1]); + Display* d = i->d; + Window w = i->wi; + i->ms = show; + if (show) { + XUndefineCursor(d, w); + XUngrabPointer(d, CurrentTime); + } else { + XColor c; + char bd[1] = { 0 }; + Pixmap b = XCreateBitmapFromData(d, w, bd, 1, 1); + Cursor cur = XCreatePixmapCursor(d, b, b, &c, &c, 0, 0); + XIEventMask em; + unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 }; + XDefineCursor(d, w, cur); + XGrabPointer( + d, + w, + 1, + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask, + GrabModeAsync, + GrabModeAsync, + w, + None, + CurrentTime + ); + em.deviceid = XIAllMasterDevices; + em.mask_len = sizeof(mask); + em.mask = mask; + XISetMask(mask, XI_RawMotion); + XISelectEvents(d, DefaultRootWindow(d), &em, 1); + i->rmx = a->mx; + i->rmy = a->my; + } +} + #endif @@ -78,4 +78,6 @@ void deinit_app(App* a); void app_begin(App* a); void app_end(App* a); +void cfg_mouse(App* a, int show); + #endif |