awesome/lib/constrain.c

88 lines
2.7 KiB
C
Raw Normal View History

2024-07-06 18:31:50 +00:00
#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;
}