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