diff options
author | David Airlie <airlied@linux.ie> | 2007-02-01 16:26:31 +1100 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-02-01 16:12:03 +1100 |
commit | 6748732658850ea506f623a3622aa7135513ffd0 (patch) | |
tree | b1860069e637f8083bbf9fa951e34b0e3c854a57 | |
parent | a77f08298dc7e097025e3f7f92e3665c0ef30095 (diff) |
update to latest intel codebase modulo using their mode set
and it breaks my cursor
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/local_xf86Rename.h | 23 | ||||
-rw-r--r-- | src/radeon_cursor.c | 2 | ||||
-rw-r--r-- | src/radeon_display.c | 82 | ||||
-rw-r--r-- | src/radeon_driver.c | 25 | ||||
-rw-r--r-- | src/radeon_modes.c | 12 | ||||
-rw-r--r-- | src/radeon_randr.c | 8 | ||||
-rw-r--r-- | src/radeon_xf86Crtc.c | 343 | ||||
-rw-r--r-- | src/radeon_xf86Crtc.h | 103 | ||||
-rw-r--r-- | src/radeon_xf86Modes.c | 65 | ||||
-rw-r--r-- | src/radeon_xf86Modes.h | 69 | ||||
-rw-r--r-- | src/radeon_xf86Rename.h | 66 | ||||
-rw-r--r-- | src/radeon_xf86Rotate.c | 401 |
13 files changed, 981 insertions, 220 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0ec7c29..ae2b002 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,7 +83,7 @@ radeon_drv_la_SOURCES = \ radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \ radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \ radeon_xf86Crtc.c radeon_xf86Modes.c radeon_randr.c \ - radeon_edid_modes.c radeon_xf86cvt.c \ + radeon_edid_modes.c radeon_xf86cvt.c radeon_xf86Rotate.c \ $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la diff --git a/src/local_xf86Rename.h b/src/local_xf86Rename.h new file mode 100644 index 0000000..5102170 --- /dev/null +++ b/src/local_xf86Rename.h @@ -0,0 +1,23 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#define XF86NAME(x) radeon_##x diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c index 8c3dcfa..6d61b07 100644 --- a/src/radeon_cursor.c +++ b/src/radeon_cursor.c @@ -202,7 +202,7 @@ RADEONRandrSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) for (c = 0 ; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; - DisplayModePtr mode = &crtc->curMode; + DisplayModePtr mode = &crtc->mode; int thisx = x - crtc->x; int thisy = y - crtc->y; diff --git a/src/radeon_display.c b/src/radeon_display.c index e769e15..a8df106 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -45,6 +45,7 @@ #include "radeon_macros.h" #include "radeon_probe.h" #include "radeon_version.h" +#include "radeon_xf86Modes.h" void radeon_crtc_load_lut(xf86CrtcPtr crtc); @@ -2021,12 +2022,12 @@ void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) { pixel_bytes2 = info->CurrentLayout.pixel_bytes; - mode1 = &xf86_config->crtc[0]->curMode; - mode2 = &xf86_config->crtc[1]->curMode; + mode1 = &xf86_config->crtc[0]->mode; + mode2 = &xf86_config->crtc[1]->mode; } else if (xf86_config->crtc[0]->enabled) { - mode1 = &xf86_config->crtc[0]->curMode; + mode1 = &xf86_config->crtc[0]->mode; } else if (xf86_config->crtc[1]->enabled) { - mode1 = &xf86_config->crtc[1]->curMode; + mode1 = &xf86_config->crtc[1]->mode; } else return; } @@ -2228,7 +2229,7 @@ radeon_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, static void radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, - DisplayModePtr adjusted_mode) + DisplayModePtr adjusted_mode, int x, int y) { ScrnInfoPtr pScrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -2285,6 +2286,24 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, radeon_crtc_load_lut(crtc); } +static Bool +radeon_crtc_lock(xf86CrtcPtr crtc) +{ +#ifdef XF86DRI + /* TODO */ +#endif + return FALSE; +} + +static void +radeon_crtc_unlock(xf86CrtcPtr crtc) +{ +#ifdef XF86DRI + /* TODO */ +#endif + +} + static const xf86CrtcFuncsRec radeon_crtc_funcs = { .dpms = radeon_crtc_dpms, .save = NULL, /* XXX */ @@ -2292,6 +2311,8 @@ static const xf86CrtcFuncsRec radeon_crtc_funcs = { .mode_fixup = radeon_crtc_mode_fixup, .mode_set = radeon_crtc_mode_set, .gamma_set = radeon_crtc_gamma_set, + .lock = radeon_crtc_lock, + .unlock = radeon_crtc_unlock, .destroy = NULL, /* XXX */ }; @@ -2556,16 +2577,21 @@ RADEONCrtcInUse(xf86CrtcPtr crtc) } Bool -RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode) +RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y) { ScrnInfoPtr pScrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); DisplayModePtr adjusted_mode; + Bool didLock = FALSE; RADEONInfoPtr info = RADEONPTR(pScrn); int i , ret; - /* XXX: curMode */ + DisplayModeRec saved_mode; + int saved_x, saved_y; + Rotation saved_rotation; + /* XXX: mode */ - adjusted_mode = xf86DuplicateMode(pMode); + adjusted_mode = xf86DuplicateMode(mode); crtc->enabled = RADEONCrtcInUse (crtc); @@ -2573,6 +2599,21 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode) return TRUE; } + didLock = crtc->funcs->lock (crtc); + + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + + /* Update crtc values up front so the driver can rely on them for mode + * setting. + */ + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; + /* Pass our mode to the outputs and the CRTC to give them a chance to * adjust it according to limitations or output properties, and also * a chance to reject the mode entirely. @@ -2583,17 +2624,21 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode) if (output->crtc != crtc) continue; - if (!output->funcs->mode_fixup(output, pMode, adjusted_mode)) { + if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) { ret = FALSE; goto done; } } - if (!crtc->funcs->mode_fixup(crtc, pMode, adjusted_mode)) { + if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) { ret = FALSE; goto done; } + if (!xf86CrtcRotate (crtc, mode, rotation)) { + goto done; + } + #if 0 /* Disable the outputs and CRTCs before setting the mode. */ for (i = 0; i < xf86_config->num_output; i++) { @@ -2612,11 +2657,11 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode) /* Set up the DPLL and any output state that needs to adjust or depend * on the DPLL. */ - crtc->funcs->mode_set(crtc, pMode, adjusted_mode); + crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y); for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; if (output->crtc == crtc) - output->funcs->mode_set(output, pMode, adjusted_mode); + output->funcs->mode_set(output, mode, adjusted_mode); } #if 0 @@ -2628,12 +2673,21 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode) output->funcs->dpms(output, DPMSModeOn); } #endif - crtc->curMode = *pMode; /* XXX free adjustedmode */ ret = TRUE; done: + if (!ret) { + crtc->x = saved_x; + crtc->y = saved_y; + crtc->rotation = saved_rotation; + crtc->mode = saved_mode; + } + + if (didLock) + crtc->funcs->unlock (crtc); + return ret; } @@ -2757,7 +2811,7 @@ RADEONDisableUnusedFunctions(ScrnInfoPtr pScrn) { xf86CrtcPtr crtc = xf86_config->crtc[c]; if (!crtc->enabled) { - memset(&crtc->curMode, 0, sizeof(crtc->curMode)); + memset(&crtc->mode, 0, sizeof(crtc->mode)); radeon_crtc_dpms(crtc, DPMSModeOff); } } diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 44a7eb2..f984b20 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -112,6 +112,7 @@ /* Forward definitions for driver functions */ +void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore); static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode); static void RADEONSave(ScrnInfoPtr pScrn); @@ -3635,10 +3636,14 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, xf86CrtcPtr crtc = xf86_config->crtc[i]; /* Mark that we'll need to re-set the mode for sure */ - memset(&crtc->curMode, 0, sizeof(crtc->curMode)); - if (!crtc->desiredMode.CrtcHDisplay) + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) { crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode); - + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE)) return FALSE; @@ -5423,8 +5428,6 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); xf86OutputPtr connector; - pRADEONEnt->pCrtc[0]->curMode = *mode; - switch (info->CurrentLayout.pixel_code) { case 4: format = 1; break; case 8: format = 2; break; @@ -5611,8 +5614,6 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, if (info->IsSecondary) info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn); - pRADEONEnt->pCrtc[1]->curMode = *mode; - switch (info->CurrentLayout.pixel_code) { case 4: format = 1; break; case 8: format = 2; break; @@ -6329,10 +6330,14 @@ _X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags) RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; radeon_crtc->binding = info->IsSecondary ? 2 : 1; /* Mark that we'll need to re-set the mode for sure */ - memset(&crtc->curMode, 0, sizeof(crtc->curMode)); - if (!crtc->desiredMode.CrtcHDisplay) + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) { crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode); - + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE)) return FALSE; diff --git a/src/radeon_modes.c b/src/radeon_modes.c index ba14fe7..16c2c30 100644 --- a/src/radeon_modes.c +++ b/src/radeon_modes.c @@ -291,7 +291,7 @@ RADEONProbeOutputModes(xf86OutputPtr output) mode->status = MODE_CLOCK_RANGE; } } - RADEONxf86PruneInvalidModes(pScrn, &ddc_modes, TRUE); + xf86PruneInvalidModes(pScrn, &ddc_modes, TRUE); /* do some physcial size stuff */ } @@ -316,9 +316,9 @@ RADEONProbeOutputModes(xf86OutputPtr output) fixed_mon.vrefresh[0].lo = 50.0; fixed_mon.vrefresh[0].hi = 70.0; - modes = RADEON_xf86DuplicateModes(pScrn, pScrn->monitor->Modes); - RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon); - RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE); + modes = xf86DuplicateModes(pScrn, pScrn->monitor->Modes); + xf86ValidateModesSync(pScrn, modes, &fixed_mon); + xf86PruneInvalidModes(pScrn, &modes, TRUE); /* fill out CRT of FP mode table */ output->probed_modes = modes; break; @@ -332,9 +332,9 @@ RADEONProbeOutputModes(xf86OutputPtr output) } if (output->probed_modes) { - RADEONxf86ValidateModesUserConfig(pScrn, + xf86ValidateModesUserConfig(pScrn, output->probed_modes); - RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes, + xf86PruneInvalidModes(pScrn, &output->probed_modes, FALSE); } } diff --git a/src/radeon_randr.c b/src/radeon_randr.c index 63b0080..97c9295 100644 --- a/src/radeon_randr.c +++ b/src/radeon_randr.c @@ -392,8 +392,8 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen) for (c = 0; c < config->num_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; - int crtc_width = crtc->x + crtc->curMode.HDisplay; - int crtc_height = crtc->y + crtc->curMode.VDisplay; + int crtc_width = crtc->x + crtc->mode.HDisplay; + int crtc_height = crtc->y + crtc->mode.VDisplay; if (crtc->enabled && crtc_width > width) width = crtc_width; @@ -532,7 +532,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) xf86CrtcPtr crtc = randr_crtc->devPrivate; xf86OutputPtr output; int i, j; - DisplayModePtr curMode = &crtc->curMode; + DisplayModePtr curMode = &crtc->mode; Bool ret; randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr)); @@ -595,7 +595,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr)); if ((mode != NULL) != crtc->enabled) changed = TRUE; - else if (mode && !xf86ModesEqual (&crtc->curMode, mode)) + else if (mode && !xf86ModesEqual (&crtc->mode, mode)) changed = TRUE; pos_changed = changed; diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c index df7b1bd..7e4ae39 100644 --- a/src/radeon_xf86Crtc.c +++ b/src/radeon_xf86Crtc.c @@ -89,6 +89,8 @@ xf86CrtcCreate (ScrnInfoPtr scrn, #ifdef RANDR_12_INTERFACE crtc->randr_crtc = NULL; #endif + crtc->rotation = RR_Rotate_0; + crtc->desiredRotation = RR_Rotate_0; if (xf86_config->crtc) crtcs = xrealloc (xf86_config->crtc, (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr)); @@ -123,6 +125,139 @@ xf86CrtcDestroy (xf86CrtcPtr crtc) xfree (crtc); } + +/** + * Return whether any outputs are connected to the specified pipe + */ + +Bool +xf86CrtcInUse (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int o; + + for (o = 0; o < xf86_config->num_output; o++) + if (xf86_config->output[o]->crtc == crtc) + return TRUE; + return FALSE; +} + +/** + * Sets the given video mode on the given crtc + */ +Bool +xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int i; + Bool ret = FALSE; + Bool didLock = FALSE; + DisplayModePtr adjusted_mode; + DisplayModeRec saved_mode; + int saved_x, saved_y; + Rotation saved_rotation; + + adjusted_mode = xf86DuplicateMode(mode); + + crtc->enabled = xf86CrtcInUse (crtc); + + if (!crtc->enabled) + { + /* XXX disable crtc? */ + return TRUE; + } + + didLock = crtc->funcs->lock (crtc); + + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + /* Update crtc values up front so the driver can rely on them for mode + * setting. + */ + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; + + /* XXX short-circuit changes to base location only */ + + /* Pass our mode to the outputs and the CRTC to give them a chance to + * adjust it according to limitations or output properties, and also + * a chance to reject the mode entirely. + */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if (output->crtc != crtc) + continue; + + if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) { + goto done; + } + } + + if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) { + goto done; + } + + if (!xf86CrtcRotate (crtc, mode, rotation)) { + goto done; + } + + /* Disable the outputs and CRTCs before setting the mode. */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if (output->crtc != crtc) + continue; + + /* Disable the output as the first thing we do. */ + output->funcs->dpms(output, DPMSModeOff); + } + + crtc->funcs->dpms(crtc, DPMSModeOff); + + /* Set up the DPLL and any output state that needs to adjust or depend + * on the DPLL. + */ + crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y); + for (i = 0; i < xf86_config->num_output; i++) + { + xf86OutputPtr output = xf86_config->output[i]; + if (output->crtc == crtc) + output->funcs->mode_set(output, mode, adjusted_mode); + } + + /* Now, enable the clocks, plane, pipe, and outputs that we set up. */ + crtc->funcs->dpms(crtc, DPMSModeOn); + for (i = 0; i < xf86_config->num_output; i++) + { + xf86OutputPtr output = xf86_config->output[i]; + if (output->crtc == crtc) + output->funcs->dpms(output, DPMSModeOn); + } + + /* XXX free adjustedmode */ + ret = TRUE; +done: + if (!ret) { + crtc->x = saved_x; + crtc->y = saved_y; + crtc->rotation = saved_rotation; + crtc->mode = saved_mode; + } + + if (didLock) + crtc->funcs->unlock (crtc); + + return ret; +} + /* * Output functions */ @@ -364,14 +499,14 @@ xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height) } static int -xf86PickCrtcs (ScrnInfoPtr pScrn, +xf86PickCrtcs (ScrnInfoPtr scrn, xf86CrtcPtr *best_crtcs, DisplayModePtr *modes, int n, int width, int height) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int c, o, l; xf86OutputPtr output; xf86CrtcPtr crtc; @@ -390,7 +525,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, */ best_crtcs[n] = NULL; best_crtc = NULL; - best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1, width, height); + best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height); if (modes[n] == NULL) return best_score; @@ -444,7 +579,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, } crtcs[n] = crtc; memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr)); - score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height); + score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height); if (score > best_score) { best_crtc = crtc; @@ -464,9 +599,9 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, */ static void -xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) +xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int width = 0, height = 0; int o; int c; @@ -515,9 +650,9 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) #define POSITION_UNSET -100000 static Bool -xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes) +xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int o; int min_x, min_y; @@ -565,7 +700,7 @@ xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes) } else { - xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + xf86DrvMsg (scrn->scrnIndex, X_ERROR, "Output %s position not of form \"x y\"\n", output->name); output->initial_x = output->initial_y = 0; @@ -608,7 +743,7 @@ xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes) } if (!relative) { - xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + xf86DrvMsg (scrn->scrnIndex, X_ERROR, "Cannot position output %s relative to unknown output %s\n", output->name, relative_name); output->initial_x = 0; @@ -657,7 +792,7 @@ xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes) xf86OutputPtr output = config->output[o]; if (output->initial_x == POSITION_UNSET) { - xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + xf86DrvMsg (scrn->scrnIndex, X_ERROR, "Output position loop. Moving %s to 0,0\n", output->name); output->initial_x = output->initial_y = 0; @@ -780,16 +915,16 @@ i830xf86SortModes (DisplayModePtr input) #define DEBUG_REPROBE 1 void -xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) +xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int o; if (maxX == 0 || maxY == 0) - xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY); + xf86RandR12GetOriginalVirtualSize (scrn, &maxX, &maxY); /* Elide duplicate modes before defaulting code uses them */ - xf86PruneDuplicateMonitorModes (pScrn->monitor); + xf86PruneDuplicateMonitorModes (scrn->monitor); /* Probe the list of modes for each output. */ for (o = 0; o < config->num_output; o++) @@ -839,7 +974,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) mon_rec.nVrefresh++; sync_source = sync_config; } - config_modes = RADEONxf86GetMonitorModes (pScrn, conf_monitor); + config_modes = xf86GetMonitorModes (scrn, conf_monitor); } output_modes = (*output->funcs->get_modes) (output); @@ -903,27 +1038,27 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) mon_rec.vrefresh[0].hi = 62.0; mon_rec.nVrefresh = 1; } - default_modes = RADEONxf86GetDefaultModes (output->interlaceAllowed, - output->doubleScanAllowed); + default_modes = xf86GetDefaultModes (output->interlaceAllowed, + output->doubleScanAllowed); if (sync_source == sync_config) { /* * Check output and config modes against sync range from config file */ - RADEONxf86ValidateModesSync (pScrn, output_modes, &mon_rec); - RADEONxf86ValidateModesSync (pScrn, config_modes, &mon_rec); + xf86ValidateModesSync (scrn, output_modes, &mon_rec); + xf86ValidateModesSync (scrn, config_modes, &mon_rec); } /* * Check default modes against sync range */ - RADEONxf86ValidateModesSync (pScrn, default_modes, &mon_rec); + xf86ValidateModesSync (scrn, default_modes, &mon_rec); /* * Check default modes against monitor max clock */ if (max_clock) - RADEONxf86ValidateModesClocks(pScrn, default_modes, - &min_clock, &max_clock, 1); + xf86ValidateModesClocks(scrn, default_modes, + &min_clock, &max_clock, 1); output->probed_modes = NULL; output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes); @@ -934,7 +1069,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) * Check all modes against max size */ if (maxX && maxY) - RADEONxf86ValidateModesSize (pScrn, output->probed_modes, + xf86ValidateModesSize (scrn, output->probed_modes, maxX, maxY, 0); /* @@ -944,7 +1079,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) if (mode->status == MODE_OK) mode->status = (*output->funcs->mode_valid)(output, mode); - RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes, TRUE); + xf86PruneInvalidModes(scrn, &output->probed_modes, TRUE); output->probed_modes = i830xf86SortModes (output->probed_modes); @@ -977,11 +1112,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) #ifdef DEBUG_REPROBE if (output->probed_modes != NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Printing probed modes for output %s\n", output->name); } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(scrn->scrnIndex, X_INFO, "No remaining probed modes for output %s\n", output->name); } @@ -995,7 +1130,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) xf86SetModeCrtc(mode, INTERLACE_HALVE_V); #ifdef DEBUG_REPROBE - xf86PrintModeline(pScrn->scrnIndex, mode); + xf86PrintModeline(scrn->scrnIndex, mode); #endif } } @@ -1008,12 +1143,12 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) /* XXX where does this function belong? Here? */ void -xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y); +xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y); void -xf86SetScrnInfoModes (ScrnInfoPtr pScrn) +xf86SetScrnInfoModes (ScrnInfoPtr scrn) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86OutputPtr output; xf86CrtcPtr crtc; DisplayModePtr last, mode; @@ -1037,31 +1172,31 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn) } crtc = output->crtc; - /* Clear any existing modes from pScrn->modes */ - while (pScrn->modes != NULL) - xf86DeleteMode(&pScrn->modes, pScrn->modes); + /* Clear any existing modes from scrn->modes */ + while (scrn->modes != NULL) + xf86DeleteMode(&scrn->modes, scrn->modes); - /* Set pScrn->modes to the mode list for the 'compat' output */ - pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes); + /* Set scrn->modes to the mode list for the 'compat' output */ + scrn->modes = xf86DuplicateModes(scrn, output->probed_modes); - for (mode = pScrn->modes; mode; mode = mode->next) + for (mode = scrn->modes; mode; mode = mode->next) if (xf86ModesEqual (mode, &crtc->desiredMode)) break; - if (pScrn->modes != NULL) { - /* For some reason, pScrn->modes is circular, unlike the other mode + if (scrn->modes != NULL) { + /* For some reason, scrn->modes is circular, unlike the other mode * lists. How great is that? */ - for (last = pScrn->modes; last && last->next; last = last->next) + for (last = scrn->modes; last && last->next; last = last->next) ; - last->next = pScrn->modes; - pScrn->modes->prev = last; + last->next = scrn->modes; + scrn->modes->prev = last; if (mode) { - while (pScrn->modes != mode) - pScrn->modes = pScrn->modes->next; + while (scrn->modes != mode) + scrn->modes = scrn->modes->next; } } - pScrn->currentMode = pScrn->modes; + scrn->currentMode = scrn->modes; } /** @@ -1072,9 +1207,9 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn) */ Bool -xf86InitialConfiguration (ScrnInfoPtr pScrn) +xf86InitialConfiguration (ScrnInfoPtr scrn) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int o, c; DisplayModePtr target_mode = NULL; xf86CrtcPtr *crtcs; @@ -1083,16 +1218,16 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) int width; int height; - if (pScrn->display->virtualX) - width = pScrn->display->virtualX; + if (scrn->display->virtualX) + width = scrn->display->virtualX; else width = config->maxWidth; - if (pScrn->display->virtualY) - height = pScrn->display->virtualY; + if (scrn->display->virtualY) + height = scrn->display->virtualY; else height = config->maxHeight; - xf86ProbeOutputModes (pScrn, width, height); + xf86ProbeOutputModes (scrn, width, height); crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr)); modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr)); @@ -1154,7 +1289,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) /* * Set the position of each output */ - if (!xf86InitialOutputPositions (pScrn, modes)) + if (!xf86InitialOutputPositions (scrn, modes)) { xfree (crtcs); xfree (modes); @@ -1164,7 +1299,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) /* * Assign CRTCs to fit output configuration */ - if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height)) + if (!xf86PickCrtcs (scrn, crtcs, modes, 0, width, height)) { xfree (crtcs); xfree (modes); @@ -1173,8 +1308,8 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) /* XXX override xf86 common frame computation code */ - pScrn->display->frameX0 = 0; - pScrn->display->frameY0 = 0; + scrn->display->frameX0 = 0; + scrn->display->frameY0 = 0; for (c = 0; c < config->num_crtc; c++) { @@ -1203,24 +1338,24 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) } } - if (pScrn->display->virtualX == 0) + if (scrn->display->virtualX == 0) { /* * Expand virtual size to cover potential mode switches */ - xf86DefaultScreenLimits (pScrn, &width, &height); + xf86DefaultScreenLimits (scrn, &width, &height); - pScrn->display->virtualX = width; - pScrn->display->virtualY = height; + scrn->display->virtualX = width; + scrn->display->virtualY = height; } - if (width > pScrn->virtualX) - pScrn->virtualX = width; - if (height > pScrn->virtualY) - pScrn->virtualY = height; + if (width > scrn->virtualX) + scrn->virtualX = width; + if (height > scrn->virtualY) + scrn->virtualY = height; - /* Mirror output modes to pScrn mode list */ - xf86SetScrnInfoModes (pScrn); + /* Mirror output modes to scrn mode list */ + xf86SetScrnInfoModes (scrn); xfree (crtcs); xfree (modes); @@ -1234,11 +1369,14 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) * Otherwise, it will affect CRTCs before outputs. */ void -xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags) +xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int i; + if (!scrn->vtSema) + return; + if (mode == DPMSModeOff) { for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; @@ -1262,6 +1400,53 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags) } } +/** + * Implement the screensaver by just calling down into the driver DPMS hooks. + * + * Even for monitors with no DPMS support, by the definition of our DPMS hooks, + * the outputs will still get disabled (blanked). + */ +Bool +xf86SaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (xf86IsUnblank(mode)) + xf86DPMSSet(pScrn, DPMSModeOn, 0); + else + xf86DPMSSet(pScrn, DPMSModeOff, 0); + + return TRUE; +} + +/** + * Disable all inactive crtcs and outputs + */ +void +xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int o, c; + + for (o = 0; o < xf86_config->num_output; o++) + { + xf86OutputPtr output = xf86_config->output[o]; + if (!output->crtc) + (*output->funcs->dpms)(output, DPMSModeOff); + } + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (!crtc->enabled) + { + crtc->funcs->dpms(crtc, DPMSModeOff); + memset(&crtc->mode, 0, sizeof(crtc->mode)); + } + } +} + #ifdef RANDR_12_INTERFACE #define EDID_ATOM_NAME "EDID_DATA" @@ -1292,10 +1477,10 @@ xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len) * Set the EDID information for the specified output */ void -i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) +xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) { - ScrnInfoPtr pScrn = output->scrn; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + ScrnInfoPtr scrn = output->scrn; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int i; #ifdef RANDR_12_INTERFACE int size; @@ -1307,12 +1492,12 @@ i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) output->MonInfo = edid_mon; /* Debug info for now, at least */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name); + xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name); xf86PrintEDID(edid_mon); /* Set the DDC properties for the 'compat' output */ if (output == config->output[config->compat_output]) - xf86SetDDCproperties(pScrn, edid_mon); + xf86SetDDCproperties(scrn, edid_mon); #ifdef RANDR_12_INTERFACE /* Set the RandR output properties */ @@ -1356,20 +1541,20 @@ i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) * stored in 'output' */ DisplayModePtr -i830_xf86OutputGetEDIDModes (xf86OutputPtr output) +xf86OutputGetEDIDModes (xf86OutputPtr output) { - ScrnInfoPtr pScrn = output->scrn; + ScrnInfoPtr scrn = output->scrn; xf86MonPtr edid_mon = output->MonInfo; if (!edid_mon) return NULL; - return xf86DDCGetModes(pScrn->scrnIndex, edid_mon); + return xf86DDCGetModes(scrn->scrnIndex, edid_mon); } xf86MonPtr -i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) +xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) { - ScrnInfoPtr pScrn = output->scrn; + ScrnInfoPtr scrn = output->scrn; - return xf86DoEDID_DDC2 (pScrn->scrnIndex, pDDCBus); + return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus); } diff --git a/src/radeon_xf86Crtc.h b/src/radeon_xf86Crtc.h index 2f534f8..67950da 100644 --- a/src/radeon_xf86Crtc.h +++ b/src/radeon_xf86Crtc.h @@ -26,6 +26,7 @@ #include "randrstr.h" #include "radeon_xf86Modes.h" #include "xf86Parser.h" +#include "damage.h" /* Compat definitions for older X Servers. */ #ifndef M_T_PREFERRED @@ -68,7 +69,19 @@ typedef struct _xf86CrtcFuncs { void (*restore)(xf86CrtcPtr crtc); - + /** + * Lock CRTC prior to mode setting, mostly for DRI. + * Returns whether unlock is needed + */ + Bool + (*lock) (xf86CrtcPtr crtc); + + /** + * Unlock CRTC after mode setting, mostly for DRI + */ + void + (*unlock) (xf86CrtcPtr crtc); + /** * Callback to adjust the mode to be set in the CRTC. * @@ -87,7 +100,8 @@ typedef struct _xf86CrtcFuncs { void (*mode_set)(xf86CrtcPtr crtc, DisplayModePtr mode, - DisplayModePtr adjusted_mode); + DisplayModePtr adjusted_mode, + int x, int y); /* Set the color ramps for the CRTC to the given values. */ void @@ -95,6 +109,18 @@ typedef struct _xf86CrtcFuncs { int size); /** + * Create shadow pixmap for rotation support + */ + PixmapPtr + (*shadow_create) (xf86CrtcPtr crtc, int width, int height); + + /** + * Destroy shadow pixmap + */ + void + (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap); + + /** * Clean up driver-specific bits of the crtc */ void @@ -114,13 +140,6 @@ struct _xf86Crtc { */ Bool enabled; - /** - * Position on screen - * - * Locates this CRTC within the frame buffer - */ - int x, y; - /** Track whether cursor is within CRTC range */ Bool cursorInRange; @@ -134,7 +153,15 @@ struct _xf86Crtc { * It will be cleared when the VT is not active or * during server startup */ - DisplayModeRec curMode; + DisplayModeRec mode; + Rotation rotation; + PixmapPtr rotatedPixmap; + /** + * Position on screen + * + * Locates this CRTC within the frame buffer + */ + int x, y; /** * Desired mode @@ -145,6 +172,8 @@ struct _xf86Crtc { * on VT switch. */ DisplayModeRec desiredMode; + Rotation desiredRotation; + int desiredX, desiredY; /** crtc-specific functions */ const xf86CrtcFuncsRec *funcs; @@ -171,6 +200,13 @@ struct _xf86Crtc { typedef struct _xf86OutputFuncs { /** + * Called to allow the output a chance to create properties after the + * RandR objects have been created. + */ + void + (*create_resources)(xf86OutputPtr output); + + /** * Turns the output on/off, or sets intermediate power levels if available. * * Unsupported intermediate modes drop to the lower power setting. If the @@ -245,6 +281,15 @@ typedef struct _xf86OutputFuncs { DisplayModePtr (*get_modes)(xf86OutputPtr output); +#ifdef RANDR_12_INTERFACE + /** + * Callback when an output's property has changed. + */ + Bool + (*set_property)(xf86OutputPtr output, + Atom property, + RRPropertyValuePtr value); +#endif /** * Clean up driver-specific bits of the output */ @@ -363,6 +408,13 @@ typedef struct _xf86CrtcConfig { int minWidth, minHeight; int maxWidth, maxHeight; + + /* For crtc-based rotation */ + DamagePtr rotationDamage; + + /* DGA */ + unsigned int dga_flags; + } xf86CrtcConfigRec, *xf86CrtcConfigPtr; extern int xf86CrtcConfigPrivateIndex; @@ -411,6 +463,25 @@ xf86AllocCrtc (xf86OutputPtr output); void xf86FreeCrtc (xf86CrtcPtr crtc); +/** + * Sets the given video mode on the given crtc + */ +Bool +xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y); + +/* + * Assign crtc rotation during mode set + */ +Bool +xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation); + +/** + * Return whether any output is assigned to the crtc + */ +Bool +xf86CrtcInUse (xf86CrtcPtr crtc); + /* * Output functions */ @@ -437,20 +508,26 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn); void xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); +Bool +xf86SaveScreen(ScreenPtr pScreen, int mode); + +void +xf86DisableUnusedFunctions(ScrnInfoPtr pScrn); + /** * Set the EDID information for the specified output */ void -i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon); +xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon); /** * Return the list of modes supported by the EDID information * stored in 'output' */ DisplayModePtr -i830_xf86OutputGetEDIDModes (xf86OutputPtr output); +xf86OutputGetEDIDModes (xf86OutputPtr output); xf86MonPtr -i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus); +xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus); #endif /* _XF86CRTC_H_ */ diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c index fa7f97a..ce9151b 100644 --- a/src/radeon_xf86Modes.c +++ b/src/radeon_xf86Modes.c @@ -148,47 +148,13 @@ xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) p->CrtcVSyncEnd *= p->VScan; p->CrtcVTotal *= p->VScan; } - p->CrtcHAdjusted = FALSE; - p->CrtcVAdjusted = FALSE; - - /* - * XXX - * - * The following is taken from VGA, but applies to other cores as well. - */ p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay); p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal); - if ((p->CrtcVBlankEnd - p->CrtcVBlankStart) >= 127) { - /* - * V Blanking size must be < 127. - * Moving blank start forward is safer than moving blank end - * back, since monitors clamp just AFTER the sync pulse (or in - * the sync pulse), but never before. - */ - p->CrtcVBlankStart = p->CrtcVBlankEnd - 127; - /* - * If VBlankStart is now > VSyncStart move VBlankStart - * to VSyncStart using the maximum width that fits into - * VTotal. - */ - if (p->CrtcVBlankStart > p->CrtcVSyncStart) { - p->CrtcVBlankStart = p->CrtcVSyncStart; - p->CrtcVBlankEnd = min(p->CrtcHBlankStart + 127, p->CrtcVTotal); - } - } p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay); p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal); - if ((p->CrtcHBlankEnd - p->CrtcHBlankStart) >= 63 * 8) { - /* - * H Blanking size must be < 63*8. Same remark as above. - */ - p->CrtcHBlankStart = p->CrtcHBlankEnd - 63 * 8; - if (p->CrtcHBlankStart > p->CrtcHSyncStart) { - p->CrtcHBlankStart = p->CrtcHSyncStart; - p->CrtcHBlankEnd = min(p->CrtcHBlankStart + 63 * 8, p->CrtcHTotal); - } - } + p->CrtcHAdjusted = FALSE; + p->CrtcVAdjusted = FALSE; } /** @@ -337,7 +303,7 @@ xf86PrintModeline(int scrnIndex,DisplayModePtr mode) * This is not in xf86Modes.c, but would be part of the proposed new API. */ void -RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, +xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, int flags) { DisplayModePtr mode; @@ -358,7 +324,7 @@ RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, * This is not in xf86Modes.c, but would be part of the proposed new API. */ void -RADEONxf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, +xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, int maxX, int maxY, int maxPitch) { DisplayModePtr mode; @@ -387,7 +353,7 @@ RADEONxf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, * This is not in xf86Modes.c, but would be part of the proposed new API. */ void -RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, +xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, MonPtr mon) { DisplayModePtr mode; @@ -434,7 +400,7 @@ RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, * This is not in xf86Modes.c, but would be part of the proposed new API. */ void -RADEONxf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, +xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, int *min, int *max, int n_ranges) { DisplayModePtr mode; @@ -468,7 +434,7 @@ RADEONxf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, * This is not in xf86Modes.c, but would be part of the proposed new API. */ void -RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) +xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) { DisplayModePtr mode; @@ -502,7 +468,7 @@ RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList) * This is not in xf86Modes.c, but would be part of the proposed new API. */ void -RADEONxf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, +xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, Bool verbose) { DisplayModePtr mode; @@ -558,13 +524,13 @@ xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new) * Build a mode list from a list of config file modes */ static DisplayModePtr -RADEONxf86GetConfigModes (XF86ConfModeLinePtr conf_mode) +xf86GetConfigModes (XF86ConfModeLinePtr conf_mode) { DisplayModePtr head = NULL, prev = NULL, mode; for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next) { - mode = xalloc(sizeof(DisplayModeRec)); + mode = xcalloc(1, sizeof(DisplayModeRec)); if (!mode) continue; mode->name = xstrdup(conf_mode->ml_identifier); @@ -573,8 +539,6 @@ RADEONxf86GetConfigModes (XF86ConfModeLinePtr conf_mode) xfree (mode); continue; } - - memset(mode,'\0',sizeof(DisplayModeRec)); mode->type = 0; mode->Clock = conf_mode->ml_clock; mode->HDisplay = conf_mode->ml_hdisplay; @@ -600,12 +564,11 @@ RADEONxf86GetConfigModes (XF86ConfModeLinePtr conf_mode) return head; } - /** * Build a mode list from a monitor configuration */ DisplayModePtr -RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) +xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) { DisplayModePtr modes = NULL; XF86ConfModesLinkPtr modes_link; @@ -626,18 +589,18 @@ RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) xf86configptr->conf_modes_lst); if (modes_link->ml_modes) modes = xf86ModesAdd (modes, - RADEONxf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst)); + xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst)); } return xf86ModesAdd (modes, - RADEONxf86GetConfigModes (conf_monitor->mon_modeline_lst)); + xf86GetConfigModes (conf_monitor->mon_modeline_lst)); } /** * Build a mode list containing all of the default modes */ DisplayModePtr -RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed) +xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed) { DisplayModePtr head = NULL, prev = NULL, mode; int i; diff --git a/src/radeon_xf86Modes.h b/src/radeon_xf86Modes.h index 8e23997..6668f44 100644 --- a/src/radeon_xf86Modes.h +++ b/src/radeon_xf86Modes.h @@ -29,67 +29,54 @@ #define _RADEON_XF86MODES_H_ #include "xorgVersion.h" #include "xf86Parser.h" +#include "radeon_xf86Rename.h" -#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) -double RADEON_xf86ModeHSync(DisplayModePtr mode); -double RADEON_xf86ModeVRefresh(DisplayModePtr mode); -DisplayModePtr RADEON_xf86DuplicateMode(DisplayModePtr pMode); -DisplayModePtr RADEON_xf86DuplicateModes(ScrnInfoPtr pScrn, +double xf86ModeHSync(DisplayModePtr mode); +double xf86ModeVRefresh(DisplayModePtr mode); +DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode); +DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList); -void RADEON_xf86SetModeDefaultName(DisplayModePtr mode); -void RADEON_xf86SetModeCrtc(DisplayModePtr p, int adjustFlags); -Bool RADEON_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); -void RADEON_xf86PrintModeline(int scrnIndex,DisplayModePtr mode); -DisplayModePtr RADEON_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new); +void xf86SetModeDefaultName(DisplayModePtr mode); +void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags); +Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); +void xf86PrintModeline(int scrnIndex,DisplayModePtr mode); +DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new); -DisplayModePtr RADEON_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); -DisplayModePtr RADEON_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, - Bool Reduced, Bool Interlaced); - -#define xf86ModeHSync RADEON_xf86ModeHSync -#define xf86ModeVRefresh RADEON_xf86ModeVRefresh -#define xf86DuplicateMode RADEON_xf86DuplicateMode -#define xf86DuplicateModes RADEON_xf86DuplicateModes -#define xf86SetModeDefaultName RADEON_xf86SetModeDefaultName -#define xf86SetModeCrtc RADEON_xf86SetModeCrtc -#define xf86ModesEqual RADEON_xf86ModesEqual -#define xf86PrintModeline RADEON_xf86PrintModeline -#define xf86ModesAdd RADEON_xf86ModesAdd -#define xf86DDCGetModes RADEON_xf86DDCGetModes -#define xf86CVTMode RADEON_xf86CVTMode -#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */ +DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); +DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, + Bool Reduced, Bool Interlaced); void -RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int flags); +xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, + int flags); void -RADEONxf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int *min, int *max, int n_ranges); +xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList, + int *min, int *max, int n_ranges); void -RADEONxf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int maxX, int maxY, int maxPitch); +xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList, + int maxX, int maxY, int maxPitch); void -RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, - MonPtr mon); +xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, + MonPtr mon); void -RADEONxf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, - Bool verbose); +xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, + Bool verbose); void -RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, - int flags); +xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, + int flags); void -RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList); +xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList); DisplayModePtr -RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor); +xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor); DisplayModePtr -RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed); +xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed); #endif diff --git a/src/radeon_xf86Rename.h b/src/radeon_xf86Rename.h new file mode 100644 index 0000000..cf8de62 --- /dev/null +++ b/src/radeon_xf86Rename.h @@ -0,0 +1,66 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _XF86RENAME_H_ +#define _XF86RENAME_H_ + +#include "local_xf86Rename.h" + +#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit) +#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex) +#define xf86CrtcCreate XF86NAME(xf86CrtcCreate) +#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy) +#define xf86CrtcInUse XF86NAME(xf86CrtcInUse) +#define xf86CrtcRotate XF86NAME(xf86CrtcRotate) +#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode) +#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange) +#define xf86CVTMode XF86NAME(xf86CVTMode) +#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions) +#define xf86DPMSSet XF86NAME(xf86DPMSSet) +#define xf86DuplicateMode XF86NAME(xf86DuplicateMode) +#define xf86DuplicateModes XF86NAME(xf86DuplicateModes) +#define xf86GetDefaultModes XF86NAME(xf86GetDefaultModes) +#define xf86GetMonitorModes XF86NAME(xf86GetMonitorModes) +#define xf86InitialConfiguration XF86NAME(xf86InitialConfiguration) +#define xf86ModeHSync XF86NAME(xf86ModeHSync) +#define xf86ModesAdd XF86NAME(xf86ModesAdd) +#define xf86ModesEqual XF86NAME(xf86ModesEqual) +#define xf86ModeVRefresh XF86NAME(xf86ModeVRefresh) +#define xf86OutputCreate XF86NAME(xf86OutputCreate) +#define xf86OutputDestroy XF86NAME(xf86OutputDestroy) +#define xf86OutputGetEDID XF86NAME(xf86OutputGetEDID) +#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes) +#define xf86OutputRename XF86NAME(xf86OutputRename) +#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID) +#define xf86PrintModeline XF86NAME(xf86PrintModeline) +#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes) +#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes) +#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc) +#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName) +#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes) +#define xf86ValidateModesClocks XF86NAME(xf86ValidateModesClocks) +#define xf86ValidateModesFlags XF86NAME(xf86ValidateModesFlags) +#define xf86ValidateModesSize XF86NAME(xf86ValidateModesSize) +#define xf86ValidateModesSync XF86NAME(xf86ValidateModesSync) +#define xf86ValidateModesUserConfig XF86NAME(xf86ValidateModesUserConfig) + +#endif /* _XF86RENAME_H_ */ diff --git a/src/radeon_xf86Rotate.c b/src/radeon_xf86Rotate.c new file mode 100644 index 0000000..102b508 --- /dev/null +++ b/src/radeon_xf86Rotate.c @@ -0,0 +1,401 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stddef.h> +#include <string.h> +#include <stdio.h> + +#include "xf86.h" +#include "xf86DDC.h" +/*#include "i830.h" */ +#include "radeon_xf86Crtc.h" +#include "radeon_xf86Modes.h" +//#include "i830_randr.h" +#include "X11/extensions/render.h" +#define DPMS_SERVER +#include "X11/extensions/dpms.h" +#include "X11/Xatom.h" + +static int +mode_height (DisplayModePtr mode, Rotation rotation) +{ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_180: + return mode->VDisplay; + case RR_Rotate_90: + case RR_Rotate_270: + return mode->HDisplay; + default: + return 0; + } +} + +static int +mode_width (DisplayModePtr mode, Rotation rotation) +{ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_180: + return mode->HDisplay; + case RR_Rotate_90: + case RR_Rotate_270: + return mode->VDisplay; + default: + return 0; + } +} + +/* borrowed from composite extension, move to Render and publish? */ + +static VisualPtr +compGetWindowVisual (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + VisualID vid = wVisual (pWin); + int i; + + for (i = 0; i < pScreen->numVisuals; i++) + if (pScreen->visuals[i].vid == vid) + return &pScreen->visuals[i]; + return 0; +} + +static PictFormatPtr +compWindowFormat (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + return PictureMatchVisual (pScreen, pWin->drawable.depth, + compGetWindowVisual (pWin)); +} + +static void +xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation, + int dest_width, int dest_height) +{ + switch (rotation & 0xf) { + default: + case RR_Rotate_0: + *dst = *src; + break; + case RR_Rotate_90: + dst->x1 = src->y1; + dst->y1 = dest_height - src->x2; + dst->x2 = src->y2; + dst->y2 = dest_height - src->x1; + break; + case RR_Rotate_180: + dst->x1 = dest_width - src->x2; + dst->y1 = dest_height - src->y2; + dst->x2 = dest_width - src->x1; + dst->y2 = dest_height - src->y1; + break; + case RR_Rotate_270: + dst->x1 = dest_width - src->y2; + dst->y1 = src->x1; + dst->y2 = src->x2; + dst->x2 = dest_width - src->y1; + break; + } + if (rotation & RR_Reflect_X) { + int x1 = dst->x1; + dst->x1 = dest_width - dst->x2; + dst->x2 = dest_width - x1; + } + if (rotation & RR_Reflect_Y) { + int y1 = dst->y1; + dst->y1 = dest_height - dst->y2; + dst->y2 = dest_height - y1; + } +} + +static void +xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) +{ + ScrnInfoPtr scrn = crtc->scrn; + ScreenPtr screen = scrn->pScreen; + WindowPtr root = WindowTable[screen->myNum]; + PixmapPtr dst_pixmap = crtc->rotatedPixmap; + PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]); + int error; + PicturePtr src, dst; + PictTransform transform; + int n = REGION_NUM_RECTS(region); + BoxPtr b = REGION_RECTS(region); + XID include_inferiors = IncludeInferiors; + + src = CreatePicture (None, + &root->drawable, + format, + CPSubwindowMode, + &include_inferiors, + serverClient, + &error); + if (!src) { + ErrorF("couldn't create src pict\n"); + return; + } + dst = CreatePicture (None, + &dst_pixmap->drawable, + format, + 0L, + NULL, + serverClient, + &error); + if (!dst) { + ErrorF("couldn't create src pict\n"); + return; + } + + memset (&transform, '\0', sizeof (transform)); + transform.matrix[2][2] = IntToxFixed(1); + transform.matrix[0][2] = IntToxFixed(crtc->x); + transform.matrix[1][2] = IntToxFixed(crtc->y); + switch (crtc->rotation & 0xf) { + default: + case RR_Rotate_0: + transform.matrix[0][0] = IntToxFixed(1); + transform.matrix[1][1] = IntToxFixed(1); + break; + case RR_Rotate_90: + transform.matrix[0][1] = IntToxFixed(-1); + transform.matrix[1][0] = IntToxFixed(1); + transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay); + break; + case RR_Rotate_180: + transform.matrix[0][0] = IntToxFixed(-1); + transform.matrix[1][1] = IntToxFixed(-1); + transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay); + transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay); + break; + case RR_Rotate_270: + transform.matrix[0][1] = IntToxFixed(1); + transform.matrix[1][0] = IntToxFixed(-1); + transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay); + break; + } + + /* handle reflection */ + if (crtc->rotation & RR_Reflect_X) + { + /* XXX figure this out */ + } + if (crtc->rotation & RR_Reflect_Y) + { + /* XXX figure this out too */ + } + + error = SetPictureTransform (src, &transform); + if (error) { + ErrorF("Couldn't set transform\n"); + return; + } + + while (n--) + { + BoxRec dst_box; + + xf86RotateBox (&dst_box, b, crtc->rotation, + crtc->mode.HDisplay, crtc->mode.VDisplay); + CompositePicture (PictOpSrc, + src, NULL, dst, + dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1, + dst_box.x2 - dst_box.x1, + dst_box.y2 - dst_box.y1); + b++; + } + FreePicture (src, None); + FreePicture (dst, None); +} + +static void +xf86RotateRedisplay(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + DamagePtr damage = xf86_config->rotationDamage; + RegionPtr region; + + if (!damage) + return; + region = DamageRegion(damage); + if (REGION_NOTEMPTY(pScreen, region)) + { + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + + if (crtc->rotation != RR_Rotate_0) + { + BoxRec box; + RegionRec crtc_damage; + + /* compute portion of damage that overlaps crtc */ + box.x1 = crtc->x; + box.x2 = crtc->x + mode_width (&crtc->mode, crtc->rotation); + box.y1 = crtc->y; + box.y2 = crtc->y + mode_height (&crtc->mode, crtc->rotation); + REGION_INIT(pScreen, &crtc_damage, &box, 1); + REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region); + + /* update damaged region */ + if (REGION_NOTEMPTY(pScreen, &crtc_damage)) + xf86RotateCrtcRedisplay (crtc, &crtc_damage); + + REGION_UNINIT (pScreen, &crtc_damage); + } + } + DamageEmpty(damage); + } +} + +static void +xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead) +{ + ScreenPtr pScreen = (ScreenPtr) data; + + xf86RotateRedisplay(pScreen); +} + +static void +xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask) +{ +} + +Bool +xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + + if (rotation == RR_Rotate_0) + { + /* Free memory from rotation */ + if (crtc->rotatedPixmap) + { + crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap); + crtc->rotatedPixmap = NULL; + } + + if (xf86_config->rotationDamage) + { + /* Free damage structure */ + DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + xf86_config->rotationDamage); + DamageDestroy (xf86_config->rotationDamage); + xf86_config->rotationDamage = NULL; + /* Free block/wakeup handler */ + RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler, + xf86RotateWakeupHandler, + (pointer) pScreen); + } + } + else + { + /* + * these are the size of the shadow pixmap, which + * matches the mode, not the pre-rotated copy in the + * frame buffer + */ + int width = mode->HDisplay; + int height = mode->VDisplay; + PixmapPtr shadow = crtc->rotatedPixmap; + int old_width = shadow ? shadow->drawable.width : 0; + int old_height = shadow ? shadow->drawable.height : 0; + BoxRec damage_box; + RegionRec damage_region; + + /* Allocate memory for rotation */ + if (old_width != width || old_height != height) + { + if (shadow) + { + crtc->funcs->shadow_destroy (crtc, shadow); + crtc->rotatedPixmap = NULL; + } + shadow = crtc->funcs->shadow_create (crtc, width, height); + if (!shadow) + goto bail1; + crtc->rotatedPixmap = shadow; + } + + if (!xf86_config->rotationDamage) + { + /* Create damage structure */ + xf86_config->rotationDamage = DamageCreate (NULL, NULL, + DamageReportNone, + TRUE, pScreen, pScreen); + if (!xf86_config->rotationDamage) + goto bail2; + + /* Hook damage to screen pixmap */ + DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + xf86_config->rotationDamage); + + /* Assign block/wakeup handler */ + if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler, + xf86RotateWakeupHandler, + (pointer) pScreen)) + { + goto bail3; + } + damage_box.x1 = 0; + damage_box.y1 = 0; + damage_box.x2 = mode_width (mode, rotation); + damage_box.y2 = mode_height (mode, rotation); + REGION_INIT (pScreen, &damage_region, &damage_box, 1); + DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + &damage_region); + REGION_UNINIT (pScreen, &damage_region); + } + if (0) + { +bail3: + DamageDestroy (xf86_config->rotationDamage); + xf86_config->rotationDamage = NULL; + +bail2: + if (shadow) + { + crtc->funcs->shadow_destroy (crtc, shadow); + crtc->rotatedPixmap = NULL; + } +bail1: + if (old_width && old_height) + crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, + old_width, + old_height); + return FALSE; + } + } + + /* All done */ + return TRUE; +} |