📄 radeon_mergedfb.c
字号:
MBXNR2XMAX = info->MBXNR2XMAX; MBXNR2YMAX = info->MBXNR2YMAX; } BOUND(x, 0, pScrn1->virtualX - HTotal); BOUND(y, 0, pScrn1->virtualY - VTotal); if(SDMPTR(pScrn1)->CRT2Position != radeonClone) {#if 0 BOUND(x1, info->CRT1XOffs, pScrn1->virtualX - HTotal - info->CRT2XOffs); BOUND(y1, info->CRT1YOffs, pScrn1->virtualY - VTotal - info->CRT2YOffs); BOUND(x2, info->CRT2XOffs, pScrn1->virtualX - HTotal - info->CRT1XOffs); BOUND(y2, info->CRT2YOffs, pScrn1->virtualY - VTotal - info->CRT1YOffs);#endif BOUND(x1, CRT1XOffs, min(HVirt, MBXNR1XMAX + CRT1XOffs) - min(HTotal, MBXNR1XMAX) - CRT2XOffs); BOUND(y1, CRT1YOffs, min(VVirt, MBXNR1YMAX + CRT1YOffs) - min(VTotal, MBXNR1YMAX) - CRT2YOffs); BOUND(x2, CRT2XOffs, min(HVirt, MBXNR2XMAX + CRT2XOffs) - min(HTotal, MBXNR2XMAX) - CRT1XOffs); BOUND(y2, CRT2YOffs, min(VVirt, MBXNR2YMAX + CRT2YOffs) - min(VTotal, MBXNR2YMAX) - CRT1YOffs); } switch(SDMPTR(pScrn1)->CRT2Position) { case radeonLeftOf: pScrn2->frameX0 = x2; /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/ BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay); info->CRT1frameX0 = x1 + CDMPTR->CRT2->HDisplay; /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/ BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay); break; case radeonRightOf: info->CRT1frameX0 = x1; /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/ BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay); pScrn2->frameX0 = x2 + CDMPTR->CRT1->HDisplay; /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/ BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay); break; case radeonAbove: /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/ BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay); pScrn2->frameY0 = y2; /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/ BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay); info->CRT1frameY0 = y1 + CDMPTR->CRT2->VDisplay; break; case radeonBelow: /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/ BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay); info->CRT1frameY0 = y1; /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/ BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay); pScrn2->frameY0 = y2 + CDMPTR->CRT1->VDisplay; break; case radeonClone: BOUND(info->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); BOUND(info->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); break; } BOUND(info->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay); BOUND(info->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay); BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay); BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay); pScrn1->frameX0 = x; pScrn1->frameY0 = y; info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1; info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1; pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1; pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1; pScrn1->frameX1 = pScrn1->frameX0 + info->CurrentLayout.mode->HDisplay - 1; pScrn1->frameY1 = pScrn1->frameY0 + info->CurrentLayout.mode->VDisplay - 1; if(SDMPTR(pScrn1)->CRT2Position != radeonClone) { pScrn1->frameX1 += CRT1XOffs + CRT2XOffs; pScrn1->frameY1 += CRT1YOffs + CRT2YOffs; }/* RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE); RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);*/}voidRADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags){ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; RADEONInfoPtr info = RADEONPTR(pScrn1); ScrnInfoPtr pScrn2 = info->CRT2pScrn; RADEONAdjustFrameMergedHelper(scrnIndex, x, y, flags); RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE); RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);}static voidRADEONMergedFBCalcDPI(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel, Bool quiet){ RADEONInfoPtr info = RADEONPTR(pScrn1); MessageType from = X_DEFAULT; xf86MonPtr DDC1 = (xf86MonPtr)(pScrn1->monitor->DDC); xf86MonPtr DDC2 = (xf86MonPtr)(pScrn2->monitor->DDC); int ddcWidthmm = 0, ddcHeightmm = 0; const char *dsstr = "MergedFB: Display dimensions: %dx%d mm\n"; /* This sets the DPI for MergedFB mode. The problem is that * this can never be exact, because the output devices may * have different dimensions. This function tries to compromise * through a few assumptions, and it just calculates an average * DPI value for both monitors. */ /* Copy user-given DisplaySize (which should regard BOTH monitors!) */ pScrn1->widthmm = pScrn1->monitor->widthmm; pScrn1->heightmm = pScrn1->monitor->heightmm; if(monitorResolution > 0) { /* Set command line given values (overrules given options) */ pScrn1->xDpi = monitorResolution; pScrn1->yDpi = monitorResolution; from = X_CMDLINE; } else if(info->MergedFBXDPI) { /* Set option-wise given values (overrules DisplaySize config option) */ pScrn1->xDpi = info->MergedFBXDPI; pScrn1->yDpi = info->MergedFBYDPI; from = X_CONFIG; } else if(pScrn1->widthmm > 0 || pScrn1->heightmm > 0) { /* Set values calculated from given DisplaySize */ from = X_CONFIG; if(pScrn1->widthmm > 0) { pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm); } if(pScrn1->heightmm > 0) { pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm); } if(!quiet) { xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, pScrn1->heightmm); } } else if(ddcWidthmm && ddcHeightmm) { /* Set values from DDC-provided display size */ /* Get DDC display size; if only either CRT1 or CRT2 provided these, * assume equal dimensions for both, otherwise add dimensions */ if( (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) && (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) ) { ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10; ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10; switch(srel) { case radeonLeftOf: case radeonRightOf: ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10; break; case radeonAbove: case radeonBelow: ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10; default: break; } } else if(DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) { ddcWidthmm = DDC1->features.hsize * 10; ddcHeightmm = DDC1->features.vsize * 10; switch(srel) { case radeonLeftOf: case radeonRightOf: ddcWidthmm *= 2; break; case radeonAbove: case radeonBelow: ddcHeightmm *= 2; default: break; } } else if(DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0) ) { ddcWidthmm = DDC2->features.hsize * 10; ddcHeightmm = DDC2->features.vsize * 10; switch(srel) { case radeonLeftOf: case radeonRightOf: ddcWidthmm *= 2; break; case radeonAbove: case radeonBelow: ddcHeightmm *= 2; default: break; } } from = X_PROBED; if(!quiet) { xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm); } pScrn1->widthmm = ddcWidthmm; pScrn1->heightmm = ddcHeightmm; if(pScrn1->widthmm > 0) { pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm); } if(pScrn1->heightmm > 0) { pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm); } } else { pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI; } /* Sanity check */ if(pScrn1->xDpi > 0 && pScrn1->yDpi <= 0) pScrn1->yDpi = pScrn1->xDpi; if(pScrn1->yDpi > 0 && pScrn1->xDpi <= 0) pScrn1->xDpi = pScrn1->yDpi; pScrn2->xDpi = pScrn1->xDpi; pScrn2->yDpi = pScrn1->yDpi; if(!quiet) { xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n", pScrn1->xDpi, pScrn1->yDpi); }}voidRADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel){ RADEONInfoPtr info = RADEONPTR(pScrn1); RADEONMergedFBCalcDPI(pScrn1, pScrn2, srel, FALSE); info->MergedDPISRel = srel; info->RADEONMergedDPIVX = pScrn1->virtualX; info->RADEONMergedDPIVY = pScrn1->virtualY;}voidRADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force){ RADEONInfoPtr info = RADEONPTR(pScrn); ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; /* This does the same calculation for the DPI as * the initial run. This means that an eventually * given -dpi command line switch will lead to * constant dpi values, regardless of the virtual * screen size. * I consider this consequent. If this is undesired, * one should use the DisplaySize parameter in the * config file instead of the command line switch. * The DPI will be calculated then. */ if(force || (info->MergedDPISRel != srel) || (info->RADEONMergedDPIVX != pScrn->virtualX) || (info->RADEONMergedDPIVY != pScrn->virtualY) ) { RADEONMergedFBCalcDPI(pScrn, info->CRT2pScrn, srel, TRUE); pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10); pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10); info->MergedDPISRel = srel; info->RADEONMergedDPIVX = pScrn->virtualX; info->RADEONMergedDPIVY = pScrn->virtualY; }}/* radeon cursor helpers */static voidRADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y){ RADEONInfoPtr info = RADEONPTR(pScrn1); unsigned char *RADEONMMIO = info->MMIO; RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; ScrnInfoPtr pScrn2 = info->CRT2pScrn; if (srel == radeonClone) { /* show cursor 2 */ OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, ~RADEON_CRTC2_CUR_EN); /* show cursor 1 */ OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, ~RADEON_CRTC_CUR_EN); } else { if (((x >= pScrn1->frameX0) && (x <= pScrn1->frameX1)) && ((y >= pScrn1->frameY0) && (y <= pScrn1->frameY1))) { /* hide cursor 2 */ OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); /* show cursor 1 */ OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, ~RADEON_CRTC_CUR_EN); } if (((x >= pScrn2->frameX0) && (x <= pScrn2->frameX1)) && ((y >= pScrn2->frameY0) && (y <= pScrn2->frameY1))) { /* hide cursor 1 */ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); /* show cursor 2 */ OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, ~RADEON_CRTC2_CUR_EN); } }}voidRADEONSetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y){ RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; xf86CursorInfoPtr cursor = info->cursor; int xorigin = 0; int yorigin = 0; int stride = 256; ScrnInfoPtr pScrn2 = info->CRT2pScrn; DisplayModePtr mode1 = CDMPTR->CRT1; DisplayModePtr mode2 = CDMPTR->CRT2; int x1, y1, x2, y2; int total_y1 = pScrn->frameY1 - pScrn->frameY0; int total_y2 = pScrn2->frameY1 - pScrn2->frameY0; if (x < 0) xorigin = -x+1; if (y < 0) yorigin = -y+1; /* if (y > total_y) y = total_y; */ if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; x += pScrn->frameX0; y += pScrn->frameY0; x1 = x - info->CRT1frameX0; y1 = y - info->CRT1frameY0; x2 = x - pScrn2->frameX0; y2 = y - pScrn2->frameY0; if (y1 > total_y1) y1 = total_y1; if (y2 > total_y2) y2 = total_y2; if(mode1->Flags & V_INTERLACE) y1 /= 2; else if(mode1->Flags & V_DBLSCAN) y1 *= 2; if(mode2->Flags & V_INTERLACE) y2 /= 2; else if(mode2->Flags & V_DBLSCAN) y2 *= 2; if (x < 0) x = 0; if (y < 0) y = 0; RADEONChooseCursorCRTC(pScrn, x, y); /* cursor1 */ OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK | (xorigin << 16) | yorigin)); OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | ((xorigin ? 0 : x1) << 16) | (yorigin ? 0 : y1))); OUTREG(RADEON_CUR_OFFSET, info->cursor_offset + yorigin * stride); /* cursor2 */ OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK | (xorigin << 16) | yorigin)); OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK | ((xorigin ? 0 : x2) << 16) | (yorigin ? 0 : y2))); OUTREG(RADEON_CUR2_OFFSET, info->cursor_offset + yorigin * stride);}/* radeon Xv helpers *//* choose the crtc for the overlay for mergedfb based on the location of the output window and the orientation of the crtcs */voidRADEONChooseOverlayCRTC( ScrnInfoPtr pScrn, BoxPtr dstBox) { RADEONInfoPtr info = RADEONPTR(pScrn); RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position; if (srel == radeonLeftOf) { if (dstBox->x1 >= info->CRT2pScrn->frameX1) info->OverlayOnCRTC2 = FALSE; el
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -