summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--randr/mirandr.c6
-rw-r--r--randr/randrstr.h28
-rw-r--r--randr/rrcrtc.c52
-rw-r--r--randr/rrinfo.c1
-rw-r--r--randr/rrmode.c68
-rw-r--r--randr/rroutput.c43
-rw-r--r--randr/rrscreen.c17
7 files changed, 171 insertions, 44 deletions
diff --git a/randr/mirandr.c b/randr/mirandr.c
index bcc8e0fcd..7300cfebe 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -52,7 +52,7 @@ miRRCrtcSet (ScreenPtr pScreen,
int y,
Rotation rotation,
int numOutput,
- RROutputPtr *outputs)
+ RROutputConfigPtr outputs)
{
return TRUE;
}
@@ -114,6 +114,10 @@ miRandRInit (ScreenPtr pScreen)
return FALSE;
if (!RROutputSetCrtcs (output, &crtc, 1))
return FALSE;
+ if (!RROutputSetPossibleOptions (output, 0))
+ return FALSE;
+ if (!RROutputSetCurrentOptions (output, 0))
+ return FALSE;
if (!RROutputSetConnection (output, RR_Connected))
return FALSE;
RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 0b8c61e1f..a4e55890f 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -72,12 +72,14 @@ extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr);
typedef struct _rrMode RRModeRec, *RRModePtr;
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
typedef struct _rrOutput RROutputRec, *RROutputPtr;
+typedef struct _rrOutputConfig RROutputConfigRec, *RROutputConfigPtr;
struct _rrMode {
int refcnt;
xRRModeInfo mode;
char *name;
void *devPrivate;
+ ScreenPtr screen;
};
struct _rrCrtc {
@@ -105,6 +107,8 @@ struct _rrOutput {
CARD8 connection;
CARD8 subpixelOrder;
RRCrtcPtr crtc;
+ CARD32 currentOptions;
+ CARD32 possibleOptions;
int numCrtcs;
RRCrtcPtr *crtcs;
int numClones;
@@ -116,6 +120,11 @@ struct _rrOutput {
void *devPrivate;
};
+struct _rrOutputConfig {
+ RROutputPtr output;
+ CARD32 options;
+};
+
#if RANDR_12_INTERFACE
typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
CARD16 width,
@@ -130,7 +139,7 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
int y,
Rotation rotation,
int numOutputs,
- RROutputPtr *outputs);
+ RROutputConfigPtr outputs);
typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen,
RRCrtcPtr crtc);
@@ -352,7 +361,7 @@ miRRCrtcSet (ScreenPtr pScreen,
int y,
Rotation rotation,
int numOutput,
- RROutputPtr *outputs);
+ RROutputConfigPtr outputs);
/* randr.c */
/*
@@ -440,7 +449,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
int x,
int y,
Rotation rotation,
- int numOutput,
+ int numOutputs,
RROutputPtr *outputs);
void
@@ -456,7 +465,7 @@ RRCrtcSet (RRCrtcPtr crtc,
int y,
Rotation rotation,
int numOutput,
- RROutputPtr *outputs);
+ RROutputConfigPtr outputs);
/*
* Request that the Crtc gamma be changed
@@ -530,6 +539,9 @@ RRModeGet (ScreenPtr pScreen,
xRRModeInfo *modeInfo,
const char *name);
+void
+RRModePruneUnused (ScreenPtr pScreen);
+
/*
* Destroy a mode.
*/
@@ -584,6 +596,10 @@ RROutputSetCrtcs (RROutputPtr output,
RRCrtcPtr *crtcs,
int numCrtcs);
+Bool
+RROutputSetPossibleOptions (RROutputPtr output,
+ CARD32 possibleOptions);
+
void
RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc);
@@ -595,6 +611,10 @@ Bool
RROutputSetSubpixelOrder (RROutputPtr output,
int subpixelOrder);
+Bool
+RROutputSetCurrentOptions (RROutputPtr output,
+ CARD32 currentOptions);
+
void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 77cba29fa..3108f1452 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -92,25 +92,25 @@ RRCrtcNotify (RRCrtcPtr crtc,
if (numOutputs != prevNumOutputs)
{
- RROutputPtr *outputs;
+ RROutputPtr *newoutputs;
if (numOutputs)
{
if (crtc->numOutputs)
- outputs = xrealloc (crtc->outputs,
+ newoutputs = xrealloc (crtc->outputs,
numOutputs * sizeof (RROutputPtr));
else
- outputs = xalloc (numOutputs * sizeof (RROutputPtr));
- if (!outputs)
+ newoutputs = xalloc (numOutputs * sizeof (RROutputPtr));
+ if (!newoutputs)
return FALSE;
}
else
{
if (crtc->outputs)
xfree (crtc->outputs);
- outputs = NULL;
+ newoutputs = NULL;
}
- crtc->outputs = outputs;
+ crtc->outputs = newoutputs;
crtc->numOutputs = numOutputs;
}
for (i = 0; i < numOutputs; i++)
@@ -183,7 +183,7 @@ RRCrtcSet (RRCrtcPtr crtc,
int y,
Rotation rotation,
int numOutputs,
- RROutputPtr *outputs)
+ RROutputConfigPtr outputs)
{
ScreenPtr pScreen = crtc->pScreen;
rrScrPriv(pScreen);
@@ -252,7 +252,7 @@ RRCrtcDestroyResource (pointer value, XID pid)
{
if (pScrPriv->crtcs[i] == crtc)
{
- memmove (pScrPriv->crtcs, pScrPriv->crtcs + 1,
+ memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
(pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr));
--pScrPriv->numCrtcs;
break;
@@ -458,15 +458,15 @@ ProcRRSetCrtcConfig (ClientPtr client)
RRCrtcPtr crtc;
RRModePtr mode;
int numOutputs;
- RROutputPtr *outputs = NULL;
- RROutput *outputIds;
+ RROutputConfigPtr outputs = NULL;
+ xRROutputConfig *outputConfigs;
TimeStamp configTime;
TimeStamp time;
Rotation rotation;
int i, j;
REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
- numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2);
+ numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)) >> 1;
crtc = LookupIDByType (stuff->crtc, RRCrtcType);
if (!crtc)
@@ -493,39 +493,47 @@ ProcRRSetCrtcConfig (ClientPtr client)
}
if (numOutputs)
{
- outputs = xalloc (numOutputs * sizeof (RROutputPtr));
+ outputs = xalloc (numOutputs * sizeof (RROutputConfigRec));
if (!outputs)
return BadAlloc;
}
else
outputs = NULL;
- outputIds = (RROutput *) (stuff + 1);
+ outputConfigs = (xRROutputConfig *) (stuff + 1);
for (i = 0; i < numOutputs; i++)
{
- outputs[i] = LookupIDByType (outputIds[i], RROutputType);
- if (!outputs[i])
+ outputs[i].output = LookupIDByType (outputConfigs[i].output, RROutputType);
+ if (!outputs[i].output)
{
- client->errorValue = outputIds[i];
+ client->errorValue = outputConfigs[i].output;
if (outputs)
xfree (outputs);
return RRErrorBase + BadRROutput;
}
+ outputs[i].options = outputConfigs[i].options;
+ if (outputs[i].options & ~outputs[i].output->possibleOptions)
+ {
+ client->errorValue = outputConfigs[i].options;
+ if (outputs)
+ xfree (outputs);
+ return BadMatch;
+ }
/* validate crtc for this output */
- for (j = 0; j < outputs[i]->numCrtcs; j++)
- if (outputs[i]->crtcs[j] == crtc)
+ for (j = 0; j < outputs[i].output->numCrtcs; j++)
+ if (outputs[i].output->crtcs[j] == crtc)
break;
- if (j == outputs[j]->numCrtcs)
+ if (j == outputs[j].output->numCrtcs)
{
if (outputs)
xfree (outputs);
return BadMatch;
}
/* validate mode for this output */
- for (j = 0; j < outputs[i]->numModes; j++)
- if (outputs[i]->modes[j] == mode)
+ for (j = 0; j < outputs[i].output->numModes; j++)
+ if (outputs[i].output->modes[j] == mode)
break;
- if (j == outputs[i]->numModes)
+ if (j == outputs[i].output->numModes)
{
if (outputs)
xfree (outputs);
diff --git a/randr/rrinfo.c b/randr/rrinfo.c
index 491ac218d..6fd4ee581 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -208,6 +208,7 @@ RRGetInfo (ScreenPtr pScreen)
if (pScrPriv->nSizes)
RRScanOldConfig (pScreen, rotations);
#endif
+ RRModePruneUnused (pScreen);
RRTellChanged (pScreen);
return TRUE;
}
diff --git a/randr/rrmode.c b/randr/rrmode.c
index 23ac5305c..3a6748691 100644
--- a/randr/rrmode.c
+++ b/randr/rrmode.c
@@ -24,6 +24,27 @@
RESTYPE RRModeType;
+static Bool
+RRModeEqual (xRRModeInfo *a, xRRModeInfo *b)
+{
+ if (a->width != b->width) return FALSE;
+ if (a->height != b->height) return FALSE;
+ if (a->mmWidth != b->mmWidth) return FALSE;
+ if (a->mmHeight != b->mmHeight) return FALSE;
+ if (a->dotClock != b->dotClock) return FALSE;
+ if (a->hSyncStart != b->hSyncStart) return FALSE;
+ if (a->hSyncEnd != b->hSyncEnd) return FALSE;
+ if (a->hTotal != b->hTotal) return FALSE;
+ if (a->hSkew != b->hSkew) return FALSE;
+ if (a->vSyncStart != b->vSyncStart) return FALSE;
+ if (a->vSyncEnd != b->vSyncEnd) return FALSE;
+ if (a->vTotal != b->vTotal) return FALSE;
+ if (a->nameLength != b->nameLength) return FALSE;
+ if (a->modeFlags != b->modeFlags) return FALSE;
+ if (a->origin != b->origin) return FALSE;
+ return TRUE;
+}
+
RRModePtr
RRModeGet (ScreenPtr pScreen,
xRRModeInfo *modeInfo,
@@ -37,8 +58,7 @@ RRModeGet (ScreenPtr pScreen,
for (i = 0; i < pScrPriv->numModes; i++)
{
mode = pScrPriv->modes[i];
- modeInfo->id = mode->mode.id;
- if (!memcmp (modeInfo, &mode->mode, sizeof (xRRModeInfo)) &&
+ if (RRModeEqual (&mode->mode, modeInfo) &&
!memcmp (name, mode->name, modeInfo->nameLength))
{
++mode->refcnt;
@@ -54,6 +74,7 @@ RRModeGet (ScreenPtr pScreen,
mode->name = (char *) (mode + 1);
memcpy (mode->name, name, modeInfo->nameLength);
mode->name[modeInfo->nameLength] = '\0';
+ mode->screen = pScreen;
if (pScrPriv->numModes)
modes = xrealloc (pScrPriv->modes,
@@ -80,8 +101,31 @@ RRModeGet (ScreenPtr pScreen,
void
RRModeDestroy (RRModePtr mode)
{
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ int m;
+
if (--mode->refcnt > 0)
return;
+ pScreen = mode->screen;
+ pScrPriv = rrGetScrPriv (pScreen);
+ for (m = 0; m < pScrPriv->numModes; m++)
+ {
+ if (pScrPriv->modes[m] == mode)
+ {
+ memmove (pScrPriv->modes + m, pScrPriv->modes + m + 1,
+ (pScrPriv->numModes - m - 1) * sizeof (RRModePtr));
+ pScrPriv->numModes--;
+ if (!pScrPriv->numModes)
+ {
+ xfree (pScrPriv->modes);
+ pScrPriv->modes = NULL;
+ }
+ pScrPriv->changed = TRUE;
+ break;
+ }
+ }
+
xfree (mode);
}
@@ -104,6 +148,26 @@ RRModeInit (void)
return TRUE;
}
+void
+RRModePruneUnused (ScreenPtr pScreen)
+{
+ rrScrPriv (pScreen);
+ RRModePtr *unused, mode;
+ int m;
+ int num = pScrPriv->numModes;
+
+ unused = xalloc (num * sizeof (RRModePtr));
+ if (!unused)
+ return;
+ memcpy (unused, pScrPriv->modes, num * sizeof (RRModePtr));
+ for (m = 0; m < num; m++) {
+ mode = unused[m];
+ if (mode->refcnt == 1 && mode->mode.origin != RRModeOriginUser)
+ FreeResource (mode->mode.id, 0);
+ }
+ xfree (unused);
+}
+
int
ProcRRCreateMode (ClientPtr client)
{
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 90b2b9856..b252d7dec 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -60,6 +60,8 @@ RROutputCreate (ScreenPtr pScreen,
output->connection = RR_UnknownConnection;
output->subpixelOrder = SubPixelUnknown;
output->crtc = NULL;
+ output->currentOptions = 0;
+ output->possibleOptions = 0;
output->numCrtcs = 0;
output->crtcs = NULL;
output->numClones = 0;
@@ -190,6 +192,17 @@ RROutputSetCrtcs (RROutputPtr output,
return TRUE;
}
+Bool
+RROutputSetPossibleOptions (RROutputPtr output,
+ CARD32 possibleOptions)
+{
+ if (output->possibleOptions == possibleOptions)
+ return TRUE;
+ output->possibleOptions = possibleOptions;
+ output->changed = TRUE;
+ return TRUE;
+}
+
void
RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc)
{
@@ -222,6 +235,17 @@ RROutputSetSubpixelOrder (RROutputPtr output,
return TRUE;
}
+Bool
+RROutputSetCurrentOptions (RROutputPtr output,
+ CARD32 currentOptions)
+{
+ if (output->currentOptions == currentOptions)
+ return TRUE;
+ output->currentOptions = currentOptions;
+ output->changed = TRUE;
+ return TRUE;
+}
+
void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
{
@@ -248,7 +272,7 @@ RROutputDestroyResource (pointer value, XID pid)
{
if (pScrPriv->outputs[i] == output)
{
- memmove (pScrPriv->outputs, pScrPriv->outputs + 1,
+ memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1,
(pScrPriv->numOutputs - (i - 1)) * sizeof (RROutputPtr));
--pScrPriv->numOutputs;
break;
@@ -280,6 +304,8 @@ RROutputInit (void)
return TRUE;
}
+#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
+
int
ProcRRGetOutputInfo (ClientPtr client)
{
@@ -307,24 +333,27 @@ ProcRRGetOutputInfo (ClientPtr client)
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
- rep.length = 0;
+ rep.length = OutputInfoExtra >> 2;
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
rep.crtc = output->crtc ? output->crtc->id : None;
+ rep.currentOptions = output->currentOptions;
rep.connection = output->connection;
rep.subpixelOrder = output->subpixelOrder;
rep.nCrtcs = output->numCrtcs;
rep.nModes = output->numModes;
rep.nClones = output->numClones;
rep.nameLength = output->nameLength;
+ rep.possibleOptions = output->possibleOptions;
+ rep.pad1 = 42;
- rep.length = (output->numCrtcs +
- output->numModes +
- output->numClones +
- ((rep.nameLength + 3) >> 2));
+ extraLen = ((output->numCrtcs +
+ output->numModes +
+ output->numClones +
+ ((rep.nameLength + 3) >> 2)) << 2);
- extraLen = rep.length << 2;
if (extraLen)
{
+ rep.length += extraLen >> 2;
extra = xalloc (extraLen);
if (!extra)
return BadAlloc;
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index e382540b7..7b53f0468 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -372,7 +372,7 @@ ProcRRGetScreenResources (ClientPtr client)
rep.length = (pScrPriv->numCrtcs +
pScrPriv->numOutputs +
- pScrPriv->numModes * 10 +
+ pScrPriv->numModes * (SIZEOF(xRRModeInfo) >> 2) +
((rep.nbytesNames + 3) >> 2));
extraLen = rep.length << 2;
@@ -429,7 +429,7 @@ ProcRRGetScreenResources (ClientPtr client)
pScrPriv->modes[i]->mode.nameLength);
names += pScrPriv->modes[i]->mode.nameLength;
}
- assert ((names + 3 >> 3) == rep.length);
+ assert (((((char *) names - (char *) extra) + 3) >> 2) == rep.length);
}
if (client->swapped) {
@@ -694,7 +694,7 @@ ProcRRSetScreenConfig (ClientPtr client)
Rotation rotation;
int rate;
Bool has_rate;
- RROutputPtr output;
+ RROutputConfigRec output;
RRModePtr mode;
RR10DataPtr pData = NULL;
RRScreenSizePtr pSize;
@@ -731,13 +731,14 @@ ProcRRSetScreenConfig (ClientPtr client)
if (!RRGetInfo (pScreen))
return BadAlloc;
- output = RRFirstOutput (pScreen);
- if (!output)
+ output.output = RRFirstOutput (pScreen);
+ if (!output.output)
{
time = currentTime;
rep.status = RRSetConfigFailed;
goto sendReply;
}
+ output.options = output.output->currentOptions;
/*
* if the client's config timestamp is not the same as the last config
@@ -750,7 +751,7 @@ ProcRRSetScreenConfig (ClientPtr client)
goto sendReply;
}
- pData = RR10GetData (pScreen, output);
+ pData = RR10GetData (pScreen, output.output);
if (!pData)
return BadAlloc;
@@ -786,7 +787,7 @@ ProcRRSetScreenConfig (ClientPtr client)
return BadValue;
}
- if ((~output->crtc->rotations) & rotation)
+ if ((~output.output->crtc->rotations) & rotation)
{
/*
* requested rotation or reflection not supported by screen
@@ -835,7 +836,7 @@ ProcRRSetScreenConfig (ClientPtr client)
goto sendReply;
}
- rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation,
+ rep.status = RRCrtcSet (output.output->crtc, mode, 0, 0, stuff->rotation,
1, &output);
sendReply: