📄 radeon_mergedfb.c
字号:
static DisplayModePtrRADEONGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str, DisplayModePtr i, DisplayModePtr j, RADEONScrn2Rel srel){ char* strmode = str; char modename[256]; Bool gotdash = FALSE; char gotsep = 0; RADEONScrn2Rel sr; DisplayModePtr mode1 = NULL; DisplayModePtr mode2 = NULL; DisplayModePtr result = NULL; int myslen; RADEONInfoPtr info = RADEONPTR(pScrn); info->AtLeastOneNonClone = FALSE; do { switch(*str) { case 0: case '-': case '+': case ' ': case ',': case ';': if(strmode != str) { myslen = str - strmode; if(myslen > 255) myslen = 255; strncpy(modename, strmode, myslen); modename[myslen] = 0; if(gotdash) { if(mode1 == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Error parsing MetaModes parameter\n"); return NULL; } mode2 = RADEONGetModeFromName(modename, j); if(!mode2) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode \"%s\" is not a supported mode for CRT2\n", modename); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename); mode1 = NULL; gotsep = 0; } } else { mode1 = RADEONGetModeFromName(modename, i); if(!mode1) { char* tmps = str; xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode \"%s\" is not a supported mode for CRT1\n", modename); while(*tmps == ' ' || *tmps == ';') tmps++; /* skip the next mode */ if(*tmps == '-' || *tmps == '+' || *tmps == ',') { tmps++; /* skip spaces */ while(*tmps == ' ' || *tmps == ';') tmps++; /* skip modename */ while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++; myslen = tmps - strmode; if(myslen > 255) myslen = 255; strncpy(modename,strmode,myslen); modename[myslen] = 0; str = tmps-1; } xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "\t(Skipping metamode \"%s\")\n", modename); mode1 = NULL; gotsep = 0; } } gotdash = FALSE; } strmode = str + 1; gotdash |= (*str == '-' || *str == '+' || *str == ','); if (*str == '-' || *str == '+' || *str == ',') gotsep = *str; if(*str != 0) break; /* Fall through otherwise */ default: if(!gotdash && mode1) { sr = srel; if(gotsep == '+') sr = radeonClone; if(!mode2) { mode2 = RADEONGetModeFromName(mode1->name, j); sr = radeonClone; } if(!mode2) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode \"%s\" is not a supported mode for CRT2\n", mode1->name); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "\t(Skipping metamode \"%s\")\n", modename); mode1 = NULL; } else { result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, sr); mode1 = NULL; mode2 = NULL; } gotsep = 0; } break; } } while(*(str++) != 0); return result;}DisplayModePtrRADEONGenerateModeList(ScrnInfoPtr pScrn, char* str, DisplayModePtr i, DisplayModePtr j, RADEONScrn2Rel srel){ RADEONInfoPtr info = RADEONPTR(pScrn); if(str != NULL) { return(RADEONGenerateModeListFromMetaModes(pScrn, str, i, j, srel)); } else { if (srel == radeonClone ) { DisplayModePtr p, q, result = NULL; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clone mode, list all common modes\n"); for (p = i; p->next != i; p = p->next) for (q = j; q->next != j; q = q->next) if ((p->HDisplay == q->HDisplay) && (p->VDisplay == q->VDisplay)) result = RADEONCopyModeNLink(pScrn, result, p, q, srel); return result; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No MetaModes given, linking %s modes by default\n", (info->NonRect ? (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest" : "tallest") : (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest common" : "tallest common")) ); return(RADEONGenerateModeListFromLargestModes(pScrn, i, j, srel)); } }}voidRADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn){ RADEONInfoPtr info = RADEONPTR(pScrn); DisplayModePtr mode, bmode; int maxh, maxv; static const char *str = "MergedFB: Virtual %s %d\n"; static const char *errstr = "Virtual %s to small for given CRT2Position offset\n"; mode = bmode = pScrn->modes; maxh = maxv = 0; do { if(mode->HDisplay > maxh) maxh = mode->HDisplay; if(mode->VDisplay > maxv) maxv = mode->VDisplay; mode = mode->next; } while(mode != bmode); maxh += info->CRT1XOffs + info->CRT2XOffs; maxv += info->CRT1YOffs + info->CRT2YOffs; if(!(pScrn->display->virtualX)) { if(maxh > 8191) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Virtual width with CRT2Position offset beyond hardware specs\n"); info->CRT1XOffs = info->CRT2XOffs = 0; maxh -= (info->CRT1XOffs + info->CRT2XOffs); } pScrn->virtualX = maxh; pScrn->displayWidth = maxh; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh); } else { if(maxh < pScrn->display->virtualX) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width"); info->CRT1XOffs = info->CRT2XOffs = 0; } } if(!(pScrn->display->virtualY)) { pScrn->virtualY = maxv; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv); } else { if(maxv < pScrn->display->virtualY) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height"); info->CRT1YOffs = info->CRT2YOffs = 0; } }}/* Pseudo-Xinerama extension for MergedFB mode */voidRADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1){ RADEONInfoPtr info = RADEONPTR(pScrn1); ScrnInfoPtr pScrn2 = NULL; int crt1scrnnum = 0, crt2scrnnum = 1; int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0; int realvirtX, realvirtY; DisplayModePtr currentMode, firstMode; Bool infochanged = FALSE; Bool usenonrect = info->NonRect; const char *rectxine = "\t... setting up rectangular Xinerama layout\n"; info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536; info->HaveNonRect = info->HaveOffsRegions = FALSE; if(!info->MergedFB) return; if(RADEONnoPanoramiXExtension) return; if(!RADEONXineramadataPtr) return; if(info->CRT2IsScrn0) { crt1scrnnum = 1; crt2scrnnum = 0; } pScrn2 = info->CRT2pScrn; /* Attention: Usage of RandR may lead into virtual X and Y values * actually smaller than our MetaModes! To avoid this, we calculate * the maxCRT fields here (and not somewhere else, like in CopyNLink) */ /* "Real" virtual: Virtual without the Offset */ realvirtX = pScrn1->virtualX - info->CRT1XOffs - info->CRT2XOffs; realvirtY = pScrn1->virtualY - info->CRT1YOffs - info->CRT2YOffs; if((info->RADEONXineramaVX != pScrn1->virtualX) || (info->RADEONXineramaVY != pScrn1->virtualY)) { if(!(pScrn1->modes)) { xf86DrvMsg(pScrn1->scrnIndex, X_ERROR, "Internal error: RADEONUpdateXineramaScreenInfo(): pScrn->modes is NULL\n"); return; } info->maxCRT1_X1 = info->maxCRT1_X2 = 0; info->maxCRT1_Y1 = info->maxCRT1_Y2 = 0; info->maxCRT2_X1 = info->maxCRT2_X2 = 0; info->maxCRT2_Y1 = info->maxCRT2_Y2 = 0; info->maxClone_X1 = info->maxClone_X2 = 0; info->maxClone_Y1 = info->maxClone_Y2 = 0; currentMode = firstMode = pScrn1->modes; do { DisplayModePtr p = currentMode->next; DisplayModePtr i = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT1; DisplayModePtr j = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2; RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2Position; if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) && (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) && (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) { if(srel != radeonClone) { if(info->maxCRT1_X1 == i->HDisplay) { if(info->maxCRT1_X2 < j->HDisplay) { info->maxCRT1_X2 = j->HDisplay; /* Widest CRT2 mode displayed with widest CRT1 mode */ } } else if(info->maxCRT1_X1 < i->HDisplay) { info->maxCRT1_X1 = i->HDisplay; /* Widest CRT1 mode */ info->maxCRT1_X2 = j->HDisplay; } if(info->maxCRT2_X2 == j->HDisplay) { if(info->maxCRT2_X1 < i->HDisplay) { info->maxCRT2_X1 = i->HDisplay; /* Widest CRT1 mode displayed with widest CRT2 mode */ } } else if(info->maxCRT2_X2 < j->HDisplay) { info->maxCRT2_X2 = j->HDisplay; /* Widest CRT2 mode */ info->maxCRT2_X1 = i->HDisplay; } if(info->maxCRT1_Y1 == i->VDisplay) { /* Same as above, but tallest instead of widest */ if(info->maxCRT1_Y2 < j->VDisplay) { info->maxCRT1_Y2 = j->VDisplay; } } else if(info->maxCRT1_Y1 < i->VDisplay) { info->maxCRT1_Y1 = i->VDisplay; info->maxCRT1_Y2 = j->VDisplay; } if(info->maxCRT2_Y2 == j->VDisplay) { if(info->maxCRT2_Y1 < i->VDisplay) { info->maxCRT2_Y1 = i->VDisplay; } } else if(info->maxCRT2_Y2 < j->VDisplay) { info->maxCRT2_Y2 = j->VDisplay; info->maxCRT2_Y1 = i->VDisplay; } } else { if(info->maxClone_X1 < i->HDisplay) { info->maxClone_X1 = i->HDisplay; } if(info->maxClone_X2 < j->HDisplay) { info->maxClone_X2 = j->HDisplay; } if(info->maxClone_Y1 < i->VDisplay) { info->maxClone_Y1 = i->VDisplay; } if(info->maxClone_Y2 < j->VDisplay) { info->maxClone_Y2 = j->VDisplay; } } } currentMode = p; } while((currentMode) && (currentMode != firstMode)); info->RADEONXineramaVX = pScrn1->virtualX; info->RADEONXineramaVY = pScrn1->virtualY; infochanged = TRUE; } if((usenonrect) && (info->CRT2Position != radeonClone) && info->maxCRT1_X1) { switch(info->CRT2Position) { case radeonLeftOf: case radeonRightOf: if((info->maxCRT1_Y1 != realvirtY) && (info->maxCRT2_Y2 != realvirtY)) { usenonrect = FALSE; } break; case radeonAbove: case radeonBelow: if((info->maxCRT1_X1 != realvirtX) && (info->maxCRT2_X2 != realvirtX)) { usenonrect = FALSE; } break; case radeonClone: break; } if(infochanged && !usenonrect) { xf86DrvMsg(pScrn1->scrnIndex, X_INFO, "Virtual screen size does not match maximum display modes...\n"); xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine); } } else if(infochanged && usenonrect) { usenonrect = FALSE; xf86DrvMsg(pScrn1->scrnIndex, X_INFO, "Only clone modes available for this virtual screen size...\n"); xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine); } if(info->maxCRT1_X1) { /* Means we have at least one non-clone mode */ switch(info->CRT2Position) { case radeonLeftOf: x1 = min(info->maxCRT1_X2, pScrn1->virtualX - info->maxCRT1_X1); if(x1 < 0) x1 = 0; y1 = info->CRT1YOffs; w1 = pScrn1->virtualX - x1; h1 = realvirtY; if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) { h1 = info->MBXNR1YMAX = info->maxCRT1_Y1; info->NonRectDead.x0 = x1; info->NonRectDead.x1 = x1 + w1 - 1; info->NonRectDead.y0 = y1 + h1; info->NonRectDead.y1 = pScrn1->virtualY - 1; info->HaveNonRect = TRUE; } x2 = 0; y2 = info->CRT2YOffs; w2 = max(info->maxCRT2_X2, pScrn1->virtualX - info->maxCRT2_X1); if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX; h2 = realvirtY; if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) { h2 = info->MBXNR2YMAX = info->maxCRT2_Y2; info->NonRectDead.x0 = x2; info->NonRectDead.x1 = x2 + w2 - 1; info->NonRectDead.y0 = y2 + h2; info->NonRectDead.y1 = pScrn1->virtualY - 1; info->HaveNonRect = TRUE; } break; case radeonRightOf: x1 = 0; y1 = info->CRT1YOffs; w1 = max(info->maxCRT1_X1, pScrn1->virtualX - info->maxCRT1_X2); if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX; h1 = realvirtY; if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) { h1 = info->MBXNR1YMAX = info->maxCRT1_Y1; info->NonRectDead.x0 = x1; info->NonRectDead.x1 = x1 + w1 - 1; info->NonRectDead.y0 = y1 + h1; info->NonRectDead.y1 = pScrn1->virtualY - 1; info->HaveNonRect = TRUE; } x2 = min(info->maxCRT2_X1, pScrn1->virtualX - info->maxCRT2_X2); if(x2 < 0) x2 = 0; y2 = info->CRT2YOffs; w2 = pScrn1->virtualX - x2; h2 = realvirtY; if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) { h2 = info->MBXNR2YMAX = info->maxCRT2_Y2; info->NonRectDead.x0 = x2; info->NonRectDead.x1 = x2 + w2 - 1; info->NonRectDead.y0 = y2 + h2; info->NonRectDead.y1 = pScrn1->virtualY - 1; info->HaveNonRect = TRUE; } break; case radeonAbove: x1 = info->CRT1XOffs; y1 = min(info->maxCRT1_Y2, pScrn1->virtualY - info->maxCRT1_Y1); if(y1 < 0) y1 = 0; w1 = realvirtX; h1 = pScrn1->virtualY - y1; if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -