use Xrandr to store monitor info; next we must use this info to place windows
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmIbslkACgkQO3+8IhRO Y5iXmhAAh3PLksGK7FH0LIfvbXRt/FROsU37IkSedm+nToF3hCSchjs4dAkuT8eO tyGf9//KIVdc7ZQLg3S4tW8F7x492JLfWVZwTvJdJla301rrcxQqJ3fy/biMxmZS mEr4DPDIWHG19GgENYu6tCM4BQpRFgD2IG7mJA6AXqnWIGoQz8ASNmR/GAl0ALc5 SMFulhlUUu0fvby11L2IeRaKn88UYlHz35LewWgTDj28Hftoc/hsKq53tBVXfMEd OkYearDZQG+wcs7y/XIHwuPGL28DQzv7LJRYzho2iXQSjo2gVEUs/lwiCEyAkh2W DAkGk8MaYHERXIA7nk1lOYXOnPPxhuwGEP6CyHMB84l7r3IssfyngscsLGEK4Xim Noi8BSB1CoGIRqyQxaabgPTNWvZWK9jGG/lgYY0I97wiHZvS/7lZCqM+SaS5VGWm 0gnrQu34YOs1gyu7nllvQmsHdFDepv6gtLfntkQ0aETnWHcFs9Ipi8vBbRV8mVor cveXUKps3MH9tLXkUDUsNN2CimU5wKw/Cx7zc4Qfe0AudNkqZYc72cT3H6l/QKLm M2XGhvmcVDY5MR/PSb5UwH4oKPa1zFJfyakZNMeVVmhXbDmxUTCQGcqeb0Xq4nna zxubeQtAeRygmYDr2z4P/nYYMjrNdqjgSh+HEMBzmsF1Y5vGOus= =F/Os -----END PGP SIGNATURE-----
M
dat.h
→
dat.h
@@ -1,5 +1,7 @@
/* Copyright (c) 1994-1996 David Hogan, see README for licence details */ - +#ifndef MAX_MONITORS +#define MAX_MONITORS 8 +#endif #ifndef BORDER #define BORDER _border #endif@@ -196,3 +198,8 @@
/* key.c and event.c share this */ extern int kbLaunch; + +/* multimonitor biz */ + +extern int nmonitors; +extern XRRMonitorInfo* monitorinfo;
M
event.c
→
event.c
@@ -12,6 +12,7 @@ #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/extensions/shape.h> +#include <X11/extensions/Xrandr.h> #include "config.h" #include "dat.h" #include "fns.h"@@ -19,6 +20,7 @@ #include "patchlevel.h"
void mainloop(int shape_event) { XEvent ev; + int i; for (;;) { getevent(&ev);@@ -36,6 +38,22 @@ shapenotify((XShapeEvent*)&ev);
else #endif fprintf(stderr, "ryudo: unknown ev.type %d\n", ev.type); + break; + /* XRANDR related events; idk what the define for this is */ + case 89: + if (XRRUpdateConfiguration(&ev)) { + fetchmonitorinfo(); + fprintf(stderr, "%d monitors:\n", nmonitors); + for (i = 0; i < nmonitors; i++) { + fprintf( + stderr, + " %d,%d,%d,%d\n", + monitorinfo[i].x, + monitorinfo[i].y, + monitorinfo[i].width, + monitorinfo[i].height); + } + } break; case KeyPress: keypress(&ev.xkey);
M
main.c
→
main.c
@@ -12,6 +12,7 @@ #include <X11/Xatom.h>
#ifdef SHAPE #include <X11/extensions/shape.h> #endif +#include <X11/extensions/Xrandr.h> #include "config.h" #ifdef VIRTNOTIFY #include <libnotify/notify.h>@@ -392,6 +393,9 @@ CopyFromParent,
s->vis, CWBackPixel | CWBorderPixel | CWColormap, &attrs); + + XRRSelectInput(dpy, DefaultRootWindow(dpy), RRScreenChangeNotifyMask); + fetchmonitorinfo(); } ScreenInfo* getscreen(Window w) {
M
mkfile
→
mkfile
@@ -12,6 +12,7 @@ key.$O\
main.$O\ manage.$O\ menu.$O\ + monitor.$O\ HFILES=dat.h fns.h@@ -22,7 +23,7 @@ # Darwin complains about the nonexistant directory
# Bug in mk? "$L64 -lXext" gobbles the space, so # add trailing slash. L64=`[ -d $X11/lib64 ] && echo 64; echo` -LDFLAGS=-L$X11/lib$L64/ -Llibnotify/ -lnotify -lXext -lX11 $LDFLAGS +LDFLAGS=-L$X11/lib$L64/ -Llibnotify/ -lnotify -lXext -lX11 -lXrandr $LDFLAGS <|sh mkriorules.sh
A
monitor.c
@@ -0,0 +1,56 @@
+#include <stdio.h> +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xrandr.h> +#include "dat.h" +#include "fns.h" + +int nmonitors = 0; +XRRMonitorInfo* monitorinfo; + +void fetchmonitorinfo() { + if (monitorinfo) + XRRFreeMonitors(monitorinfo); + + monitorinfo = XRRGetMonitors(dpy, DefaultRootWindow(dpy), 1, &nmonitors); +} + +int getmonitorbyclient(Client* c) { + XRRMonitorInfo m; + int cx, cy, i, p; + cx = c->x + c->dx / 2; + cy = c->y + c->dy / 2; + + p = 0; + + for (i = 0; i < nmonitors; i++) { + m = monitorinfo[i]; + if (cx >= m.x && cx < m.x + m.width && cy >= m.y && cy < m.y + m.height) { + return i; + } + + if (m.primary) { + p = i; + } + } + + /* if center is not within any window, return primary */ + return p; +} + +int getmonitorbymouse() { + Window w; + int x, y, i; + unsigned int mask; + XRRMonitorInfo m; + + XQueryPointer(dpy, DefaultRootWindow(dpy), &w, &w, &x, &y, &x, &y, &mask); + for (i = 0; i < nmonitors; i++) { + m = monitorinfo[i]; + if (x >= m.x && x < m.x + m.width && y >= m.y && y < m.y + m.height) { + return i; + } + } + /* should never reach here, but return first monitor if we do */ + return 0; +}