Not compile-tested, merely syntactically plausible, just wanted to get this out for a second look. This implements the primary output requests in the DIX, and mangles the appropriate protocol requests to sort the primary output to the front.
Patch #4 maps the primary output to the RANDR 1.0 "first" output, which is sort of vaguely defined but seems like the right thing to do. The xf86 DDX also has a "compat" output which is even more vaguely defined; I'm not yet sure what the correct thing to do with that is. Input appreciated. Updated protocol specs and client-side library are in git on the get-set-primary branches of the appropriate modules. - ajax
From 0a40d1959735ee82cdee80ac937bb2c55385af32 Mon Sep 17 00:00:00 2001
From: Adam Jackson <[EMAIL PROTECTED]>
Date: Mon, 8 Dec 2008 16:26:49 -0500
Subject: [PATCH] randr: Add [GS]etOutputPrimary
---
randr/randrstr.h | 8 ++++
randr/rrdispatch.c | 2 +
randr/rroutput.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++-
randr/rrsdispatch.c | 27 +++++++++++++
4 files changed, 143 insertions(+), 1 deletions(-)
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 0cc4ff7..b868144 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -2,6 +2,7 @@
* Copyright © 2000 Compaq Computer Corporation
* Copyright © 2002 Hewlett-Packard Company
* Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -272,6 +273,7 @@ typedef struct _rrScrPriv {
int numOutputs;
RROutputPtr *outputs;
+ RROutputPtr primaryOutput;
int numCrtcs;
RRCrtcPtr *crtcs;
@@ -811,6 +813,12 @@ RROutputDestroy (RROutputPtr output);
extern _X_EXPORT int
ProcRRGetOutputInfo (ClientPtr client);
+extern int
+ProcRRSetOutputPrimary (ClientPtr client);
+
+extern int
+ProcRRGetOutputPrimary (ClientPtr client);
+
/*
* Initialize output type
*/
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index 0cc0bca..5a2ea71 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -217,5 +217,7 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
ProcRRGetCrtcTransform, /* 27 */
ProcRRGetPanning, /* 28 */
ProcRRSetPanning, /* 29 */
+ ProcRRSetOutputPrimary, /* 30 */
+ ProcRRGetOutputPrimary, /* 31 */
};
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 1ecde31..5eedba3 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -1,5 +1,6 @@
/*
* Copyright © 2006 Keith Packard
+ * Copyright © 2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -426,7 +427,7 @@ RROutputInit (void)
}
#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
-
+
int
ProcRRGetOutputInfo (ClientPtr client)
{
@@ -533,3 +534,107 @@ ProcRRGetOutputInfo (ClientPtr client)
return client->noClientException;
}
+
+void
+RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv,
+ RROutputPtr output)
+{
+ if (pScrPriv->primaryOutput == output)
+ return;
+
+ /* clear the old primary */
+ if (pScrPriv->primaryOutput) {
+ RROutputChanged(pScrPriv->primaryOutput, 0);
+ pScrPriv->primaryOutput = NULL;
+ }
+
+ /* set the new primary */
+ if (output) {
+ pScrPriv->primaryOutput = output;
+ RROutputChanged(output, 0);
+ }
+
+ rrScrPriv->layoutChanged = TRUE;
+
+ RRTellChanged(pScreen);
+}
+
+int
+ProcRRSetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRSetOutputPrimary);
+ RROutputPtr output = NULL;
+ WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimary);
+
+ pWin = SecurityLookupIDByType(client, stuff->window, RT_WINDOW,
+ DixReadAccess);
+
+ if (!pWin) {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ if (stuff->output) {
+ output = LookupOutput(client, stuff->output, DixReadAccess);
+
+ if (!output) {
+ client->errorValue = stuff->output;
+ return RRErrorBase + BadRROutput;
+ }
+
+ if (output->crtc) {
+ client->errorValue = stuff->output;
+ return BadMatch;
+ }
+
+ if (output->pScreen != pWin->drawable.pScreen) {
+ client->errorValue = stuff->window;
+ return BadMatch;
+ }
+ }
+
+ RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
+
+ return client->noClientException;
+}
+
+int
+ProcRRGetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPrimaryReq);
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+ xRRGetOutputPrimary rep;
+ RROutputPtr primary = NULL;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimary);
+
+ pWin = SecurityLookupIDByType(client, stuff->window, RT_WINDOW,
+ DixReadAccess);
+
+ if (!pWin) {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ if (pScrPriv)
+ primary = pScrPriv->primaryOutput;
+
+ memset(&rep, 0, sizeof(rep));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.output = primary ? primary->id : None;
+
+ if (client->swapped) {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.output, n);
+ }
+
+ WriteToClient(client, sizeof(xRRGetOutputPrimary), &rep);
+
+ return client->noClientException;
+}
diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c
index 3ff9f3f..9fbf8f0 100644
--- a/randr/rrsdispatch.c
+++ b/randr/rrsdispatch.c
@@ -436,6 +436,31 @@ SProcRRSetPanning (ClientPtr client)
return (*ProcRandrVector[stuff->randrReqType]) (client);
}
+static int
+SProcRRSetOutputPrimary (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->output, n);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRGetOutputPrimary (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
@@ -472,5 +497,7 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRGetCrtcTransform, /* 27 */
SProcRRGetPanning, /* 28 */
SProcRRSetPanning, /* 29 */
+ SProcRRSetOutputPrimary, /* 30 */
+ SProcRRGetOutputPrimary, /* 31 */
};
--
1.6.0.3
From cc2e104dcbc31362fd1f289f115dcaee1ed1a296 Mon Sep 17 00:00:00 2001
From: Adam Jackson <[EMAIL PROTECTED]>
Date: Mon, 8 Dec 2008 17:28:55 -0500
Subject: [PATCH] randr: Mangle compat Xinerama reply based on primary output
---
randr/rrxinerama.c | 48 +++++++++++++++++++++++++++++++-----------------
1 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index 544666f..ad40a1e 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -260,6 +260,30 @@ ProcRRXineramaIsActive(ClientPtr client)
return client->noClientException;
}
+static void
+RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc)
+{
+ xXineramaScreenInfo scratch;
+
+ if (RRXineramaCrtcActive (crtc))
+ {
+ int width, height;
+ RRCrtcGetScanoutSize (crtc, &width, &height);
+ scratch.x_org = crtc->x;
+ scratch.y_org = crtc->y;
+ scratch.width = width;
+ scratch.height = height;
+ if(client->swapped) {
+ register int n;
+ swaps(&scratch.x_org, n);
+ swaps(&scratch.y_org, n);
+ swaps(&scratch.width, n);
+ swaps(&scratch.height, n);
+ }
+ WriteToClient(client, sz_XineramaScreenInfo, &scratch);
+ }
+}
+
int
ProcRRXineramaQueryScreens(ClientPtr client)
{
@@ -291,26 +315,16 @@ ProcRRXineramaQueryScreens(ClientPtr client)
rrScrPriv(pScreen);
xXineramaScreenInfo scratch;
int i;
+ int has_primary = (pScrPriv->primaryOutput != NULL);
+
+ if (has_primary) {
+ RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
+ }
for(i = 0; i < pScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pScrPriv->crtcs[i];
- if (RRXineramaCrtcActive (crtc))
- {
- int width, height;
- RRCrtcGetScanoutSize (crtc, &width, &height);
- scratch.x_org = crtc->x;
- scratch.y_org = crtc->y;
- scratch.width = width;
- scratch.height = height;
- if(client->swapped) {
- register int n;
- swaps(&scratch.x_org, n);
- swaps(&scratch.y_org, n);
- swaps(&scratch.width, n);
- swaps(&scratch.height, n);
- }
- WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
- }
+ if (!has_primary || (crtc != pScrPriv->primaryOutput->crtc))
+ RRXineramaWriteCrtc(client, crtc);
}
}
--
1.6.0.3
From 3a7d40a453274a10ab1c8d463ad654158e42ffbe Mon Sep 17 00:00:00 2001
From: Adam Jackson <[EMAIL PROTECTED]>
Date: Mon, 8 Dec 2008 17:37:17 -0500
Subject: [PATCH] randr: Mangle GetScreenResources sort order based on primary output
---
randr/rrscreen.c | 17 ++++++++++++++---
1 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index c8fea99..85a30a4 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -324,7 +324,7 @@ rrGetScreenResources(ClientPtr client, Bool query)
rrScrPrivPtr pScrPriv;
CARD8 *extra;
unsigned long extraLen;
- int i, n, rc;
+ int i, n, rc, has_primary;
RRCrtc *crtcs;
RROutput *outputs;
xRRModeInfo *modeinfos;
@@ -401,12 +401,23 @@ rrGetScreenResources(ClientPtr client, Bool query)
outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs);
modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs);
names = (CARD8 *) (modeinfos + num_modes);
+
+ has_primary = (pScrPriv->primaryOutput != NULL);
+ if (pScrPriv->primaryOutput)
+ {
+ crtcs[0] = pScrPriv->primaryOutput->id;
+ if (client->swapped)
+ swapl (&crtcs[0], n);
+ }
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
- crtcs[i] = pScrPriv->crtcs[i]->id;
+ if (pScrPriv->primaryOutput &&
+ pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i])
+ continue;
+ crtcs[i + has_primary] = pScrPriv->crtcs[i]->id;
if (client->swapped)
- swapl (&crtcs[i], n);
+ swapl (&crtcs[i + has_primary], n);
}
for (i = 0; i < pScrPriv->numOutputs; i++)
--
1.6.0.3
From 2c41f0329d28dda19261c4eba9057863de3c46c8 Mon Sep 17 00:00:00 2001
From: Adam Jackson <[EMAIL PROTECTED]>
Date: Mon, 8 Dec 2008 17:40:07 -0500
Subject: [PATCH] randr: use primary output for RRFirstOutput()
---
randr/randr.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/randr/randr.c b/randr/randr.c
index 230d816..2e482f0 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -438,6 +438,9 @@ RRFirstOutput (ScreenPtr pScreen)
RROutputPtr output;
int i, j;
+ if (pScrPriv->primaryOutput)
+ return pScrPriv->primaryOutput;
+
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
RRCrtcPtr crtc = pScrPriv->crtcs[i];
--
1.6.0.3
From 318223e7b43a1f034952e507553a09af26f4e268 Mon Sep 17 00:00:00 2001
From: Adam Jackson <[EMAIL PROTECTED]>
Date: Mon, 8 Dec 2008 17:42:47 -0500
Subject: [PATCH] randr: clear primaryOutput when the output is deleted
---
randr/rroutput.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 5eedba3..06761b9 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -380,6 +380,9 @@ RROutputDestroyResource (pointer value, XID pid)
{
rrScrPriv(pScreen);
int i;
+
+ if (pScrPriv->primaryOutput == output)
+ pScrPriv->primaryOutput = NULL;
for (i = 0; i < pScrPriv->numOutputs; i++)
{
--
1.6.0.3
signature.asc
Description: This is a digitally signed message part
_______________________________________________ xorg mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/xorg
