📄 xf86edidmodes.c
字号:
/* We ignore h/v_size and h/v_border for now. */ if (timing->interlaced) Mode->Flags |= V_INTERLACE; if (timing->misc & 0x02) Mode->Flags |= V_PVSYNC; else Mode->Flags |= V_NVSYNC; if (timing->misc & 0x01) Mode->Flags |= V_PHSYNC; else Mode->Flags |= V_NHSYNC; return Mode;}/* * */static voidDDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes){ DisplayModePtr Mode = Modes; if (!Monitor || !Modes) return; /* set up the ranges for scanning through the modes */ Monitor->nHsync = 1; Monitor->hsync[0].lo = 1024.0; Monitor->hsync[0].hi = 0.0; Monitor->nVrefresh = 1; Monitor->vrefresh[0].lo = 1024.0; Monitor->vrefresh[0].hi = 0.0; while (Mode) { if (!Mode->HSync) Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal); if (!Mode->VRefresh) Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / ((float) (Mode->HTotal * Mode->VTotal)); if (Mode->HSync < Monitor->hsync[0].lo) Monitor->hsync[0].lo = Mode->HSync; if (Mode->HSync > Monitor->hsync[0].hi) Monitor->hsync[0].hi = Mode->HSync; if (Mode->VRefresh < Monitor->vrefresh[0].lo) Monitor->vrefresh[0].lo = Mode->VRefresh; if (Mode->VRefresh > Monitor->vrefresh[0].hi) Monitor->vrefresh[0].hi = Mode->VRefresh; Mode = Mode->next; }}_X_EXPORT DisplayModePtrxf86DDCGetModes(int scrnIndex, xf86MonPtr DDC){ int preferred, i; DisplayModePtr Modes = NULL, Mode; ddc_quirk_t quirks; xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", DDC->vendor.name, DDC->vendor.prod_id); quirks = DDC_QUIRK_NONE; for (i = 0; ddc_quirks[i].detect; i++) if (ddc_quirks[i].detect (scrnIndex, DDC)) { xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n", ddc_quirks[i].description); quirks |= ddc_quirks[i].quirk; } preferred = PREFERRED_TIMING_MODE(DDC->features.msc); if (quirks & DDC_QUIRK_PREFER_LARGE_60) preferred = 0; for (i = 0; i < DET_TIMINGS; i++) { struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; switch (det_mon->type) { case DT: Mode = DDCModeFromDetailedTiming(scrnIndex, &det_mon->section.d_timings, preferred, quirks); preferred = 0; Modes = xf86ModesAdd(Modes, Mode); break; case DS_STD_TIMINGS: Mode = DDCModesFromStandardTiming(scrnIndex, det_mon->section.std_t, quirks); Modes = xf86ModesAdd(Modes, Mode); break; default: break; } } /* Add established timings */ Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks); Modes = xf86ModesAdd(Modes, Mode); /* Add standard timings */ Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks); Modes = xf86ModesAdd(Modes, Mode); if (quirks & DDC_QUIRK_PREFER_LARGE_60) { DisplayModePtr best = Modes; for (Mode = Modes; Mode; Mode = Mode->next) { if (Mode == best) continue; if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay) { best = Mode; continue; } if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay) { double mode_refresh = xf86ModeVRefresh (Mode); double best_refresh = xf86ModeVRefresh (best); double mode_dist = fabs(mode_refresh - 60.0); double best_dist = fabs(best_refresh - 60.0); if (mode_dist < best_dist) { best = Mode; continue; } } } if (best) best->type |= M_T_PREFERRED; } return Modes;}/* * Fill out MonPtr with xf86MonPtr information. */_X_EXPORT voidxf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC){ DisplayModePtr Modes = NULL, Mode; int i, clock; Bool have_hsync = FALSE, have_vrefresh = FALSE, have_maxpixclock = FALSE; if (!Monitor || !DDC) return; Monitor->DDC = DDC; Monitor->widthmm = 10 * DDC->features.hsize; Monitor->heightmm = 10 * DDC->features.vsize; /* If this is a digital display, then we can use reduced blanking */ if (DDC->features.input_type) Monitor->reducedblanking = TRUE; /* Allow the user to also enable this through config */ Modes = xf86DDCGetModes(scrnIndex, DDC); /* Skip EDID ranges if they were specified in the config file */ have_hsync = (Monitor->nHsync != 0); have_vrefresh = (Monitor->nVrefresh != 0); have_maxpixclock = (Monitor->maxPixClock != 0); /* Go through the detailed monitor sections */ for (i = 0; i < DET_TIMINGS; i++) { switch (DDC->det_mon[i].type) { case DS_RANGES: if (!have_hsync) { if (!Monitor->nHsync) xf86DrvMsg(scrnIndex, X_INFO, "Using EDID range info for horizontal sync\n"); Monitor->hsync[Monitor->nHsync].lo = DDC->det_mon[i].section.ranges.min_h; Monitor->hsync[Monitor->nHsync].hi = DDC->det_mon[i].section.ranges.max_h; Monitor->nHsync++; } else { xf86DrvMsg(scrnIndex, X_INFO, "Using hsync ranges from config file\n"); } if (!have_vrefresh) { if (!Monitor->nVrefresh) xf86DrvMsg(scrnIndex, X_INFO, "Using EDID range info for vertical refresh\n"); Monitor->vrefresh[Monitor->nVrefresh].lo = DDC->det_mon[i].section.ranges.min_v; Monitor->vrefresh[Monitor->nVrefresh].hi = DDC->det_mon[i].section.ranges.max_v; Monitor->nVrefresh++; } else { xf86DrvMsg(scrnIndex, X_INFO, "Using vrefresh ranges from config file\n"); } clock = DDC->det_mon[i].section.ranges.max_clock * 1000; if (!have_maxpixclock && clock > Monitor->maxPixClock) Monitor->maxPixClock = clock; break; default: break; } } if (Modes) { /* Print Modes */ xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n"); Mode = Modes; while (Mode) { xf86PrintModeline(scrnIndex, Mode); Mode = Mode->next; } /* Do we still need ranges to be filled in? */ if (!Monitor->nHsync || !Monitor->nVrefresh) DDCGuessRangesFromModes(scrnIndex, Monitor, Modes); /* look for last Mode */ Mode = Modes; while (Mode->next) Mode = Mode->next; /* add to MonPtr */ if (Monitor->Modes) { Monitor->Last->next = Modes; Modes->prev = Monitor->Last; Monitor->Last = Mode; } else { Monitor->Modes = Modes; Monitor->Last = Mode; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -