summaryrefslogtreecommitdiff
path: root/xserver/randr/rroutput.c
diff options
context:
space:
mode:
Diffstat (limited to 'xserver/randr/rroutput.c')
-rw-r--r--xserver/randr/rroutput.c183
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;