diff options
Diffstat (limited to 'xserver/randr/rroutput.c')
-rw-r--r-- | xserver/randr/rroutput.c | 183 |
1 files changed, 126 insertions, 57 deletions
diff --git a/xserver/randr/rroutput.c b/xserver/randr/rroutput.c index 647f19a52..e52ad7671 100644 --- a/xserver/randr/rroutput.c +++ b/xserver/randr/rroutput.c @@ -22,6 +22,7 @@ */ #include "randrstr.h" +#include <X11/Xatom.h> RESTYPE RROutputType; @@ -65,19 +66,17 @@ RROutputCreate(ScreenPtr pScreen, RROutputPtr output; RROutputPtr *outputs; rrScrPrivPtr pScrPriv; + Atom nonDesktopAtom; if (!RRInit()) return NULL; pScrPriv = rrGetScrPriv(pScreen); - if (pScrPriv->numOutputs) - outputs = reallocarray(pScrPriv->outputs, - pScrPriv->numOutputs + 1, sizeof(RROutputPtr)); - else - outputs = malloc(sizeof(RROutputPtr)); + outputs = reallocarray(pScrPriv->outputs, + pScrPriv->numOutputs + 1, sizeof(RROutputPtr)); if (!outputs) - return FALSE; + return NULL; pScrPriv->outputs = outputs; @@ -107,6 +106,7 @@ RROutputCreate(ScreenPtr pScreen, output->properties = NULL; output->pendingProperties = FALSE; output->changed = FALSE; + output->nonDesktop = FALSE; output->devPrivate = devPrivate; if (!AddResource(output->id, RROutputType, (void *) output)) @@ -114,6 +114,13 @@ RROutputCreate(ScreenPtr pScreen, pScrPriv->outputs[pScrPriv->numOutputs++] = output; + nonDesktopAtom = MakeAtom(RR_PROPERTY_NON_DESKTOP, strlen(RR_PROPERTY_NON_DESKTOP), TRUE); + if (nonDesktopAtom != BAD_RESOURCE) { + static const INT32 values[2] = { 0, 1 }; + (void) RRConfigureOutputProperty(output, nonDesktopAtom, FALSE, FALSE, FALSE, + 2, values); + } + RROutputSetNonDesktop(output, FALSE); RRResourcesChanged(pScreen); return output; @@ -314,6 +321,20 @@ RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight) return TRUE; } +Bool +RROutputSetNonDesktop(RROutputPtr output, Bool nonDesktop) +{ + const char *nonDesktopStr = RR_PROPERTY_NON_DESKTOP; + Atom nonDesktopProp = MakeAtom(nonDesktopStr, strlen(nonDesktopStr), TRUE); + uint32_t value = nonDesktop ? 1 : 0; + + if (nonDesktopProp == None || nonDesktopProp == BAD_RESOURCE) + return FALSE; + + return RRChangeOutputProperty(output, nonDesktopProp, XA_INTEGER, 32, + PropModeReplace, 1, &value, TRUE, FALSE) == Success; +} + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { @@ -333,7 +354,7 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) .crtc = crtc ? crtc->id : None, .mode = mode ? mode->mode.id : None, .rotation = crtc ? crtc->rotation : RR_Rotate_0, - .connection = output->connection, + .connection = output->nonDesktop ? RR_Disconnected : output->connection, .subpixelOrder = output->subpixelOrder }; WriteEventsToClient(client, 1, (xEvent *) &oe); @@ -358,6 +379,17 @@ RROutputDestroyResource(void *value, XID pid) if (pScreen) { rrScrPriv(pScreen); int i; + RRLeasePtr lease, next; + + xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) { + int o; + for (o = 0; o < lease->numOutputs; o++) { + if (lease->outputs[o] == output) { + RRTerminateLease(lease); + break; + } + } + } if (pScrPriv->primaryOutput == output) pScrPriv->primaryOutput = NULL; @@ -429,65 +461,99 @@ ProcRRGetOutputInfo(ClientPtr client) RROutput *clones; char *name; int i; + Bool leased; REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); + leased = RROutputIsLeased(output); + pScreen = output->pScreen; pScrPriv = rrGetScrPriv(pScreen); - rep = (xRRGetOutputInfoReply) { - .type = X_Reply, - .status = RRSetConfigSuccess, - .sequenceNumber = client->sequence, - .length = bytes_to_int32(OutputInfoExtra), - .timestamp = pScrPriv->lastSetTime.milliseconds, - .crtc = output->crtc ? output->crtc->id : None, - .mmWidth = output->mmWidth, - .mmHeight = output->mmHeight, - .connection = output->connection, - .subpixelOrder = output->subpixelOrder, - .nCrtcs = output->numCrtcs, - .nModes = output->numModes + output->numUserModes, - .nPreferred = output->numPreferred, - .nClones = output->numClones, - .nameLength = output->nameLength - }; - extraLen = ((output->numCrtcs + - output->numModes + output->numUserModes + - output->numClones + bytes_to_int32(rep.nameLength)) << 2); - - if (extraLen) { - rep.length += bytes_to_int32(extraLen); - extra = calloc(1, extraLen); - if (!extra) - return BadAlloc; - } - else - extra = NULL; + if (leased) { + rep = (xRRGetOutputInfoReply) { + .type = X_Reply, + .status = RRSetConfigSuccess, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(OutputInfoExtra), + .timestamp = pScrPriv->lastSetTime.milliseconds, + .crtc = None, + .mmWidth = 0, + .mmHeight = 0, + .connection = RR_Disconnected, + .subpixelOrder = SubPixelUnknown, + .nCrtcs = 0, + .nModes = 0, + .nPreferred = 0, + .nClones = 0, + .nameLength = output->nameLength + }; + extraLen = bytes_to_int32(rep.nameLength) << 2; + if (extraLen) { + rep.length += bytes_to_int32(extraLen); + extra = calloc(1, extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; + + name = (char *) extra; + } else { + rep = (xRRGetOutputInfoReply) { + .type = X_Reply, + .status = RRSetConfigSuccess, + .sequenceNumber = client->sequence, + .length = bytes_to_int32(OutputInfoExtra), + .timestamp = pScrPriv->lastSetTime.milliseconds, + .crtc = output->crtc ? output->crtc->id : None, + .mmWidth = output->mmWidth, + .mmHeight = output->mmHeight, + .connection = output->nonDesktop ? RR_Disconnected : output->connection, + .subpixelOrder = output->subpixelOrder, + .nCrtcs = output->numCrtcs, + .nModes = output->numModes + output->numUserModes, + .nPreferred = output->numPreferred, + .nClones = output->numClones, + .nameLength = output->nameLength + }; + extraLen = ((output->numCrtcs + + output->numModes + output->numUserModes + + output->numClones + bytes_to_int32(rep.nameLength)) << 2); + + if (extraLen) { + rep.length += bytes_to_int32(extraLen); + extra = calloc(1, extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; - crtcs = (RRCrtc *) extra; - modes = (RRMode *) (crtcs + output->numCrtcs); - clones = (RROutput *) (modes + output->numModes + output->numUserModes); - name = (char *) (clones + output->numClones); + crtcs = (RRCrtc *) extra; + modes = (RRMode *) (crtcs + output->numCrtcs); + clones = (RROutput *) (modes + output->numModes + output->numUserModes); + name = (char *) (clones + output->numClones); - for (i = 0; i < output->numCrtcs; i++) { - crtcs[i] = output->crtcs[i]->id; - if (client->swapped) - swapl(&crtcs[i]); - } - for (i = 0; i < output->numModes + output->numUserModes; i++) { - if (i < output->numModes) - modes[i] = output->modes[i]->mode.id; - else - modes[i] = output->userModes[i - output->numModes]->mode.id; - if (client->swapped) - swapl(&modes[i]); - } - for (i = 0; i < output->numClones; i++) { - clones[i] = output->clones[i]->id; - if (client->swapped) - swapl(&clones[i]); + for (i = 0; i < output->numCrtcs; i++) { + crtcs[i] = output->crtcs[i]->id; + if (client->swapped) + swapl(&crtcs[i]); + } + for (i = 0; i < output->numModes + output->numUserModes; i++) { + if (i < output->numModes) + modes[i] = output->modes[i]->mode.id; + else + modes[i] = output->userModes[i - output->numModes]->mode.id; + if (client->swapped) + swapl(&modes[i]); + } + for (i = 0; i < output->numClones; i++) { + clones[i] = output->clones[i]->id; + if (client->swapped) + swapl(&clones[i]); + } } memcpy(name, output->name, output->nameLength); if (client->swapped) { @@ -554,6 +620,9 @@ ProcRRSetOutputPrimary(ClientPtr client) if (stuff->output) { VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); + if (RROutputIsLeased(output)) + return BadAccess; + if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) { client->errorValue = stuff->window; return BadMatch; |