diff options
Diffstat (limited to 'xorg-server/hw/xfree86/modes/xf86Crtc.c')
-rw-r--r-- | xorg-server/hw/xfree86/modes/xf86Crtc.c | 516 |
1 files changed, 388 insertions, 128 deletions
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index 1facf86e9..84d3cac3e 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -96,6 +96,7 @@ xf86CrtcCreate (ScrnInfoPtr scrn, crtc = xcalloc (sizeof (xf86CrtcRec), 1); if (!crtc) return NULL; + crtc->version = XF86_CRTC_VERSION; crtc->scrn = scrn; crtc->funcs = funcs; #ifdef RANDR_12_INTERFACE @@ -103,6 +104,19 @@ xf86CrtcCreate (ScrnInfoPtr scrn, #endif crtc->rotation = RR_Rotate_0; crtc->desiredRotation = RR_Rotate_0; + pixman_transform_init_identity (&crtc->crtc_to_framebuffer); + pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer); + pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc); + crtc->filter = NULL; + crtc->params = NULL; + crtc->nparams = 0; + crtc->filter_width = 0; + crtc->filter_height = 0; + crtc->transform_in_use = FALSE; + crtc->transformPresent = FALSE; + crtc->desiredTransformPresent = FALSE; + memset (&crtc->bounds, '\0', sizeof (crtc->bounds)); + if (xf86_config->crtc) crtcs = xrealloc (xf86_config->crtc, (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr)); @@ -134,6 +148,8 @@ xf86CrtcDestroy (xf86CrtcPtr crtc) xf86_config->num_crtc--; break; } + if (crtc->params) + xfree (crtc->params); xfree (crtc); } @@ -224,8 +240,8 @@ xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen) * Sets the given video mode on the given crtc */ _X_EXPORT Bool -xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, - int x, int y) +xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + RRTransformPtr transform, int x, int y) { ScrnInfoPtr scrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -236,12 +252,14 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, DisplayModeRec saved_mode; int saved_x, saved_y; Rotation saved_rotation; + RRTransformRec saved_transform; + Bool saved_transform_present; if (crtc->funcs->set_mode_major) return crtc->funcs->set_mode_major(crtc, mode, rotation, x, y); - + crtc->enabled = xf86CrtcInUse (crtc); - + if (!crtc->enabled) { /* XXX disable crtc? */ @@ -256,6 +274,12 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, saved_x = crtc->x; saved_y = crtc->y; saved_rotation = crtc->rotation; + if (crtc->transformPresent) { + RRTransformInit (&saved_transform); + RRTransformCopy (&saved_transform, &crtc->transform); + } + saved_transform_present = crtc->transformPresent; + /* Update crtc values up front so the driver can rely on them for mode * setting. */ @@ -263,33 +287,25 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, crtc->x = x; crtc->y = y; crtc->rotation = rotation; + if (transform) { + RRTransformCopy (&crtc->transform, transform); + crtc->transformPresent = TRUE; + } else + crtc->transformPresent = FALSE; - /* Shift offsets that move us out of virtual size */ - if (x + mode->HDisplay > xf86_config->maxWidth || - y + mode->VDisplay > xf86_config->maxHeight) + if (crtc->funcs->set_origin && + memcmp (mode, &saved_mode, sizeof(saved_mode)) == 0 && + saved_rotation == rotation && + saved_transform_present == crtc->transformPresent && + (!crtc->transformPresent || RRTransformEqual(&saved_transform, &crtc->transform))) { - if (x + mode->HDisplay > xf86_config->maxWidth) - crtc->x = xf86_config->maxWidth - mode->HDisplay; - if (y + mode->VDisplay > xf86_config->maxHeight) - crtc->y = xf86_config->maxHeight - mode->VDisplay; - if (crtc->x < 0 || crtc->y < 0) - { - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Mode %dx%d does not fit virtual size %dx%d - " - "internal error\n", mode->HDisplay, mode->VDisplay, - xf86_config->maxWidth, xf86_config->maxHeight); - goto done; - } - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Mode %dx%d+%d+%d does not fit virtual size %dx%d - " - "offset updated to +%d+%d\n", - mode->HDisplay, mode->VDisplay, x, y, - xf86_config->maxWidth, xf86_config->maxHeight, - crtc->x, crtc->y); + if (!xf86CrtcRotate (crtc)) + goto done; + crtc->funcs->set_origin (crtc, crtc->x, crtc->y); + ret = TRUE; + goto done; } - /* 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. @@ -309,9 +325,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, goto done; } - if (!xf86CrtcRotate (crtc, mode, rotation)) { + if (!xf86CrtcRotate (crtc)) goto done; - } /* Prepare the outputs and CRTCs before setting the mode. */ for (i = 0; i < xf86_config->num_output; i++) { @@ -343,13 +358,7 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, { xf86OutputPtr output = xf86_config->output[i]; if (output->crtc == crtc) - { output->funcs->commit(output); -#ifdef RANDR_12_INTERFACE - if (output->randr_output) - RRPostPendingProperties (output->randr_output); -#endif - } } /* XXX free adjustedmode */ @@ -363,6 +372,9 @@ done: crtc->y = saved_y; crtc->rotation = saved_rotation; crtc->mode = saved_mode; + if (saved_transform_present) + RRTransformCopy (&crtc->transform, &saved_transform); + crtc->transformPresent = saved_transform_present; } if (didLock) @@ -371,6 +383,34 @@ done: return ret; } +/** + * Sets the given video mode on the given crtc, but without providing + * a transform + */ +_X_EXPORT Bool +xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y) +{ + return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y); +} + +/** + * Pans the screen, does not change the mode + */ +_X_EXPORT void +xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y) +{ + crtc->x = x; + crtc->y = y; + if (crtc->funcs->set_origin) { + if (!xf86CrtcRotate (crtc)) + return; + crtc->funcs->set_origin (crtc, x, y); + } + else + xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y); +} + /* * Output functions */ @@ -390,6 +430,7 @@ typedef enum { OPTION_MAX_CLOCK, OPTION_IGNORE, OPTION_ROTATE, + OPTION_PANNING, } OutputOpts; static OptionInfoRec xf86OutputOptions[] = { @@ -405,6 +446,7 @@ static OptionInfoRec xf86OutputOptions[] = { {OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE }, {OPTION_IGNORE, "Ignore", OPTV_BOOLEAN, {0}, FALSE }, {OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE }, + {OPTION_PANNING, "Panning", OPTV_STRING, {0}, FALSE }, {-1, NULL, OPTV_NONE, {0}, FALSE }, }; @@ -694,7 +736,12 @@ xf86CrtcCloseScreen (int index, ScreenPtr screen) /* * Called at ScreenInit time to set up */ -_X_EXPORT Bool +_X_EXPORT +#ifdef RANDR_13_INTERFACE +int +#else +Bool +#endif xf86CrtcScreenInit (ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; @@ -714,11 +761,17 @@ xf86CrtcScreenInit (ScreenPtr screen) break; } if (c == config->num_crtc) + { xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270 | RR_Reflect_X | RR_Reflect_Y); + xf86RandR12SetTransformSupport (screen, TRUE); + } else + { xf86RandR12SetRotations (screen, RR_Rotate_0); + xf86RandR12SetTransformSupport (screen, FALSE); + } /* Wrap CreateScreenResources so we can initialize the RandR code */ config->CreateScreenResources = screen->CreateScreenResources; @@ -727,7 +780,11 @@ xf86CrtcScreenInit (ScreenPtr screen) config->CloseScreen = screen->CloseScreen; screen->CloseScreen = xf86CrtcCloseScreen; +#ifdef RANDR_13_INTERFACE + return RANDR_INTERFACE_VERSION; +#else return TRUE; +#endif } static DisplayModePtr @@ -905,7 +962,7 @@ xf86PickCrtcs (ScrnInfoPtr scrn, * see if they can be cloned */ if (xf86ModesEqual (modes[o], modes[n]) && - config->output[0]->initial_rotation == config->output[n]->initial_rotation && + config->output[o]->initial_rotation == config->output[n]->initial_rotation && config->output[o]->initial_x == config->output[n]->initial_x && config->output[o]->initial_y == config->output[n]->initial_y) { @@ -1176,10 +1233,12 @@ xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes) output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation); break; case OPTION_ABOVE: - output->initial_y -= xf86ModeHeight (modes[o], relative->initial_rotation); + if (modes[o]) + output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation); break; case OPTION_LEFT_OF: - output->initial_x -= xf86ModeWidth (modes[o], relative->initial_rotation); + if (modes[o]) + output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation); break; default: break; @@ -1237,6 +1296,59 @@ xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes) return TRUE; } +static void +xf86InitialPanning (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + char *panning = xf86GetOptValString (output->options, OPTION_PANNING); + int width, height, left, top; + int track_width, track_height, track_left, track_top; + int brdr[4]; + + memset (&output->initialTotalArea, 0, sizeof(BoxRec)); + memset (&output->initialTrackingArea, 0, sizeof(BoxRec)); + memset (output->initialBorder, 0, 4*sizeof(INT16)); + + if (! panning) + continue; + + switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d", + &width, &height, &left, &top, + &track_width, &track_height, &track_left, &track_top, + &brdr[0], &brdr[1], &brdr[2], &brdr[3])) { + case 12: + output->initialBorder[0] = brdr[0]; + output->initialBorder[1] = brdr[1]; + output->initialBorder[2] = brdr[2]; + output->initialBorder[3] = brdr[3]; + /* fall through */ + case 8: + output->initialTrackingArea.x1 = track_left; + output->initialTrackingArea.y1 = track_top; + output->initialTrackingArea.x2 = track_left + track_width; + output->initialTrackingArea.y2 = track_top + track_height; + /* fall through */ + case 4: + output->initialTotalArea.x1 = left; + output->initialTotalArea.y1 = top; + /* fall through */ + case 2: + output->initialTotalArea.x2 = output->initialTotalArea.x1 + width; + output->initialTotalArea.y2 = output->initialTotalArea.y1 + height; + break; + default: + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Broken panning specification '%s' for output %s in config file\n", + panning, output->name); + } + } +} + /* * XXX walk the monitor mode list and prune out duplicates that * are inserted by xf86DDCMonitorSet. In an ideal world, that @@ -1407,7 +1519,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) { xf86OutputPtr output = config->output[o]; DisplayModePtr mode; - DisplayModePtr config_modes = NULL, output_modes, default_modes; + DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL; char *preferred_mode; xf86MonPtr edid_monitor; XF86ConfMonitorPtr conf_monitor; @@ -1415,6 +1527,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) int min_clock = 0; int max_clock = 0; double clock; + Bool add_default_modes = TRUE; enum { sync_config, sync_edid, sync_default } sync_source = sync_default; while (output->probed_modes != NULL) @@ -1465,6 +1578,11 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) int i; Bool set_hsync = mon_rec.nHsync == 0; Bool set_vrefresh = mon_rec.nVrefresh == 0; + struct disp_features *features = &edid_monitor->features; + + /* if display is not continuous-frequency, don't add default modes */ + if (!GTF_SUPPORTED(features->msc)) + add_default_modes = FALSE; for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++) { @@ -1521,8 +1639,10 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) mon_rec.vrefresh[0].hi = 62.0; mon_rec.nVrefresh = 1; } - default_modes = xf86GetDefaultModes (output->interlaceAllowed, - output->doubleScanAllowed); + + if (add_default_modes) + default_modes = xf86GetDefaultModes (output->interlaceAllowed, + output->doubleScanAllowed); /* * If this is not an RB monitor, remove RB modes from the default @@ -1809,6 +1929,66 @@ nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index) } static Bool +aspectMatch(float a, float b) +{ + return fabs(1 - (a / b)) < 0.05; +} + +static DisplayModePtr +nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect) +{ + DisplayModePtr m = NULL; + + if (!o) + return NULL; + + if (!last) + m = o->probed_modes; + else + m = last->next; + + for (; m; m = m->next) + if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay)) + return m; + + return NULL; +} + +static DisplayModePtr +bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) +{ + int o = -1, p; + DisplayModePtr mode = NULL, test = NULL, match = NULL; + + if (!nextEnabledOutput(config, enabled, &o)) + return NULL; + while ((mode = nextAspectMode(config->output[o], mode, aspect))) { + test = mode; + for (p = o; nextEnabledOutput(config, enabled, &p); ) { + test = xf86OutputFindClosestMode(config->output[p], mode); + if (!test) + break; + if (test->HDisplay != mode->HDisplay || + test->VDisplay != mode->VDisplay) { + test = NULL; + break; + } + } + + /* if we didn't match it on all outputs, try the next one */ + if (!test) + continue; + + /* if it's bigger than the last one, save it */ + if (!match || (test->HDisplay > match->HDisplay)) + match = test; + } + + /* return the biggest one found */ + return match; +} + +static Bool xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, DisplayModePtr *modes, Bool *enabled, int width, int height) @@ -1860,75 +2040,43 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, } } - if (ret) { - /* oh good, there is a match. stash the selected modes and return. */ - memcpy(modes, preferred_match, - config->num_output * sizeof(DisplayModePtr)); - } - - xfree(preferred); - xfree(preferred_match); - return ret; -} - -static Bool -aspectMatch(float a, float b) -{ - return fabs(1 - (a / b)) < 0.05; -} - -static DisplayModePtr -nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect) -{ - DisplayModePtr m = NULL; - - if (!o) - return NULL; + /* + * If there's no preferred mode, but only one monitor, pick the + * biggest mode for its aspect ratio, assuming one exists. + */ + if (!ret) do { + int i = 0; + float aspect = 0.0; - if (!last) - m = o->probed_modes; - else - m = last->next; + /* count the number of enabled outputs */ + for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ; - for (; m; m = m->next) - if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay)) - return m; + if (i != 1) + break; - return NULL; -} + p = -1; + nextEnabledOutput(config, enabled, &p); + if (config->output[p]->mm_height) + aspect = (float)config->output[p]->mm_width / + (float)config->output[p]->mm_height; -static DisplayModePtr -bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) -{ - int o = -1, p; - DisplayModePtr mode = NULL, test = NULL, match = NULL; + if (aspect) + preferred_match[p] = bestModeForAspect(config, enabled, aspect); - if (!nextEnabledOutput(config, enabled, &o)) - return NULL; - while ((mode = nextAspectMode(config->output[o], mode, aspect))) { - test = mode; - for (p = o; nextEnabledOutput(config, enabled, &p); ) { - test = xf86OutputFindClosestMode(config->output[p], mode); - if (!test) - break; - if (test->HDisplay != mode->HDisplay || - test->VDisplay != mode->VDisplay) { - test = NULL; - break; - } - } + if (preferred_match[p]) + ret = TRUE; - /* if we didn't match it on all outputs, try the next one */ - if (!test) - continue; + } while (0); - /* if it's bigger than the last one, save it */ - if (!match || (test->HDisplay > match->HDisplay)) - match = test; + if (ret) { + /* oh good, there is a match. stash the selected modes and return. */ + memcpy(modes, preferred_match, + config->num_output * sizeof(DisplayModePtr)); } - /* return the biggest one found */ - return match; + xfree(preferred); + xfree(preferred_match); + return ret; } static Bool @@ -2127,6 +2275,11 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) xfree (modes); return FALSE; } + + /* + * Set initial panning of each output + */ + xf86InitialPanning (scrn); /* * Assign CRTCs to fit output configuration @@ -2166,9 +2319,13 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) crtc->desiredRotation = output->initial_rotation; crtc->desiredX = output->initial_x; crtc->desiredY = output->initial_y; + crtc->desiredTransformPresent = FALSE; crtc->enabled = TRUE; crtc->x = output->initial_x; crtc->y = output->initial_y; + memcpy (&crtc->panningTotalArea, &output->initialTotalArea, sizeof(BoxRec)); + memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec)); + memcpy (crtc->panningBorder, output->initialBorder, 4*sizeof(INT16)); output->crtc = crtc; } else { output->crtc = NULL; @@ -2217,6 +2374,68 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) } /* + * Check the CRTC we're going to map each output to vs. it's current + * CRTC. If they don't match, we have to disable the output and the CRTC + * since the driver will have to re-route things. + */ +static void +xf86PrepareOutputs (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr output = config->output[o]; +#if RANDR_GET_CRTC_INTERFACE + /* Disable outputs that are unused or will be re-routed */ + if (!output->funcs->get_crtc || + output->crtc != (*output->funcs->get_crtc)(output) || + output->crtc == NULL) +#endif + (*output->funcs->dpms)(output, DPMSModeOff); + } +} + +static void +xf86PrepareCrtcs (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < config->num_crtc; c++) { +#if RANDR_GET_CRTC_INTERFACE + xf86CrtcPtr crtc = config->crtc[c]; + xf86OutputPtr output = NULL; + uint32_t desired_outputs = 0, current_outputs = 0; + int o; + + for (o = 0; o < config->num_output; o++) { + output = config->output[o]; + if (output->crtc == crtc) + desired_outputs |= (1<<o); + /* If we can't tell where it's mapped, force it off */ + if (!output->funcs->get_crtc) { + desired_outputs = 0; + break; + } + if ((*output->funcs->get_crtc)(output) == crtc) + current_outputs |= (1<<o); + } + + /* + * If mappings are different or the CRTC is unused, + * we need to disable it + */ + if (desired_outputs != current_outputs || + !desired_outputs) + (*crtc->funcs->dpms)(crtc, DPMSModeOff); +#else + (*crtc->funcs->dpms)(crtc, DPMSModeOff); +#endif + } +} + +/* * Using the desired mode information in each crtc, set * modes (used in EnterVT functions, or at server startup) */ @@ -2225,31 +2444,22 @@ _X_EXPORT Bool xf86SetDesiredModes (ScrnInfoPtr scrn) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int c, o; + xf86CrtcPtr crtc = config->crtc[0]; + int c; - /* - * Turn off everything so mode setting is done - * with hardware in a consistent state - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - (*output->funcs->dpms)(output, DPMSModeOff); + /* A driver with this hook will take care of this */ + if (!crtc->funcs->set_mode_major) { + xf86PrepareOutputs(scrn); + xf86PrepareCrtcs(scrn); } - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - - crtc->funcs->dpms(crtc, DPMSModeOff); - memset(&crtc->mode, 0, sizeof(crtc->mode)); - } - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; xf86OutputPtr output = NULL; int o; + RRTransformPtr transform; + + crtc = config->crtc[c]; /* Skip disabled CRTCs */ if (!crtc->enabled) @@ -2280,12 +2490,17 @@ xf86SetDesiredModes (ScrnInfoPtr scrn) return FALSE; crtc->desiredMode = *mode; crtc->desiredRotation = RR_Rotate_0; + crtc->desiredTransformPresent = FALSE; crtc->desiredX = 0; crtc->desiredY = 0; } - if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, - crtc->desiredX, crtc->desiredY)) + if (crtc->desiredTransformPresent) + transform = &crtc->desiredTransform; + else + transform = NULL; + if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation, + transform, crtc->desiredX, crtc->desiredY)) return FALSE; } @@ -2414,18 +2629,19 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation) crtc->enabled = FALSE; continue; } - if (!xf86CrtcSetMode (crtc, crtc_mode, rotation, 0, 0)) + if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0)) ok = FALSE; else { crtc->desiredMode = *crtc_mode; crtc->desiredRotation = rotation; + crtc->desiredTransformPresent = FALSE; crtc->desiredX = 0; crtc->desiredY = 0; } } xf86DisableUnusedFunctions(pScrn); -#if RANDR_12_INTERFACE +#ifdef RANDR_12_INTERFACE xf86RandR12TellChanged (pScrn->pScreen); #endif return ok; @@ -2513,8 +2729,11 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) { crtc->funcs->dpms(crtc, DPMSModeOff); memset(&crtc->mode, 0, sizeof(crtc->mode)); + xf86RotateDestroy(crtc); } } + if (pScrn->pScreen) + xf86_crtc_notify(pScrn->pScreen); } #ifdef RANDR_12_INTERFACE @@ -2576,9 +2795,11 @@ xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) size = 0; if (edid_mon) { - if (edid_mon->ver.version == 1) + if (edid_mon->ver.version == 1) { size = 128; - else if (edid_mon->ver.version == 2) + if (edid_mon->flags & EDID_COMPLETE_RAWDATA) + size += edid_mon->no_sections * 128; + } else if (edid_mon->ver.version == 2) size = 256; } xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size); @@ -2623,15 +2844,16 @@ xf86OutputGetEDIDModes (xf86OutputPtr output) return xf86DDCGetModes(scrn->scrnIndex, edid_mon); } +/* maybe we should care about DDC1? meh. */ _X_EXPORT xf86MonPtr xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) { ScrnInfoPtr scrn = output->scrn; xf86MonPtr mon; - mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus); + mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE); if (mon) - xf86DDCApplyQuirks (scrn->scrnIndex, mon); + xf86DDCApplyQuirks(scrn->scrnIndex, mon); return mon; } @@ -2766,3 +2988,41 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn, return ret; } + +xf86_crtc_notify_proc_ptr +xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new) +{ + if (xf86CrtcConfigPrivateIndex != -1) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + xf86_crtc_notify_proc_ptr old; + + old = config->xf86_crtc_notify; + config->xf86_crtc_notify = new; + return old; + } + return NULL; +} + +void +xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old) +{ + if (xf86CrtcConfigPrivateIndex != -1) + { + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + + config->xf86_crtc_notify = old; + } +} + +void +xf86_crtc_notify(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + + if (config->xf86_crtc_notify) + config->xf86_crtc_notify(screen); +} |