summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@guitar.keithp.com>2007-02-15 20:13:15 -0800
committerKeith Packard <keithp@guitar.keithp.com>2007-02-15 20:37:44 -0800
commit258beebc77510f84fbea66d6ebf29c5097bd11db (patch)
treee238bd3f6391bad84c28469690fcc102488517da
parentef6b1235fd7d6dc422e8a150c089496a8e648067 (diff)
Report correct RandR 1.0 sizeID. Report correct subpixel order.
RandR 1.0 sizeID must be computed the same way every time, so when reporting it in the ScreenChangeNotify event, just construct the usual 1.0 data block and use that. subpixel geometry information can be computed by looking at the connected outputs and finding any with subpixel geometry and using one of those for the global screen subpixel geometry. This might be improved by reporting None if more than one screen has information and they conflict.
-rw-r--r--hw/xfree86/modes/xf86Crtc.c67
-rw-r--r--hw/xfree86/modes/xf86Crtc.h8
-rw-r--r--hw/xfree86/modes/xf86RandR12.c1
-rw-r--r--hw/xfree86/modes/xf86Rename.h1
-rw-r--r--randr/rrscreen.c62
5 files changed, 110 insertions, 29 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 5e0a0c602..bda805519 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -144,6 +144,71 @@ xf86CrtcInUse (xf86CrtcPtr crtc)
return FALSE;
}
+void
+xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
+{
+#ifdef RENDER
+ int subpixel_order = SubPixelUnknown;
+ Bool has_none = FALSE;
+ ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c, o;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ for (o = 0; o < xf86_config->num_output; o++)
+ {
+ xf86OutputPtr output = xf86_config->output[o];
+
+ if (output->crtc == crtc)
+ {
+ switch (output->subpixel_order) {
+ case SubPixelNone:
+ has_none = TRUE;
+ break;
+ case SubPixelUnknown:
+ break;
+ default:
+ subpixel_order = output->subpixel_order;
+ break;
+ }
+ }
+ if (subpixel_order != SubPixelUnknown)
+ break;
+ }
+ if (subpixel_order != SubPixelUnknown)
+ {
+ static const int circle[4] = {
+ SubPixelHorizontalRGB,
+ SubPixelVerticalRGB,
+ SubPixelHorizontalBGR,
+ SubPixelVerticalBGR,
+ };
+ int rotate;
+ int c;
+ for (rotate = 0; rotate < 4; rotate++)
+ if (crtc->rotation & (1 << rotate))
+ break;
+ for (c = 0; c < 4; c++)
+ if (circle[c] == subpixel_order)
+ break;
+ c = (c + rotate) & 0x3;
+ if ((crtc->rotation & RR_Reflect_X) && !(c & 1))
+ c ^= 2;
+ if ((crtc->rotation & RR_Reflect_Y) && (c & 1))
+ c ^= 2;
+ subpixel_order = circle[c];
+ break;
+ }
+ }
+ if (subpixel_order == SubPixelUnknown && has_none)
+ subpixel_order = SubPixelNone;
+ PictureSetSubpixelOrder (pScreen, subpixel_order);
+#endif
+}
+
/**
* Sets the given video mode on the given crtc
*/
@@ -245,6 +310,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
/* XXX free adjustedmode */
ret = TRUE;
+ xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
+
done:
if (!ret) {
crtc->x = saved_x;
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 49f4965ba..07f7d4960 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -552,4 +552,12 @@ xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address);
Bool
xf86DiDGAReInit (ScreenPtr pScreen);
+/*
+ * Set the subpixel order reported for the screen using
+ * the information from the outputs
+ */
+
+void
+xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen);
+
#endif /* _XF86CRTC_H_ */
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 2a5d7bab2..1dacb6f34 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -433,6 +433,7 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
}
+ xf86CrtcSetScreenSubpixelOrder (pScreen);
#if RANDR_12_INTERFACE
if (xf86RandR12CreateScreenResources12 (pScreen))
return TRUE;
diff --git a/hw/xfree86/modes/xf86Rename.h b/hw/xfree86/modes/xf86Rename.h
index a00253d56..ce4d21796 100644
--- a/hw/xfree86/modes/xf86Rename.h
+++ b/hw/xfree86/modes/xf86Rename.h
@@ -73,5 +73,6 @@
#define xf86RandR12SetConfig XF86NAME(xf86RandR12SetConfig)
#define xf86RandR12SetRotations XF86NAME(xf86RandR12SetRotations)
#define xf86SaveScreen XF86NAME(xf86SaveScreen)
+#define xf86CrtcSetScreenSubpixelOrder XF86NAME(xf86CrtcSetScreenSubpixelOrder)
#endif /* _XF86RENAME_H_ */
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index e10aa0362..168000351 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -26,6 +26,9 @@ extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
+static CARD16
+RR10CurrentSizeID (ScreenPtr pScreen);
+
/*
* Edit connection information block so that new clients
* see the current screen size on connect
@@ -96,10 +99,7 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
rrScrPriv (pScreen);
xRRScreenChangeNotifyEvent se;
RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL;
- RROutputPtr output = pScrPriv->numOutputs ? pScrPriv->outputs[0] : NULL;
- RRModePtr mode = crtc ? crtc->mode : NULL;
WindowPtr pRoot = WindowTable[pScreen->myNum];
- int i;
se.type = RRScreenChangeNotify + RREventBase;
se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0);
@@ -115,32 +115,12 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
#endif
se.sequenceNumber = client->sequence;
- if (mode)
- {
- se.sizeID = -1;
- for (i = 0; i < output->numModes; i++)
- if (mode == output->modes[i])
- {
- se.sizeID = i;
- break;
- }
- se.widthInPixels = mode->mode.width;
- se.heightInPixels = mode->mode.height;
- se.widthInMillimeters = pScreen->mmWidth;
- se.heightInMillimeters = pScreen->mmHeight;
- }
- else
- {
- /*
- * This "shouldn't happen", but a broken DDX can
- * forget to set the current configuration on GetInfo
- */
- se.sizeID = 0xffff;
- se.widthInPixels = 0;
- se.heightInPixels = 0;
- se.widthInMillimeters = 0;
- se.heightInMillimeters = 0;
- }
+ se.sizeID = RR10CurrentSizeID (pScreen);
+
+ se.widthInPixels = pScreen->width;
+ se.heightInPixels = pScreen->height;
+ se.widthInMillimeters = pScreen->mmWidth;
+ se.heightInMillimeters = pScreen->mmHeight;
WriteEventsToClient (client, 1, (xEvent *) &se);
}
@@ -949,3 +929,27 @@ sendReply:
return (client->noClientException);
}
+static CARD16
+RR10CurrentSizeID (ScreenPtr pScreen)
+{
+ CARD16 sizeID = 0xffff;
+ RROutputPtr output = RRFirstOutput (pScreen);
+
+ if (output)
+ {
+ RR10DataPtr data = RR10GetData (pScreen, output);
+ if (data)
+ {
+ int i;
+ for (i = 0; i < data->nsize; i++)
+ if (data->sizes[i].width == pScreen->width &&
+ data->sizes[i].height == pScreen->height)
+ {
+ sizeID = (CARD16) i;
+ break;
+ }
+ xfree (data);
+ }
+ }
+ return sizeID;
+}