~ctwm/ctwm/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * Copyright notice...
 */

#include "ctwm.h"

#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include "r_layout.h"
#include "r_area.h"
#include "xparsegeometry.h"


/**
 * Parse an X Geometry out to get the positions and sizes.
 *
 * This generally wraps and replaces our uses of XParseGeometry in order
 * to allow positioning relative to a XRANDR output name.  This allows
 * specifying a geometry relative to a particular monitor, rather than on
 * the whole composite multi-screen output meta-display.
 */
int
RLayoutXParseGeometry(RLayout *layout, const char *geometry, int *x, int *y,
                      unsigned int *width, unsigned int *height)
{
	char *sep;

	// Got something that looks like a display?
	sep = strchr(geometry, ':');
	if(sep != NULL) {
		RArea mon = RLayoutGetAreaByName(layout, geometry, sep - geometry);
		if(RAreaIsValid(&mon)) {
			// Yep, one of our monitors; figure the placement on our
			// whole root where that part of this monitor lies.
			int mask = XParseGeometry(sep + 1, x, y, width, height);
			RArea big = RLayoutBigArea(layout);

			if(mask & XValue) {
				if(mask & XNegative) {
					*x -= big.width - mon.width - (mon.x - big.x);
				}
				else {
					*x += mon.x - big.x;
				}
			}

			if(mask & YValue) {
				if(mask & YNegative) {
					*y -= big.height - mon.height - (mon.y - big.y);
				}
				else {
					*y += mon.y - big.y;
				}
			}

			return mask;
		}

		// Name not found, keep the geometry part as-is
		geometry = sep + 1;
	}

	return XParseGeometry(geometry, x, y, width, height);
}