git.strcat.st

/strcat/wm.git/ - summarytreelogarchivereleases

subject
add optional xinerama support
commit
9d2f4d97ce7bd51e4a6f5d75ec4e63fe025290c2
date
2026-05-01T18:24:02Z
message
	new file:   extras/xinerama.c
	new file:   extras/xinerama.h
	modified:   Makefile
	modified:   wm.c

diff
 extras/xinerama.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 extras/xinerama.h | 10 +++++++
 2 files changed, 96 insertions(+)

diff --git a/extras/xinerama.c b/extras/xinerama.c
new file mode 100644
index 0000000..ba43c9a
--- /dev/null
+++ b/extras/xinerama.c
@@ -0,0 +1,86 @@
+#include <X11/Xlib.h>
+#include <X11/extensions/Xinerama.h>
+
+#include "xinerama.h"
+
+#define max_monitors 16
+
+struct monitor {
+	int x;
+	int y;
+	int width;
+	int height;
+};
+
+static struct monitor monitors[max_monitors];
+static int monitor_count;
+
+static int
+point_in_monitor(int x, int y, int monitor)
+{
+	if (x < monitors[monitor].x || y < monitors[monitor].y)
+	    return 0;
+	if (x >= monitors[monitor].x + monitors[monitor].width)
+	    return 0;
+	if (y >= monitors[monitor].y + monitors[monitor].height)
+	    return 0;
+	return 1;
+}
+
+int
+xinerama_init(Display *display, Window root_window)
+{
+	XWindowAttributes root_attrs;
+	XineramaScreenInfo *screen_info;
+	int i, j, major, minor;
+
+	monitor_count = 1;
+	if (!XGetWindowAttributes(display, root_window, &root_attrs))
+	    return monitor_count;
+	monitors[0].x = 0;
+	monitors[0].y = 0;
+	monitors[0].width = root_attrs.width;
+	monitors[0].height = root_attrs.height;
+	if (!XineramaQueryExtension(display, &major, &minor) ||
+	    !XineramaIsActive(display))
+	    return monitor_count;
+	screen_info = XineramaQueryScreens(display, &j);
+	if (screen_info == None || j < 1)
+	    return monitor_count;
+	monitor_count = j;
+	if (monitor_count > max_monitors)
+	    monitor_count = max_monitors;
+	for (i = 0; i < monitor_count; i++) {
+	    monitors[i].x = screen_info[i].x_org;
+	    monitors[i].y = screen_info[i].y_org;
+	    monitors[i].width = screen_info[i].width;
+	    monitors[i].height = screen_info[i].height;
+	}
+	XFree(screen_info);
+	return monitor_count;
+}
+
+int
+xinerama_monitor_for_point(int x, int y)
+{
+	int i;
+
+	for (i = 0; i < monitor_count; i++)
+	    if (point_in_monitor(x, y, i))
+	        return i;
+	return 0;
+}
+
+int
+xinerama_monitor_for_window(Display *display, Window root_window, Window window)
+{
+	XWindowAttributes window_attrs;
+	int x, y;
+
+	(void)root_window;
+	if (!XGetWindowAttributes(display, window, &window_attrs))
+	    return 0;
+	x = window_attrs.x + (window_attrs.width / 2);
+	y = window_attrs.y + (window_attrs.height / 2);
+	return xinerama_monitor_for_point(x, y);
+}
diff --git a/extras/xinerama.h b/extras/xinerama.h
new file mode 100644
index 0000000..3241592
--- /dev/null
+++ b/extras/xinerama.h
@@ -0,0 +1,10 @@
+#ifndef XINERAMA_H
+#define XINERAMA_H
+
+#include <X11/Xlib.h>
+
+int xinerama_init(Display *display, Window root_window);
+int xinerama_monitor_for_point(int x, int y);
+int xinerama_monitor_for_window(Display *display, Window root_window, Window window);
+
+#endif