Commit 258beebc authored by Keith Packard's avatar Keith Packard

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.
parent ef6b1235
...@@ -144,6 +144,71 @@ xf86CrtcInUse (xf86CrtcPtr crtc) ...@@ -144,6 +144,71 @@ xf86CrtcInUse (xf86CrtcPtr crtc)
return FALSE; 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 * Sets the given video mode on the given crtc
*/ */
...@@ -245,6 +310,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, ...@@ -245,6 +310,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
/* XXX free adjustedmode */ /* XXX free adjustedmode */
ret = TRUE; ret = TRUE;
xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
done: done:
if (!ret) { if (!ret) {
crtc->x = saved_x; crtc->x = saved_x;
......
...@@ -552,4 +552,12 @@ xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address); ...@@ -552,4 +552,12 @@ xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address);
Bool Bool
xf86DiDGAReInit (ScreenPtr pScreen); xf86DiDGAReInit (ScreenPtr pScreen);
/*
* Set the subpixel order reported for the screen using
* the information from the outputs
*/
void
xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen);
#endif /* _XF86CRTC_H_ */ #endif /* _XF86CRTC_H_ */
...@@ -433,6 +433,7 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen) ...@@ -433,6 +433,7 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
randrp->virtualX = pScrn->virtualX; randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY; randrp->virtualY = pScrn->virtualY;
} }
xf86CrtcSetScreenSubpixelOrder (pScreen);
#if RANDR_12_INTERFACE #if RANDR_12_INTERFACE
if (xf86RandR12CreateScreenResources12 (pScreen)) if (xf86RandR12CreateScreenResources12 (pScreen))
return TRUE; return TRUE;
......
...@@ -73,5 +73,6 @@ ...@@ -73,5 +73,6 @@
#define xf86RandR12SetConfig XF86NAME(xf86RandR12SetConfig) #define xf86RandR12SetConfig XF86NAME(xf86RandR12SetConfig)
#define xf86RandR12SetRotations XF86NAME(xf86RandR12SetRotations) #define xf86RandR12SetRotations XF86NAME(xf86RandR12SetRotations)
#define xf86SaveScreen XF86NAME(xf86SaveScreen) #define xf86SaveScreen XF86NAME(xf86SaveScreen)
#define xf86CrtcSetScreenSubpixelOrder XF86NAME(xf86CrtcSetScreenSubpixelOrder)
#endif /* _XF86RENAME_H_ */ #endif /* _XF86RENAME_H_ */
...@@ -26,6 +26,9 @@ extern char *ConnectionInfo; ...@@ -26,6 +26,9 @@ extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1}; static int padlength[4] = {0, 3, 2, 1};
static CARD16
RR10CurrentSizeID (ScreenPtr pScreen);
/* /*
* Edit connection information block so that new clients * Edit connection information block so that new clients
* see the current screen size on connect * see the current screen size on connect
...@@ -96,10 +99,7 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) ...@@ -96,10 +99,7 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
rrScrPriv (pScreen); rrScrPriv (pScreen);
xRRScreenChangeNotifyEvent se; xRRScreenChangeNotifyEvent se;
RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL; 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]; WindowPtr pRoot = WindowTable[pScreen->myNum];
int i;
se.type = RRScreenChangeNotify + RREventBase; se.type = RRScreenChangeNotify + RREventBase;
se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0); se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0);
...@@ -115,32 +115,12 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) ...@@ -115,32 +115,12 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
#endif #endif
se.sequenceNumber = client->sequence; se.sequenceNumber = client->sequence;
if (mode) se.sizeID = RR10CurrentSizeID (pScreen);
{
se.sizeID = -1; se.widthInPixels = pScreen->width;
for (i = 0; i < output->numModes; i++) se.heightInPixels = pScreen->height;
if (mode == output->modes[i]) se.widthInMillimeters = pScreen->mmWidth;
{ se.heightInMillimeters = pScreen->mmHeight;
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;
}
WriteEventsToClient (client, 1, (xEvent *) &se); WriteEventsToClient (client, 1, (xEvent *) &se);
} }
...@@ -949,3 +929,27 @@ sendReply: ...@@ -949,3 +929,27 @@ sendReply:
return (client->noClientException); 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;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment