winpl

LD_PRELOAD-based X11 window manipulator
git clone https://git.sinitax.com/sinitax/winpl
Log | Files | Refs | LICENSE | sfeed.txt

commit c592a9acbdccccf84009de2e0d68d0fca2d7a2d3
parent 852bc9bb1cf7bd8b0af65b5b3caa1378e6cda63c
Author: Louis Burda <quent.burda@gmail.com>
Date:   Tue, 12 Apr 2022 22:39:49 +0200

Refactoring and added loader for usability

Diffstat:
M.gitignore | 4+++-
AMakefile | 23+++++++++++++++++++++++
DREADME | 13-------------
Aloader.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dmakefile | 5-----
Dtest.sh | 5-----
Awinpl.c | 359+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dwinpreload.c | 375-------------------------------------------------------------------------------
8 files changed, 495 insertions(+), 399 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1 +1,3 @@ -winpreload.so +winpl.so.o +winpl.so +winpl diff --git a/Makefile b/Makefile @@ -0,0 +1,23 @@ +CFLAGS = --std=gnu99 -Wmissing-prototypes -Wunused-variable -g +LIB_FLAGS = $(CFLAGS) -nostartfiles -fPIC -shared -Wl,-soname,xwrap.so +LOADER_FLAGS = $(CFLAGS) +LDLIBS = -ldl -lX11 -lXinerama + +.PHONY: all clean + +all: winpl + +clean: + rm -f winpl winpl.so winpl.so.o + +winpl: loader.c winpl.so.o + $(CC) -o $@ $^ $(LOADER_FLAGS) + +winpl.so: winpl.c + $(CC) -o $@ $< $(LIB_FLAGS) $(LDLIBS) + +winpl.so.o: winpl.so + objcopy --input binary --output elf64-x86-64 \ + --binary-architecture i386:x86-64 $< $@ + + diff --git a/README b/README @@ -1,13 +0,0 @@ -winpreload -========== - - -Ideology --------- - -Winpreload is a non-invasive way of modifying window properties for -windows created by a program through the use of LD_PRELOAD. This -enables the user to set properties such as _NET_WM_WINDOW_TYPE to -start the window as floating and adjust its position. Parameters -are passed to winpreload via environment variables, which are -prefixed with 'WINPRELOAD_'. diff --git a/loader.c b/loader.c @@ -0,0 +1,110 @@ +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/stat.h> + +#define ARRLEN(x) (sizeof(x) / sizeof((x)[0])) + +#define ERROR(msg) { fprintf(stderr, "winpl: %s\n", msg); exit(1); } + +extern char _binary_winpl_so_start[]; +extern char _binary_winpl_so_end[]; + +extern char **environ; + +static void write_lib(const char *filename); +static bool parse_arg(const char *arg); + +static const char *conv[][2] = { + { "wx:", "WINPL_WX" }, + { "wy:", "WINPL_WY" }, + { "rwx:", "WINPL_RWX" }, + { "rwy:", "WINPL_RWY" }, + { "mwx:", "WINPL_MWX" }, + { "mwy:", "WINPL_MWY" }, + { "ww:", "WINPL_WW" }, + { "wh:", "WINPL_WH" }, + { "rww:", "WINPL_RWW" }, + { "rwh:", "WINPL_RWH" }, + { "center", "WINPL_CENTER" }, + { "float", "WINPL_FLOAT" }, +}; + +void +write_lib(const char *filename) +{ + FILE *file; + void *data; + size_t expected, actual; + + file = fopen(filename, "w+"); + if (!file) ERROR("Failed to create temp file"); + + data = (void*) _binary_winpl_so_start; + expected = (size_t) (_binary_winpl_so_end - _binary_winpl_so_start); + + actual = fwrite(data, 1, expected, file); + if (actual != expected) ERROR("Failed to write temp file"); + + fclose(file); +} + +bool +parse_arg(const char *arg) +{ + int i, len; + + for (i = 0; i < ARRLEN(conv); i++) { + len = strlen(conv[i][0]); + if (strncmp(arg, conv[i][0], len)) + continue; + + if (conv[i][0][len-1] == ':') { + setenv(conv[i][1], arg + len, true); + } else if (!arg[len]) { + setenv(conv[i][1], "1", true); + } else { + return false;; + } + + return true; + } + + return false; +} + +int +main(int argc, char *const *argv) +{ + char *tmpfile = "/tmp/winpl.so"; + struct stat st; + char *const *arg, *const *cmd; + + if (argc < 1) return 0; + + cmd = NULL; + for (arg = argv + 1; *arg; arg++) { + if (!strcmp(*arg, "--") && *(arg+1)) { + cmd = arg + 1; + break; + } + + if (!parse_arg(*arg)) + ERROR("Invalid argument"); + } + + if (cmd == NULL) + ERROR("Missing args separator"); + + if (stat(*cmd, &st)) + ERROR("Binary not full path"); + + if (stat(tmpfile, &st)) + write_lib(tmpfile); + + setenv("LD_PRELOAD", tmpfile, true); + + execve(*cmd, cmd, environ); +} diff --git a/makefile b/makefile @@ -1,5 +0,0 @@ -CFLAGS = -nostartfiles -fPIC -shared -Wl,-soname,xwrap.so --std=gnu99 -LDLIBS = -ldl -lX11 -lXinerama - -winpreload.so: winpreload.c - $(CC) -o $@ $< $(CFLAGS) $(LDLIBS) diff --git a/test.sh b/test.sh @@ -1,5 +0,0 @@ -#!/bin/bash - -SCRIPTPATH="$(dirname $(readlink -f "$0"))" -LD_PRELOAD="$SCRIPTPATH/winpreload.so" xclock - diff --git a/winpl.c b/winpl.c @@ -0,0 +1,359 @@ +/* original: https://www.mail-archive.com/devel@xfree86.org/msg05806.html */ + +#include <X11/Xlib.h> +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/extensions/Xinerama.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/utsname.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <stdarg.h> +#include <string.h> +#include <dlfcn.h> +#include <unistd.h> + +#define MAX(a,b) ((a > b) ? a : b) +#define MIN(a,b) ((a < b) ? a : b) + +#define ERROR(msg) { fprintf(stderr, "winpl: %s\n", msg); exit(1); } + +extern char **environ; + +static const char prefix[] = "WINPL_"; +static const int prefixlen = sizeof(prefix) - 1; + +static void *lib_xlib = NULL; + +static char **iter_args(char **env, const char **key, size_t *keylen, + const char **val); + +static int intersection_area(XineramaScreenInfo *info, XWindowAttributes *wa); + +static int monitor_from_pointer(XineramaScreenInfo *info, int mcount, + Display *display, Window window); +static int monitor_from_focussed(Display *display, XineramaScreenInfo *info, + int mcount); + +static void set_prop(Display *display, Window window, const char *name, + int type, size_t size, void *val); +static void set_props(Display *display, Window window); + +char ** +iter_args(char **env, const char **key, size_t *keylen, const char **val) +{ + const char *tok; + + for (; *env; env++) { \ + if (strncmp(*env, prefix, prefixlen)) + continue; + *key = *env + prefixlen; + tok = strchr(*env, '='); + if (!tok) continue; + *keylen = tok - *env - prefixlen; + *val = tok + 1; + return env + 1; + } + + return NULL; +} + +int +intersection_area(XineramaScreenInfo *info, XWindowAttributes *wa) +{ + int dx, dy; + + dx = MIN(wa->x + wa->width, info->x_org + info->width); + dx -= MAX(wa->x, info->x_org); + + dy = MIN(wa->y + wa->height, info->y_org + info->height); + dy -= MAX(wa->y, info->y_org); + + return MAX(0, dx) * MAX(0, dy); +} + +int +monitor_from_pointer(XineramaScreenInfo *info, int mcount, + Display *display, Window window) +{ + Window dummy; + int x = 0, y = 0, di, i, screen; + unsigned int dui; + + screen = -1; + XQueryPointer(display, window, &dummy, &dummy, + &x, &y, &di, &di, &dui); + + for (i = 0; i < mcount; i++) { + if (x >= info[i].x_org && y >= info[i].y_org + && x < info[i].x_org + info[i].width + && y < info[i].y_org + info[i].height) { + screen = i; + break; + } + } + + return screen; +} + +#define INTERSECT(x,y,w,h,r) ( + + +int +monitor_from_focussed(Display *display, XineramaScreenInfo *info, int mcount) +{ + Window w, root, *dws, dw, pw; + XWindowAttributes wa; + int di, area, maxarea, i; + unsigned du; + int screen; + + screen = -1; + root = XDefaultRootWindow(display); + + /* check if a focussed window exists.. */ + XGetInputFocus(display, &w, &di); + + /* modified snippet from dmenu-4.9 source */ + if (w != root && w != PointerRoot && w != None) { + do { + if (XQueryTree(display, (pw = w), &dw, &w, &dws, &du) && dws) + XFree(dws); + } while (w != root && w != pw); + + /* find xinerama screen with largest screen intersection */ + if (XGetWindowAttributes(display, pw, &wa)) { + for (i = 0; i < mcount; i++) { + area = intersection_area(&info[i], &wa); + if (area > maxarea) { + maxarea = area; + screen = i; + } + } + } + } + + return screen; +} + +void +set_prop(Display *display, Window window, const char *name, + int type, size_t size, void *val) +{ + int atom; + + atom = XInternAtom(display, name, False); + XChangeProperty(display, window, atom, type, size, + PropModeReplace, val, 1); +} + +void +set_props(Display *display, Window window) +{ + int wx, wy, mx, my; + unsigned int ww, wh, mw, mh; + const char *key, *val; + unsigned int border, depth; + size_t keylen; + char **env; + Window root; + Atom atom; + pid_t pid, ppid; + uid_t uid; + + uid = getuid(); + pid = getpid(); + ppid = getppid(); + + if (!XGetGeometry(display, window, &root, + &wx, &wy, &ww, &wh, &border, &depth)) + ERROR("Failed to get window geometry"); + + if (!XGetGeometry(display, root, &root, + &mx, &my, &mw, &mh, &border, &depth)) + ERROR("Failed to get screen geometry"); + + if (XineramaIsActive(display)) { + XineramaScreenInfo *info; + int mcount, screen; + + if (!(info = XineramaQueryScreens(display, &mcount))) + ERROR("Failed to query xinerama"); + + screen = -1; + + env = environ; + while ((env = iter_args(env, &key, &keylen, &val))) { + if (!strncmp("SCREEN_NUM", key, keylen)) { + screen = strtoul(val, NULL, 0); + if (screen >= mcount || screen < 0) + ERROR("Screen out-of-bounds"); + } else if (!strncmp("SCREEN_PTR", key, keylen)) { + screen = monitor_from_pointer(info, + mcount, display, window); + } + } + + if (screen == -1) + screen = monitor_from_focussed(display, + info, mcount); + + if (screen == -1) + screen = monitor_from_pointer(info, mcount, + display, window); + + if (screen == -1) + ERROR("Failed to get screen"); + + mx = info[screen].x_org; + my = info[screen].y_org; + mw = info[screen].width; + mh = info[screen].height; + } + + env = environ; + while ((env = iter_args(env, &key, &keylen, &val))) { + if (!strncmp(key, "WX", keylen)) { + /* absolute window x */ + wx = strtoul(val, NULL, 0); + } else if (!strncmp(key, "WY", keylen)) { + /* absolute window y */ + wy = strtoul(val, NULL, 0); + } else if (!strncmp(key, "RWX", keylen)) { + /* window x relative to monitor size */ + wx = mw * strtof(val, NULL); + } else if (!strncmp(key, "RWY", keylen)) { + /* window y relative to monitor size */ + wy = mh * strtof(val, NULL); + } else if (!strncmp(key, "MWX", keylen)) { + /* window x from monitor top left */ + wx = mx + strtoul(val, NULL, 0); + } else if (!strncmp(key, "MWY", keylen)) { + /* window y from monitor top left */ + wy = my + strtoul(val, NULL, 0); + } else if (!strncmp(key, "WW", keylen)) { + /* window width */ + ww = strtoul(val, NULL, 0); + } else if (!strncmp(key, "WH", keylen)) { + /* window height */ + wh = strtoul(val, NULL, 0); + } else if (!strncmp(key, "RWW", keylen)) { + /* window width relative to monitor size */ + ww = mw * strtof(val, NULL); + } else if (!strncmp(key, "RWH", keylen)) { + /* window height relative to monitor size */ + wh = mh * strtof(val, NULL); + } else if (!strncmp(key, "CENTER", keylen)) { + /* window centered in monitor */ + wx = mx + (mw - ww) / 2.f; + wy = my + (mh - wh) / 2.f; + } else if (!strncmp(key, "FLOAT", keylen)) { + /* window 'floating' in tiled WM */ + atom = XInternAtom(display, + "_NET_WM_WINDOW_TYPE_DIALOG", False); + set_prop(display, window, "_NET_WM_WINDOW_TYPE", + XA_ATOM, 32, &atom); + } + } + + /* set basic properties */ + set_prop(display, window, "_NET_WM_UID", + XA_CARDINAL, 32, &uid); + set_prop(display, window, "_NET_WM_PID", + XA_CARDINAL, 32, &pid); + set_prop(display, window, "_NET_WM_PPID", + XA_CARDINAL, 32, &ppid); + + /* update window pos and geometry */ + XMoveWindow(display, window, wx, wy); + XResizeWindow(display, window, ww, wh); +} + +Window +XCreateWindow(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, unsigned int border_width, + int depth, unsigned int class, Visual *visual, unsigned long valuemask, + XSetWindowAttributes *attributes) +{ + static Window (*func)(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, unsigned int class, + Visual *visual, unsigned long valuemask, + XSetWindowAttributes *attributes) = NULL; + Window window; + int i; + + if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); + if (!func) func = dlsym (lib_xlib, "XCreateWindow"); + + for (i = 0; i < ScreenCount(display); i++) { + /* for toplevel windows */ + if (parent == RootWindow(display, i)) { + window = (*func) (display, parent, x, y, width, height, + border_width, depth, class, visual, valuemask, attributes); + set_props(display, window); + return window; + } + } + + /* create window as usual */ + return (*func) (display, parent, x, y, width, height, border_width, depth, + class, visual, valuemask, attributes); +} + +Window +XCreateSimpleWindow(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, unsigned int border_width, + unsigned long border, unsigned long background) +{ + static Window (*func)(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, unsigned long border, + unsigned long background) = NULL; + Window window; + int i; + + if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); + if (!func) func = dlsym (lib_xlib, "XCreateSimpleWindow"); + + for (i = 0; i < ScreenCount(display); i++) { + /* for toplevel windows */ + if (parent == RootWindow(display, i)) { + window = (*func) (display, parent, x, y, width, height, + border_width, border, background); + set_props(display, window); + return window; + } + } + + /* create window as usual */ + return (*func) (display, parent, x, y, width, height, + border_width, border, background); +} + +int +XReparentWindow(Display *display, Window window, Window parent, int x, int y) +{ + static int (*func)(Display *display, Window window, Window parent, + int x, int y) = NULL; + int i; + + if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); + if (!func) func = dlsym (lib_xlib, "XReparentWindow"); + + for (i = 0; i < ScreenCount(display); i++) { + /* for toplevel windows */ + if (parent == RootWindow(display, i)) { + set_props(display, window); + return (*func)(display, window, parent, x, y); + } + } + + /* reparent as usual */ + return (*func) (display, window, parent, x, y); +} + diff --git a/winpreload.c b/winpreload.c @@ -1,375 +0,0 @@ -/* original source by https://www.mail-archive.com/devel@xfree86.org/msg05806.html */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <dlfcn.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/utsname.h> -#include <X11/Xlib.h> -#include <X11/X.h> -#include <X11/Xatom.h> -#include <X11/extensions/Xinerama.h> - -extern char **environ; - -static const char env_prefix[] = "WINPL_"; -static const int env_prefixlen = sizeof(env_prefix) - 1; -/* dlopened xlib so we can find the symbols in the real xlib to call them */ -static void *lib_xlib = NULL; - -#define MAX(a,b) ((a > b) ? a : b) -#define MIN(a,b) ((a < b) ? a : b) -#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) \ - - MAX((x),(r).x_org)) \ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) \ - - MAX((y),(r).y_org))) -#define ERRQUIT(msg) { fprintf(stderr, msg); exit(1); } -#define ENVPARSE(...) \ - { \ - char **__envvar, *__enviter, *key, *value, __varbuf[256]; \ - for (__envvar = environ; *__envvar; __envvar++) { \ - strncpy(__varbuf, *__envvar, sizeof(__varbuf) - 1); \ - __varbuf[sizeof(__varbuf) - 1] = '\0'; \ - __enviter = strchr(__varbuf, '='); \ - if (!__enviter) continue; \ - *__enviter = '\0'; \ - key = __varbuf; \ - value = __enviter + 1; \ - if (strncmp(key, env_prefix, env_prefixlen)) \ - continue; \ - key = &key[env_prefixlen]; \ - __VA_ARGS__ \ - } \ - } -#define SETFMTPROP(name, format, val) \ - { \ - int __atom; \ - char __buf[1024]; \ - snprintf(__buf, sizeof(__buf), format, val); \ - __atom = XInternAtom(display, name, False); \ - XChangeProperty(display, window, __atom, XA_STRING, 8, \ - PropModeReplace, (unsigned char*) __buf, strlen(__buf)); \ - } -#define SETPROP(name, type, size, val) \ - { \ - int __atom; \ - __atom = XInternAtom(display, name, False); \ - XChangeProperty(display, window, __atom, type, size, \ - PropModeReplace, val, 1); \ - } - -/* prototypes */ -static void set_properties(Display *display, Window window); - -int -monitor_by_pointer(XineramaScreenInfo *info, int mcount, - Display *display, Window window) -{ - Window dummy; - int x = 0, y = 0, di, i, screen; - unsigned int dui; - - /* determine monitor by where the pointer is */ - XQueryPointer(display, window, &dummy, &dummy, - &x, &y, &di, &di, &dui); - - for (screen = i = 0; i < mcount; i++) { - if (x >= info[i].x_org && y >= info[i].y_org - && x < info[i].x_org + info[i].width - && y < info[i].y_org + info[i].height) { - screen = i; - break; - } - } - - if (i == mcount) - return -1; - else - return screen; -} - -void -set_properties(Display *display, Window window) -{ - int wx, wy, mx, my; - unsigned int ww, wh, mw, mh; - char *env = NULL; - - { - Window root; - unsigned int border, depth; - - /* get window geometry */ - if (!XGetGeometry(display, window, &root, - &wx, &wy, &ww, &wh, &border, &depth)) - ERRQUIT("winpreload: unable to determine window geometry\n"); - - /* use root geometry for monitor as default */ - if (!XGetGeometry(display, root, &root, - &mx, &my, &mw, &mh, &border, &depth)) - ERRQUIT("winpreload: unable to determine screen geometry\n"); - } - - /* parse env for screen-related vars first */ - if (XineramaIsActive(display)) { - XineramaScreenInfo *info; - int mcount, screen, set; - - if (!(info = XineramaQueryScreens(display, &mcount))) - goto cleanup_xinerama; - - /* NOTE: - * for dwm (tested ver 4.9), windows are contrained to the dimensions of - * their monitor (which is the selected monitor on creation). Because of - * this, it is not possible to init the screen position outside the - * selected monitor.. a patch of dwm or some kind of signal that the - * selected monitor should be changed is necessary - */ - screen = 0; - set = 0; - ENVPARSE( - if (!strcmp("SCREEN_NUM", key)) { - set = 1; - screen = strtoul(value, NULL, 0); - if (screen >= mcount) - ERRQUIT("winpreload: invalid screen number specified\n"); - } else if (!strcmp("SCREEN_PTR", key)) { - set = 1; - screen = monitor_by_pointer(info, mcount, display, window); - if (screen == -1) - goto cleanup_xinerama; - } - ) - - if (!set) { - Window w, root, *dws, dw, pw; - XWindowAttributes wa; - int di, a, area, i; - unsigned du; - - root = XDefaultRootWindow(display); - screen = -1; - - /* check if a focussed window exists.. */ - XGetInputFocus(display, &w, &di); - /* modified snippet from dmenu-4.9 source */ - if (w != root && w != PointerRoot && w != None) { - do { - if (XQueryTree(display, (pw = w), &dw, &w, &dws, &du) && dws) - XFree(dws); - } while (w != root && w != pw); - /* find xinerama screen with which the window intersects most */ - if (XGetWindowAttributes(display, pw, &wa)) { - for (i = 0; i < mcount; i++) { - a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[i]); - if (a > area) { - area = a; - screen = i; - } - } - } - } - - /* ..else try by pointer */ - if (screen == -1) { - screen = monitor_by_pointer(info, mcount, display, window); - if (screen == -1) - goto cleanup_xinerama; - } - } - - mx = info[screen].x_org; - my = info[screen].y_org; - mw = info[screen].width; - mh = info[screen].height; - -cleanup_xinerama: - XFree(info); - } - - ENVPARSE( - if (!strcmp(key, "WX")) { /* absolute window x */ - wx = strtoul(value, NULL, 0); - } else if (!strcmp(key, "WY")) { /* absolute window y */ - wy = strtoul(value, NULL, 0); - } else if (!strcmp(key, "RWX")) { /* window x relative to monitor rsize */ - wx = mw * strtof(value, NULL); - } else if (!strcmp(key, "RWY")) { /* window y relative to monitor size */ - wy = mh * strtof(value, NULL); - } else if (!strcmp(key, "MWX")) { /* window x from monitor top left */ - wx = mx + strtoul(value, NULL, 0); - } else if (!strcmp(key, "MWY")) { /* window y from monitor top left */ - wy = my + strtoul(value, NULL, 0); - } else if (!strcmp(key, "WW")) { /* window width */ - ww = strtoul(value, NULL, 0); - } else if (!strcmp(key, "WH")) { /* window height */ - wh = strtoul(value, NULL, 0); - } else if (!strcmp(key, "RWW")) { /* window width relative to monitor size */ - ww = mw * strtof(value, NULL); - } else if (!strcmp(key, "RWH")) { /* window height relative to monitor size */ - wh = mh * strtof(value, NULL); - } else if (!strcmp(key, "CENTER")) { /* window centered in monitor */ - wx = mx + (mw - ww) / 2.f; - wy = my + (mh - wh) / 2.f; - } else if (!strcmp(key, "FLOAT")) { /* window 'floating' in tiled WM */ - Atom atom; - - atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); - SETPROP("_NET_WM_WINDOW_TYPE", XA_ATOM, 32, (void*) &atom); - } else { - SETFMTPROP(key, "%s", value); - } - ) - - { - uid_t uid; - pid_t pid, ppid; - - uid = getuid(); - pid = getpid(); - ppid = getppid(); - - /* set basic properties */ - SETPROP("_NET_WM_UID", XA_CARDINAL, 32, (void*) &uid); - SETPROP("_NET_WM_PID", XA_CARDINAL, 32, (void*) &pid); - SETPROP("_NET_WM_PPID", XA_CARDINAL, 32, (void*) &ppid); - } - - /* update window pos and geometry */ - XMoveWindow(display, window, wx, wy); - XResizeWindow(display, window, ww, wh); -} - -/* XCreateWindow intercept */ -Window -XCreateWindow( - Display *display, - Window parent, - int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, - int depth, - unsigned int class, - Visual *visual, - unsigned long valuemask, - XSetWindowAttributes *attributes) -{ - static Window (*func)( - Display *display, - Window parent, - int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, - int depth, - unsigned int class, - Visual *visual, - unsigned long valuemask, - XSetWindowAttributes *attributes) = NULL; - int i; - - /* find the real Xlib and the real X function */ - if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); - if (!func) func = dlsym (lib_xlib, "XCreateWindow"); - - /* multihead screen handling loop */ - for (i = 0; i < ScreenCount(display); i++) { - /* if the window is created as a toplevel window */ - if (parent == RootWindow(display, i)) { - Window window; - - /* create and set properties */ - window = (*func) (display, parent, x, y, width, height, - border_width, depth, class, visual, valuemask, attributes); - set_properties(display, window); - - return window; - } - } - - /* normal child window - create without properties */ - return (*func) (display, parent, x, y, width, height, border_width, depth, - class, visual, valuemask, attributes); -} - -/* XCreateSimpleWindow intercept */ -Window -XCreateSimpleWindow( - Display *display, - Window parent, - int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, - unsigned long border, - unsigned long background) -{ - static Window (*func)( - Display *display, - Window parent, - int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, - unsigned long border, - unsigned long background) = NULL; - int i; - - /* find the real Xlib and the real X function */ - if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); - if (!func) func = dlsym (lib_xlib, "XCreateSimpleWindow"); - - /* multihead screen handling loop */ - for (i = 0; i < ScreenCount(display); i++) { - /* if the window is created as a toplevel window */ - if (parent == RootWindow(display, i)) { - Window window; - - /* create and set properties */ - window = (*func) (display, parent, x, y, width, height, - border_width, border, background); - set_properties(display, window); - return window; - } - } - - /* normal child window - create as usual */ - return (*func) (display, parent, x, y, width, height, - border_width, border, background); -} - -/* XReparentWindow intercept */ -int -XReparentWindow( - Display *display, - Window window, - Window parent, - int x, int y) -{ - static int (*func)( - Display *display, - Window window, - Window parent, - int x, int y) = NULL; - int i; - - /* find the real Xlib and the real X function */ - if (!lib_xlib) lib_xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); - if (!func) func = dlsym (lib_xlib, "XReparentWindow"); - - /* multihead screen handling loop */ - for (i = 0; i < ScreenCount(display); i++) { - /* if the window is created as a toplevel window */ - if (parent == RootWindow(display, i)) { - - /* set properties and reparent */ - set_properties(display, window); - return (*func) (display, window, parent, x, y); - } - } - - /* normal child window - reparent as usual */ - return (*func) (display, window, parent, x, y); -} -