From f6e5abeb793ae05d5fdc1fa116d22caceff6f7e8 Mon Sep 17 00:00:00 2001 From: Fedora X Ninjas Date: Thu, 12 Jun 2014 14:44:30 +1000 Subject: [PATCH] rrxinerama: hack in tiling support --- randr/rrxinerama.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 5 deletions(-) diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c index 76d728c..b3e360f 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 ver; + int id; + int h_size; + int v_size; + int h_loc; + int v_loc; +}; + +static int SplitTile(RRPropertyValuePtr tile_val, + struct tile_info *info) +{ + const char *tok = tile_val->data; + /* only version 0 */ + if (tok[0] != '0') + return -1; + + return sscanf(tok, "%d:%d:%d:%d:%d:%d", &info->ver, + &info->id, &info->h_size, &info->v_size, + &info->h_loc, &info->v_loc); +} + 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++) + 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,79 @@ 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); + ErrorF(" %d: ver is %d, id is %d, h/v: %d/%d loc: %d/%d\n", orig_id, + info.ver, info.id, info.h_size, + info.v_size, info.h_loc, info.v_loc); + + 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; + } + } + ErrorF("total for tile %d : %d x %d\n", orig_id, total_w, total_h); + + 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 +460,23 @@ 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, MakeAtom("TILE", sizeof("TILE") - 1, TRUE)); + if (tile) { + ErrorF("output %d has tiled\n", output->id); + 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) { -- 1.9.3