summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimur Kristóf <Timur@Timur-Amilo.(none)>2011-04-28 16:10:54 +0200
committerTimur Kristóf <Timur@Timur-Amilo.(none)>2011-04-28 16:10:54 +0200
commit12eb79fbb08f2fe4efde795e7a35c879d3367f9c (patch)
tree58989378cc1bc9cfd23177496b7afce33985b4e4
downloadXineramaBarriers-12eb79fbb08f2fe4efde795e7a35c879d3367f9c.tar.gz
XineramaBarriers-12eb79fbb08f2fe4efde795e7a35c879d3367f9c.tar.xz
XineramaBarriers-12eb79fbb08f2fe4efde795e7a35c879d3367f9c.zip
This is an X client app that creates pointer barriers based on information from the Xinerama extension.
-rw-r--r--XineramaBarriers.pro28
-rw-r--r--barriermanager.cpp195
-rw-r--r--barriermanager.h37
-rw-r--r--main.cpp45
4 files changed, 305 insertions, 0 deletions
diff --git a/XineramaBarriers.pro b/XineramaBarriers.pro
new file mode 100644
index 0000000..0ecd4cc
--- /dev/null
+++ b/XineramaBarriers.pro
@@ -0,0 +1,28 @@
+
+# XineramaBarriers
+# ----------
+# Copyright (C) 2011, Timur Kristóf
+#
+# This X client application will create pointer barriers
+# based on the Xinerama information of your current driver.
+# Only works with XFixes v5 or higher and the Xorg server
+# which has the pointer barriers patch.
+# ----------
+# Licensed under the terms of the GPL
+# ----------
+
+TEMPLATE = app
+TARGET = XineramaBarriers
+
+CONFIG += console link_pkgconfig
+CONFIG -= QT app_bundle
+PKGCONFIG += x11 xinerama xfixes
+
+SOURCES += main.cpp \
+ barriermanager.cpp
+
+INSTALLS += target
+target.path = /usr/bin
+
+HEADERS += \
+ barriermanager.h
diff --git a/barriermanager.cpp b/barriermanager.cpp
new file mode 100644
index 0000000..4bce3fc
--- /dev/null
+++ b/barriermanager.cpp
@@ -0,0 +1,195 @@
+
+// XineramaBarriers
+// ----------
+// Copyright (C) 2011, Timur Kristóf
+//
+// This X client application will create pointer barriers
+// based on the Xinerama information of your current driver.
+// Only works with XFixes v5 or higher and the Xorg server
+// which has the pointer barriers patch.
+// ----------
+// Licensed under the terms of the GPL
+// ----------
+
+#include "barriermanager.h"
+#include <iostream>
+#include <algorithm>
+
+static std::ostream &operator<<(std::ostream &os, const XineramaScreenInfo &info)
+{
+ return os << info.screen_number << " " << info.width << " " << info.height << " " << info.x_org << " " << info.y_org;
+}
+
+static std::vector<XineramaScreenInfo> fetchXineramaInfo(Display *d)
+{
+ std::vector<XineramaScreenInfo> result;
+ int a;
+ XineramaScreenInfo *info = XineramaQueryScreens(d, &a);
+ for (int i = 0; i < a; i++)
+ {
+ result.push_back(info[i]);
+ std::cout << info[i] << std::endl;
+ }
+ XFree(info);
+ return result;
+}
+
+static bool compareY(const XineramaScreenInfo &i1, const XineramaScreenInfo &i2)
+{
+ return i1.y_org < i2.y_org;
+}
+
+static bool compareX(const XineramaScreenInfo &i1, const XineramaScreenInfo &i2)
+{
+ return i1.x_org < i2.x_org;
+}
+
+BarrierManager::BarrierManager(Display *d)
+ : d(d)
+{
+ updateBarriers();
+}
+
+BarrierManager::~BarrierManager()
+{
+ destroyBarriers();
+}
+
+void BarrierManager::destroyBarriers()
+{
+ for (std::vector<PointerBarrier>::iterator i = barriers.begin(); i != barriers.end(); i++)
+ XFixesDestroyPointerBarrier(d, *i);
+ barriers.clear();
+}
+
+void BarrierManager::updateBarriers()
+{
+ destroyBarriers();
+ XGetWindowAttributes(d, DefaultRootWindow(d), &attrs);
+ infos = fetchXineramaInfo(d);
+
+ std::cout << "updating barriers" << std::endl;
+
+ for (std::vector<XineramaScreenInfo>::iterator i = infos.begin(); i != infos.end(); i++)
+ {
+ if (i->x_org)
+ {
+ // Checking left neighbours
+ std::vector<XineramaScreenInfo> leftNeighbours;
+ for (std::vector<XineramaScreenInfo>::iterator j = infos.begin(); j != infos.end(); j++)
+ if (j->x_org + j->width == i->x_org)
+ leftNeighbours.push_back(*j);
+
+ std::sort(leftNeighbours.begin(), leftNeighbours.end(), compareY);
+ int startY = i->y_org;
+ int x = i->x_org;
+
+ // Adding barriers to the edge to the area where there are no neighbours
+ for (std::vector<XineramaScreenInfo>::iterator j = leftNeighbours.begin(); j != leftNeighbours.end(); j++)
+ {
+ if (j->y_org > startY)
+ {
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), x, startY, x, j->y_org, BarrierPositiveX, 0, 0));
+ std::cout << "left barrier created: x=" << x << " startY=" << startY << " y=" << j->y_org + j->height << std::endl;
+ }
+ startY = MIN(j->y_org + j->height, i->y_org + i->height);
+ }
+ if (startY < i->y_org + i->height)
+ {
+ // Adding a barrier to the remaining area where there are no more neighbours
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), x, startY, x, i->y_org + i->height, BarrierPositiveX, 0, 0));
+ std::cout << "left barrier created: x=" << x << " startY=" << startY << " y=" << i->y_org + i->height << std::endl;
+ }
+ }
+
+ if (i->x_org + i->width != attrs.width)
+ {
+ // checking right neighbours
+ std::vector<XineramaScreenInfo> rightNeighbours;
+ for (std::vector<XineramaScreenInfo>::iterator j = infos.begin(); j != infos.end(); j++)
+ if (i->x_org + i->width == j->x_org)
+ rightNeighbours.push_back(*j);
+
+ std::sort(rightNeighbours.begin(), rightNeighbours.end(), compareY);
+ int startY = i->y_org;
+ int x = i->x_org + i->width;
+
+ // Adding barriers to the edge to the area where there are no neighbours
+ for (std::vector<XineramaScreenInfo>::iterator j = rightNeighbours.begin(); j != rightNeighbours.end(); j++)
+ {
+ if (j->y_org > startY)
+ {
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), x, startY, x, j->y_org, BarrierNegativeX, 0, 0));
+ std::cout << "right barrier created: x=" << x << " startY=" << startY << " y=" << j->y_org << std::endl;
+ }
+ startY = MIN(j->y_org + j->height, i->y_org + i->height);
+ }
+ if (startY < i->y_org + i->height)
+ {
+ // Adding a barrier to the remaining area where there are no more neighbours
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), x, startY, x, i->y_org + i->height, BarrierNegativeX, 0, 0));
+ std::cout << "right barrier created: x=" << x << " startY=" << startY << " y=" << i->y_org + i->height << std::endl;
+ }
+ }
+
+ if (i->y_org)
+ {
+ // checking top neighbours
+ std::vector<XineramaScreenInfo> topNeighbours;
+ for (std::vector<XineramaScreenInfo>::iterator j = infos.begin(); j != infos.end(); j++)
+ if (j->y_org + j->height == i->y_org)
+ topNeighbours.push_back(*j);
+
+ std::sort(topNeighbours.begin(), topNeighbours.end(), compareX);
+ int startX = i->x_org;
+ int y = i->y_org;
+
+ // Adding barriers to the edge to the area where there are no neighbours
+ for (std::vector<XineramaScreenInfo>::iterator j = topNeighbours.begin(); j != topNeighbours.end(); j++)
+ {
+ if (j->x_org > startX)
+ {
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), startX, y, j->x_org, y, BarrierPositiveY, 0, 0));
+ std::cout << "top barrier created: y=" << y << " startX=" << startX << " X=" << j->x_org << std::endl;
+ }
+ startX = MIN(j->x_org + j->width, i->x_org + i->width);
+ }
+ if (startX < i->x_org + i->width)
+ {
+ // Adding a barrier to the remaining area where there are no more neighbours
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), startX, y, i->x_org + i->width, y, BarrierPositiveY, 0, 0));
+ std::cout << "top barrier created: y=" << y << " startX=" << startX << " X=" << i->x_org + i->width << std::endl;
+ }
+ }
+
+ if (i->y_org + i->height != attrs.height)
+ {
+ // checking bottom neighbours
+ std::vector<XineramaScreenInfo> bottomNeighbours;
+ for (std::vector<XineramaScreenInfo>::iterator j = infos.begin(); j != infos.end(); j++)
+ if (i->y_org + i->height == j->y_org)
+ bottomNeighbours.push_back(*j);
+
+ std::sort(bottomNeighbours.begin(), bottomNeighbours.end(), compareX);
+ int startX = i->x_org;
+ int y = i->y_org + i->height;
+
+ // Adding barriers to the edge to the area where there are no neighbours
+ for (std::vector<XineramaScreenInfo>::iterator j = bottomNeighbours.begin(); j != bottomNeighbours.end(); j++)
+ {
+ if (j->x_org > startX)
+ {
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), startX, y, j->x_org, y, BarrierNegativeY, 0, 0));
+ std::cout << "bottom barrier created: y=" << y << " startX=" << startX << " X=" << j->x_org << std::endl;
+ }
+ startX = MIN(j->x_org + j->width, i->x_org + i->width);
+ }
+ if (startX < i->x_org + i->width)
+ {
+ // Adding a barrier to the remaining area where there are no more neighbours
+ barriers.push_back(XFixesCreatePointerBarrier(d, DefaultRootWindow(d), startX, y, i->x_org + i->width, y, BarrierNegativeY, 0, 0));
+ std::cout << "bottom barrier created: y=" << y << " startX=" << startX << " X=" << i->x_org + i->width << std::endl;
+ }
+ }
+ }
+}
diff --git a/barriermanager.h b/barriermanager.h
new file mode 100644
index 0000000..b5b4186
--- /dev/null
+++ b/barriermanager.h
@@ -0,0 +1,37 @@
+
+// XineramaBarriers
+// ----------
+// Copyright (C) 2011, Timur Kristóf
+//
+// This X client application will create pointer barriers
+// based on the Xinerama information of your current driver.
+// Only works with XFixes v5 or higher and the Xorg server
+// which has the pointer barriers patch.
+// ----------
+// Licensed under the terms of the GPL
+// ----------
+
+#ifndef BARRIERMANAGER_H
+#define BARRIERMANAGER_H
+
+#include <X11/extensions/Xinerama.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/xfixesproto.h>
+#include <vector>
+
+#define MIN(a, b) (((a) < (b)) ? a : b)
+
+class BarrierManager {
+ std::vector<PointerBarrier> barriers;
+ std::vector<XineramaScreenInfo> infos;
+ XWindowAttributes attrs;
+ Display *d;
+
+public:
+ explicit BarrierManager(Display *d);
+ ~BarrierManager();
+ void updateBarriers();
+ void destroyBarriers();
+};
+
+#endif // BARRIERMANAGER_H
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..fa278ea
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,45 @@
+
+// XineramaBarriers
+// ----------
+// Copyright (C) 2011, Timur Kristóf
+//
+// This X client application will create pointer barriers
+// based on the Xinerama information of your current driver.
+// Only works with XFixes v5 or higher and the Xorg server
+// which has the pointer barriers patch.
+// ----------
+// Licensed under the terms of the GPL
+// ----------
+
+#include "barriermanager.h"
+#include <iostream>
+
+int main()
+{
+ std::cout << "good morning!" << std::endl;
+ Display *d = XOpenDisplay(0);
+
+ if (!XineramaIsActive(d))
+ {
+ std::cout << "Xinerama is not active, bye!" << std::endl;
+ return -1;
+ }
+
+ BarrierManager m(d);
+ XSelectInput(d, DefaultRootWindow(d), StructureNotifyMask);
+ XEvent ev;
+
+ while (XNextEvent(d, &ev))
+ {
+ switch (ev.type)
+ {
+ case ConfigureNotify:
+ std::cout << "configure event" << std::endl;
+ m.updateBarriers();
+ break;
+ }
+ }
+
+ XCloseDisplay(d);
+ return 0;
+}