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; +}