From 014a315f3a41b04028b3c1c3a8f612f73516dd8b Mon Sep 17 00:00:00 2001 From: gryf Date: Tue, 7 Feb 2017 21:05:15 +0100 Subject: [PATCH] Added wGetHeadRelativeToCurrentHead function 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 3d261396..483046c7 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -18,6 +18,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include + #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 fd1d4692..29103258 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.11.4.GIT