88 lines
2.7 KiB
C
88 lines
2.7 KiB
C
|
#include <lua.h>
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include <X11/Xatom.h>
|
||
|
#include <X11/Xlib.h>
|
||
|
#include <X11/extensions/Xfixes.h>
|
||
|
#include <X11/extensions/XInput2.h>
|
||
|
#include <X11/extensions/Xrandr.h>
|
||
|
#include <threads.h>
|
||
|
|
||
|
#define DEBUG
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
static FILE *log_file = NULL;
|
||
|
static void dbg(const char *fmt, ...) {
|
||
|
va_list args;
|
||
|
if (log_file == NULL) {
|
||
|
log_file = fopen("/home/mutzi/xdpb.txt", "a+");
|
||
|
}
|
||
|
va_start(args, fmt);
|
||
|
vfprintf(log_file, fmt, args);
|
||
|
va_end(args);
|
||
|
fflush(log_file);
|
||
|
}
|
||
|
#else
|
||
|
static inline void dbg(const char *fmt, ...) {}
|
||
|
#endif
|
||
|
|
||
|
static struct {
|
||
|
Display *display;
|
||
|
Window root_window;
|
||
|
|
||
|
int have_barriers;
|
||
|
PointerBarrier t, b, l, r;
|
||
|
} globals;
|
||
|
|
||
|
static PointerBarrier mkbar(int x1, int y1, int x2, int y2, int directions) {
|
||
|
PointerBarrier pb = XFixesCreatePointerBarrier(globals.display, globals.root_window, x1, y1, x2, y2, directions, 0, NULL);
|
||
|
dbg("mkbar(%d, %d, %d, %d, %d) = %lu\n", x1, y1, x2, y2, directions, pb);
|
||
|
return pb;
|
||
|
}
|
||
|
|
||
|
static int toggle_constrain(lua_State *L) {
|
||
|
dbg("Toggling constrain\n");
|
||
|
if (globals.have_barriers == 0) {
|
||
|
lua_getfield(L, -1, "x");
|
||
|
lua_getfield(L, -2, "y");
|
||
|
lua_getfield(L, -3, "width");
|
||
|
lua_getfield(L, -4, "height");
|
||
|
|
||
|
int x = (int)lua_tointeger(L, -4), y = (int)lua_tointeger(L, -3), w = (int)lua_tointeger(L, -2), h = (int)lua_tointeger(L, -1);
|
||
|
|
||
|
dbg("Window x: %d y: %d w: %d h: %d\n", x, y, w, h);
|
||
|
|
||
|
globals.t = mkbar(x - 1, y, x + w + 1, y, BarrierPositiveY);
|
||
|
globals.b = mkbar(x - 1, y + h, x + w + 1, y + h, BarrierNegativeY);
|
||
|
globals.l = mkbar(x, y - 1, x, y + h + 1, BarrierPositiveX);
|
||
|
globals.r = mkbar(x + w, y - 1, x + w, y + h + 1, BarrierNegativeX);
|
||
|
|
||
|
globals.have_barriers = 1;
|
||
|
char msg_format[200];
|
||
|
lua_getfield(L, -5, "name");
|
||
|
snprintf(msg_format, 200, "Constraining mouse to %s", lua_tostring(L, -1));
|
||
|
lua_pushstring(L, msg_format);
|
||
|
} else {
|
||
|
XFixesDestroyPointerBarrier(globals.display, globals.t);
|
||
|
XFixesDestroyPointerBarrier(globals.display, globals.b);
|
||
|
XFixesDestroyPointerBarrier(globals.display, globals.l);
|
||
|
XFixesDestroyPointerBarrier(globals.display, globals.r);
|
||
|
|
||
|
globals.have_barriers = 0;
|
||
|
lua_pushstring(L, "Released mouse");
|
||
|
}
|
||
|
XSync(globals.display, 0);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int luaopen_libconstrain(lua_State *L) {
|
||
|
dbg("Constrain opened\n");
|
||
|
globals.have_barriers = 0;
|
||
|
globals.display = XOpenDisplay(NULL);
|
||
|
globals.root_window = XDefaultRootWindow(globals.display);
|
||
|
lua_newtable(L);
|
||
|
lua_pushcfunction(L, toggle_constrain);
|
||
|
lua_setfield(L, -2, "toggle");
|
||
|
return 1;
|
||
|
}
|