summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@neko.keithp.com>2006-10-05 22:31:35 -0700
committerKeith Packard <keithp@neko.keithp.com>2006-10-05 22:31:35 -0700
commit1178796a4dff5ebf0bd9fb3cacb35be9709b41e5 (patch)
tree16ffa4bec4b696326b44929a32c7fe3ea6e8f16e
parentb4659faf9b455b44ac8e691cc7a8fc00a967c80b (diff)
Add preferred modes for each output. Round vrefresh. Deliver crtc events.
-rw-r--r--randr/mirandr.c2
-rw-r--r--randr/randr.c5
-rw-r--r--randr/randrstr.h10
-rw-r--r--randr/rrcrtc.c144
-rw-r--r--randr/rrmode.c4
-rw-r--r--randr/rroutput.c9
6 files changed, 117 insertions, 57 deletions
diff --git a/randr/mirandr.c b/randr/mirandr.c
index 7300cfebe..918e55da4 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -110,7 +110,7 @@ miRandRInit (ScreenPtr pScreen)
return FALSE;
if (!RROutputSetClones (output, NULL, 0))
return FALSE;
- if (!RROutputSetModes (output, &mode, 1))
+ if (!RROutputSetModes (output, &mode, 1, 0))
return FALSE;
if (!RROutputSetCrtcs (output, &crtc, 1))
return FALSE;
diff --git a/randr/randr.c b/randr/randr.c
index 4ea72e505..35f9a4c80 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -406,9 +406,10 @@ CARD16
RRVerticalRefresh (xRRModeInfo *mode)
{
CARD32 refresh;
- if (!mode->hTotal || !mode->vTotal)
+ CARD32 dots = mode->hTotal * mode->vTotal;
+ if (!dots)
return 0;
- refresh = mode->dotClock / (mode->hTotal * mode->vTotal);
+ refresh = (mode->dotClock + dots/2) / dots;
if (refresh > 0xffff)
refresh = 0xffff;
return (CARD16) refresh;
diff --git a/randr/randrstr.h b/randr/randrstr.h
index a4e55890f..6690556b4 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -80,6 +80,7 @@ struct _rrMode {
char *name;
void *devPrivate;
ScreenPtr screen;
+ Bool userDefined;
};
struct _rrCrtc {
@@ -114,6 +115,7 @@ struct _rrOutput {
int numClones;
RROutputPtr *clones;
int numModes;
+ int numPreferred;
RRModePtr *modes;
Bool changed;
PropertyPtr properties;
@@ -144,6 +146,10 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen,
RRCrtcPtr crtc);
+typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property);
+
#endif
typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
@@ -187,6 +193,7 @@ typedef struct _rrScrPriv {
RRScreenSetSizeProcPtr rrScreenSetSize;
RRCrtcSetProcPtr rrCrtcSet;
RRCrtcSetGammaProcPtr rrCrtcSetGamma;
+ RROutputSetPropertyProcPtr rrOutputSetProperty;
#endif
/*
@@ -589,7 +596,8 @@ RROutputSetClones (RROutputPtr output,
Bool
RROutputSetModes (RROutputPtr output,
RRModePtr *modes,
- int numModes);
+ int numModes,
+ int numPreferred);
Bool
RROutputSetCrtcs (RROutputPtr output,
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 3108f1452..baefd3a15 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -88,9 +88,41 @@ RRCrtcNotify (RRCrtcPtr crtc,
ScreenPtr pScreen = crtc->pScreen;
rrScrPriv(pScreen);
int i, j;
- int prevNumOutputs = crtc->numOutputs;
- if (numOutputs != prevNumOutputs)
+ /*
+ * Check to see if any of the new outputs were
+ * not in the old list and mark them as changed
+ */
+ for (i = 0; i < numOutputs; i++)
+ {
+ for (j = 0; j < crtc->numOutputs; j++)
+ if (outputs[i] == crtc->outputs[j])
+ break;
+ if (j == crtc->numOutputs)
+ {
+ outputs[i]->changed = TRUE;
+ crtc->changed = TRUE;
+ }
+ }
+ /*
+ * Check to see if any of the old outputs are
+ * not in the new list and mark them as changed
+ */
+ for (j = 0; j < crtc->numOutputs; j++)
+ {
+ for (i = 0; i < numOutputs; i++)
+ if (outputs[i] == crtc->outputs[j])
+ break;
+ if (i == numOutputs)
+ {
+ crtc->outputs[j]->changed = TRUE;
+ crtc->changed = TRUE;
+ }
+ }
+ /*
+ * Reallocate the crtc output array if necessary
+ */
+ if (numOutputs != crtc->numOutputs)
{
RROutputPtr *newoutputs;
@@ -113,28 +145,13 @@ RRCrtcNotify (RRCrtcPtr crtc,
crtc->outputs = newoutputs;
crtc->numOutputs = numOutputs;
}
- for (i = 0; i < numOutputs; i++)
- {
- for (j = 0; j < crtc->numOutputs; j++)
- if (outputs[i] == crtc->outputs[j])
- break;
- if (j != crtc->numOutputs)
- {
- outputs[i]->changed = TRUE;
- crtc->changed = TRUE;
- }
- }
- for (j = 0; j < crtc->numOutputs; j++)
- {
- for (i = 0; i < numOutputs; i++)
- if (outputs[i] == crtc->outputs[j])
- break;
- if (i != numOutputs)
- {
- crtc->outputs[j]->changed = TRUE;
- crtc->changed = TRUE;
- }
- }
+ /*
+ * Copy the new list of outputs into the crtc
+ */
+ memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr));
+ /*
+ * Update remaining crtc fields
+ */
if (mode != crtc->mode)
{
if (crtc->mode)
@@ -158,6 +175,9 @@ RRCrtcNotify (RRCrtcPtr crtc,
crtc->rotation = rotation;
crtc->changed = TRUE;
}
+ /*
+ * Send events if anything changed
+ */
if (crtc->changed)
{
if (!pScrPriv->changed)
@@ -170,7 +190,35 @@ RRCrtcNotify (RRCrtcPtr crtc,
void
RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
{
-
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv (pScreen);
+ xRRCrtcChangeNotifyEvent ce;
+ RRModePtr mode = crtc->mode;
+
+ ce.type = RRNotify + RREventBase;
+ ce.subCode = RRNotify_CrtcChange;
+ ce.sequenceNumber = client->sequence;
+ ce.timestamp = pScrPriv->lastSetTime.milliseconds;
+ ce.window = pWin->drawable.id;
+ ce.crtc = crtc->id;
+ ce.rotation = crtc->rotation;
+ if (mode)
+ {
+ ce.mode = mode->mode.id;
+ ce.x = crtc->x;
+ ce.y = crtc->y;
+ ce.width = mode->mode.width;
+ ce.height = mode->mode.height;
+ }
+ else
+ {
+ ce.mode = None;
+ ce.x = 0;
+ ce.y = 0;
+ ce.width = 0;
+ ce.height = 0;
+ }
+ WriteEventsToClient (client, 1, (xEvent *) &ce);
}
/*
@@ -381,7 +429,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
rep.y = crtc->y;
rep.width = mode ? mode->mode.width : 0;
rep.height = mode ? mode->mode.height : 0;
- rep.mode = mode->mode.id;
+ rep.mode = mode ? mode->mode.id : 0;
rep.rotation = crtc->rotation;
rep.rotations = crtc->rotations;
rep.nOutput = crtc->numOutputs;
@@ -572,30 +620,30 @@ ProcRRSetCrtcConfig (ClientPtr client)
goto sendReply;
}
- if (mode)
- {
+ /*
+ * Validate requested rotation
+ */
+ rotation = (Rotation) stuff->rotation;
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
/*
- * Validate requested rotation
+ * Invalid rotation
*/
- rotation = (Rotation) stuff->rotation;
-
- /* test the rotation bits only! */
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_90:
- case RR_Rotate_180:
- case RR_Rotate_270:
- break;
- default:
- /*
- * Invalid rotation
- */
- client->errorValue = stuff->rotation;
- if (outputs)
- xfree (outputs);
- return BadValue;
- }
-
+ client->errorValue = stuff->rotation;
+ if (outputs)
+ xfree (outputs);
+ return BadValue;
+ }
+
+ if (mode)
+ {
if ((~crtc->rotations) & rotation)
{
/*
diff --git a/randr/rrmode.c b/randr/rrmode.c
index 3a6748691..07cd0c14f 100644
--- a/randr/rrmode.c
+++ b/randr/rrmode.c
@@ -41,7 +41,6 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *b)
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;
}
@@ -75,6 +74,7 @@ RRModeGet (ScreenPtr pScreen,
memcpy (mode->name, name, modeInfo->nameLength);
mode->name[modeInfo->nameLength] = '\0';
mode->screen = pScreen;
+ mode->userDefined = FALSE;
if (pScrPriv->numModes)
modes = xrealloc (pScrPriv->modes,
@@ -162,7 +162,7 @@ RRModePruneUnused (ScreenPtr pScreen)
memcpy (unused, pScrPriv->modes, num * sizeof (RRModePtr));
for (m = 0; m < num; m++) {
mode = unused[m];
- if (mode->refcnt == 1 && mode->mode.origin != RRModeOriginUser)
+ if (mode->refcnt == 1 && !mode->userDefined)
FreeResource (mode->mode.id, 0);
}
xfree (unused);
diff --git a/randr/rroutput.c b/randr/rroutput.c
index b252d7dec..618ef1f80 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -67,6 +67,7 @@ RROutputCreate (ScreenPtr pScreen,
output->numClones = 0;
output->clones = NULL;
output->numModes = 0;
+ output->numPreferred = 0;
output->modes = NULL;
output->properties = NULL;
output->changed = TRUE;
@@ -120,12 +121,13 @@ RROutputSetClones (RROutputPtr output,
Bool
RROutputSetModes (RROutputPtr output,
RRModePtr *modes,
- int numModes)
+ int numModes,
+ int numPreferred)
{
RRModePtr *newModes;
int i;
- if (numModes == output->numModes)
+ if (numModes == output->numModes && numPreferred == output->numPreferred)
{
for (i = 0; i < numModes; i++)
if (output->modes[i] != modes[i])
@@ -155,6 +157,7 @@ RROutputSetModes (RROutputPtr output,
memcpy (newModes, modes, numModes * sizeof (RRModePtr));
output->modes = newModes;
output->numModes = numModes;
+ output->numPreferred = numPreferred;
output->changed = TRUE;
return TRUE;
}
@@ -341,10 +344,10 @@ ProcRRGetOutputInfo (ClientPtr client)
rep.subpixelOrder = output->subpixelOrder;
rep.nCrtcs = output->numCrtcs;
rep.nModes = output->numModes;
+ rep.nPreferred = output->numPreferred;
rep.nClones = output->numClones;
rep.nameLength = output->nameLength;
rep.possibleOptions = output->possibleOptions;
- rep.pad1 = 42;
extraLen = ((output->numCrtcs +
output->numModes +