[PATCH 2/4] Added wGetHeadRelativeToCurrentHead function

Roman Dobosz <[email protected]>
Newsgroups gmane.compw.window-managers.windowmaker.devel
Message-ID <[email protected]>
From: gryf <[email protected]>

A new function for obtaining possible heads (displays) was added. It
allow to query for a head in four directions relative to the current
one.
---
 src/xinerama.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/xinerama.h |  9 ++++++++
 2 files changed, 79 insertions(+)

diff --git a/src/xinerama.c b/src/xinerama.c
index 3d26139..483046c 100644
--- a/src/xinerama.c
+++ b/src/xinerama.c
@@ -18,6 +18,8 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <stdlib.h>
+
 #include "wconfig.h"
 
 #include "xinerama.h"
@@ -236,6 +238,74 @@ int wGetHeadForWindow(WWindow * wwin)
 	return wGetHeadForRect(wwin->screen_ptr, rect);
 }
 
+/* Find head on left, right, up or down direction relative to current
+head. If there is no screen available on pointed direction, -1 will be
+returned.*/
+int wGetHeadRelativeToCurrentHead(WScreen *scr, int current_head, int direction)
+{
+	short int found = 0;
+	int i;
+	int distance = 0;
+	int smallest_distance = 0;
+	int nearest_head = scr->xine_info.primary_head;
+	WMRect crect = wGetRectForHead(scr, current_head);
+
+	for (i = 0; i < scr->xine_info.count; i++) {
+		if (i == current_head)
+			continue;
+
+		WMRect *rect = &scr->xine_info.screens[i];
+
+		/* calculate distance from the next screen to current one */
+		switch (direction) {
+			case DIRECTION_LEFT:
+				if (rect->pos.x < crect.pos.x) {
+					found = 1;
+					distance = abs((rect->pos.x + rect->size.width)
+							- crect.pos.x) + abs(rect->pos.y + crect.pos.y);
+				}
+				break;
+			case DIRECTION_RIGHT:
+				if (rect->pos.x > crect.pos.x) {
+					found = 1;
+					distance = abs((crect.pos.x + crect.size.width)
+							- rect->pos.x) + abs(rect->pos.y + crect.pos.y);
+				}
+				break;
+			case DIRECTION_UP:
+				if (rect->pos.y < crect.pos.y) {
+					found = 1;
+					distance = abs((rect->pos.y + rect->size.height)
+							- crect.pos.y) + abs(rect->pos.x + crect.pos.x);
+				}
+				break;
+			case DIRECTION_DOWN:
+				if (rect->pos.y > crect.pos.y) {
+					found = 1;
+					distance = abs((crect.pos.y + crect.size.height)
+							- rect->pos.y) + abs(rect->pos.x + crect.pos.x);
+				}
+				break;
+		}
+
+		if (found && distance == 0)
+			return i;
+
+		if (smallest_distance == 0)
+			smallest_distance = distance;
+
+		if (abs(distance) <= smallest_distance) {
+			smallest_distance = distance;
+			nearest_head = i;
+		}
+	}
+
+	if (found && smallest_distance != 0 && nearest_head != current_head)
+		return nearest_head;
+
+	return -1;
+}
+
 int wGetHeadForPoint(WScreen * scr, WMPoint point)
 {
 	int i;
diff --git a/src/xinerama.h b/src/xinerama.h
index fd1d469..2910325 100644
--- a/src/xinerama.h
+++ b/src/xinerama.h
@@ -35,12 +35,21 @@ void wInitXinerama(WScreen *scr);
 #define XFLAG_MULTIPLE	0x02
 #define XFLAG_PARTIAL	0x04
 
+enum {
+	DIRECTION_LEFT,
+	DIRECTION_RIGHT,
+	DIRECTION_UP,
+	DIRECTION_DOWN
+};
+
 int wGetRectPlacementInfo(WScreen *scr, WMRect rect, int *flags);
 
 int wGetHeadForRect(WScreen *scr, WMRect rect);
 
 int wGetHeadForWindow(WWindow *wwin);
 
+int wGetHeadRelativeToCurrentHead(WScreen *scr, int current_head, int direction);
+
 int wGetHeadForPoint(WScreen *scr, WMPoint point);
 
 int wGetHeadForPointerLocation(WScreen *scr);
-- 
2.10.2


-- 
To unsubscribe, send mail to [email protected].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.