summaryrefslogtreecommitdiff
path: root/randr
diff options
context:
space:
mode:
authorKeith Packard <keithp@guitar.keithp.com>2006-10-03 21:06:11 -0700
committerKeith Packard <keithp@neko.keithp.com>2006-11-16 10:03:00 -0800
commit0f37ee35a8edb8de442e4de050607f041f39d7a5 (patch)
tree98cfdc509f91064b0fbeb393293f74a69e52c027 /randr
parentf7dcf3a6d482d4934ff7ba33826adf725103470b (diff)
Add mode origins and output options. Fix memmoves in resource free funcs.
Output options and mode origins both affected driver ABI. memmove mistakes were causing 'Freeing resource which isn't there' messages. Prune unused non-user defined modes from available list now.
Diffstat (limited to 'randr')
-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: