[PATCH 2/2] rrxinerama: report tiled monitors in one rectangle
Dave Airlie
airlied at gmail.com
Mon Nov 24 19:00:52 PST 2014
From: Fedora X Ninjas <x at fedoraproject.org>
This changes the xinerama reporting for tiled monitors
so that the large rectangle is reported as a single
xinerama rectangle.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
randr/rrxinerama.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 118 insertions(+), 4 deletions(-)
diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index 26894a6..4a71678 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -153,18 +153,61 @@ RRXineramaCrtcActive(RRCrtcPtr crtc)
return crtc->mode != NULL && crtc->numOutputs > 0;
}
+static Atom GetTileAtom(void)
+{
+ return MakeAtom("TILE", sizeof("TILE") - 1, TRUE);
+}
+
+struct tile_info {
+ int id;
+ int flags;
+ int h_tiles;
+ int v_tiles;
+ int h_loc;
+ int v_loc;
+ int h_tile_size;
+ int v_tile_size;
+};
+
+static int SplitTile(RRPropertyValuePtr tile_val,
+ struct tile_info *info)
+{
+ const char *tok = tile_val->data;
+
+ return sscanf(tok, "%d:%d:%d:%d:%d:%d:%d:%d",
+ &info->id, &info->flags,
+ &info->h_tiles, &info->v_tiles,
+ &info->h_loc, &info->v_loc,
+ &info->h_tile_size, &info->v_tile_size);
+}
+
static int
RRXineramaScreenCount(ScreenPtr pScreen)
{
- int i, n;
+ int i, n, o;
ScreenPtr slave;
-
+ RRPropertyPtr tile;
+ struct tile_info info;
n = 0;
if (rrGetScrPriv(pScreen)) {
rrScrPriv(pScreen);
for (i = 0; i < pScrPriv->numCrtcs; i++)
if (RRXineramaCrtcActive(pScrPriv->crtcs[i]))
n++;
+
+ /* remove tiles */
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ for (o = 0; o < pScrPriv->crtcs[i]->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->crtcs[i]->outputs[o];
+ tile = RRQueryOutputProperty(output, GetTileAtom());
+ if (!tile)
+ continue;
+
+ SplitTile(&tile->current, &info);
+ if (info.h_loc || info.v_loc)
+ n--;
+ }
+ }
}
xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
@@ -312,13 +355,74 @@ RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc)
}
}
+static void
+RRXineramaWriteTile(ClientPtr client, ScreenPtr pScreen, RRPropertyPtr orig)
+{
+ rrScrPriv(pScreen);
+ RRPropertyPtr tile;
+ xXineramaScreenInfo scratch;
+ int o;
+ int total_w = 0, total_h = 0;
+ int orig_id;
+ int width, height;
+ int x_org = 0, y_org = 0;
+ struct tile_info info;
+ int ret;
+
+ ret = SplitTile(&orig->current, &info);
+ if (ret < 0)
+ return;
+
+ if (info.h_loc > 0 || info.v_loc > 0)
+ return;
+
+ orig_id = info.id;
+ for (o = 0; o < pScrPriv->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->outputs[o];
+
+ if (!output->crtc)
+ continue;
+ tile = RRQueryOutputProperty(output, GetTileAtom());
+
+ if (!tile)
+ continue;
+
+ ret = SplitTile(&tile->current, &info);
+ if (orig_id == info.id) {
+ RRCrtcGetScanoutSize(output->crtc, &width, &height);
+ if (info.h_loc == 0 && info.v_loc == 0) {
+ x_org = output->crtc->x;
+ y_org = output->crtc->y;
+ }
+ if (info.h_loc == 0)
+ total_h += height;
+ if (info.v_loc == 0)
+ total_w += width;
+ }
+ }
+
+ scratch.x_org = x_org;
+ scratch.y_org = y_org;
+ scratch.width = total_w;
+ scratch.height = total_h;
+
+ if (client->swapped) {
+ swaps(&scratch.x_org);
+ swaps(&scratch.y_org);
+ swaps(&scratch.width);
+ swaps(&scratch.height);
+ }
+ WriteToClient(client, sz_XineramaScreenInfo, &scratch);
+}
+
int
ProcRRXineramaQueryScreens(ClientPtr client)
{
xXineramaQueryScreensReply rep;
ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
int n = 0;
- int i;
+ int i, o;
+ RRPropertyPtr tile;
REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
@@ -351,12 +455,22 @@ ProcRRXineramaQueryScreens(ClientPtr client)
}
for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ Bool skip = FALSE;
if (has_primary &&
pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) {
has_primary = 0;
continue;
}
- RRXineramaWriteCrtc(client, pScrPriv->crtcs[i]);
+ for (o = 0; o < pScrPriv->crtcs[i]->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->crtcs[i]->outputs[o];
+ tile = RRQueryOutputProperty(output, GetTileAtom());
+ if (tile) {
+ RRXineramaWriteTile(client, pScreen, tile);
+ skip = TRUE;
+ }
+ }
+ if (!skip)
+ RRXineramaWriteCrtc(client, pScrPriv->crtcs[i]);
}
xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
--
2.1.0
More information about the xorg-devel
mailing list