public MonitorTimings GetMonitorTimings() { var hor = new ExpandedTimingsPart(); hor.visible = (UInt16)numHorVisible.Value; hor.border = (UInt16)numHorBorder.Value; hor.frontPorch = (UInt16)numHorFrontPorch.Value; hor.syncWidth = (UInt16)numHorSyncWidth.Value; hor.backPorch = (UInt16)numHorBackPorch.Value; hor.blanking = (UInt16)numHorBlanking.Value; hor.total = (UInt16)numHorTotal.Value; var ver = new ExpandedTimingsPart(); ver.visible = (UInt16)numVerVisible.Value; ver.border = (UInt16)numVerBorder.Value; ver.frontPorch = (UInt16)numVerFrontPorch.Value; ver.syncWidth = (UInt16)numVerSyncWidth.Value; ver.backPorch = (UInt16)numVerBackPorch.Value; ver.blanking = (UInt16)numVerBlanking.Value; ver.total = (UInt16)numVerTotal.Value; var dst = new MonitorTimings(); dst.frequency = (UInt16)(numActualClock.Value * 100); dst.hor = hor.ToTimingsPart(); dst.ver = ver.ToTimingsPart(); return(dst); }
private void btnDecode_Click(object sender, EventArgs e) { if (sender == btnDecodeDisplayTimings) { try { var timings = MonitorTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(textDisplayTimings.Text)); ApplyMonitorTimings(timings); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error parsing encoded display timings"); return; } } else if (sender == btnDecodeGlassesTimings) { try { var timings = GlassesTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(textGlassesTimings.Text)); ApplyGlassesTimings(timings); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error parsing encoded glasses timings"); return; } } }
public static ResourceTiming FromMonitorTimings(MonitorTimings tims) { var dst = new ResourceTiming(); var hor = ExpandedTimingsPart.CreateFromTimingsPart(tims.hor); var ver = ExpandedTimingsPart.CreateFromTimingsPart(tims.ver); dst.freq10sKhz = tims.frequency; dst.horActive = hor.visible; dst.horBorder = hor.border; dst.horFrontPorch = hor.frontPorch; dst.horSyncPixels = hor.syncWidth; dst.horTotal = hor.total; dst.verActive = ver.visible; dst.verBorder = ver.border; dst.verFrontPorch = ver.frontPorch; dst.verSyncLines = ver.syncWidth; dst.verTotal = ver.total; if (tims.frequency != 0 && hor.total != 0 && ver.total != 0) { var frequency = (decimal)(tims.frequency) / 100; var refresh = (frequency * 1000000) / (hor.total * ver.total); dst.refreshRateHz = (UInt16)Math.Round(refresh); } return(dst); }
public static MonitorTimings CreateFromByteArray(byte[] bytes) { var timingsStr = new MonitorTimings(); var requiredLength = Marshal.SizeOf(timingsStr); if (bytes.Length != requiredLength) { throw new ArgumentException(String.Format("Encoded display timing parameters must be {0} bytes long: {1}", requiredLength, StructureExtensions.ByteArrayToString(bytes))); } timingsStr = StructureExtensions.ToStructure <MonitorTimings>(bytes); return(timingsStr); }
public override string ToString() { try { var timings = MonitorTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(encodedName)); var frequency = (decimal)(timings.frequency) / 100; var refresh = (frequency * 1000000) / (timings.hor.total * timings.ver.total); refresh = Math.Round(refresh * 1000) / 1000; return(String.Format("{0}x{1} ({2}x{3}) @ {4}Hz ({5}MHz)", timings.hor.visible, timings.ver.visible, timings.hor.total, timings.ver.total, refresh, frequency)); } catch (Exception) { return("ERROR:" + encodedName); } }
public void ApplyMonitorTimings(MonitorTimings all) { var frequency = (decimal)(all.frequency) / 100; var hor = ExpandedTimingsPart.CreateFromTimingsPart(all.hor); var ver = ExpandedTimingsPart.CreateFromTimingsPart(all.ver); var horizontal = (frequency * 1000) / hor.total; var refresh = (frequency * 1000000) / (hor.total * ver.total); suppressValueChangedEvent = true; try { numWantedClock.Value = numActualClock.Value = frequency; numWantedHoriz.Value = numActualHoriz.Value = horizontal; numWantedRefresh.Value = numActualRefresh.Value = refresh; ApplyHorTimings(hor); ApplyVerTimings(ver); } finally { suppressValueChangedEvent = false; } }
private void btnPatchNvStRes_Click(object sender, EventArgs e) { if (monitorSubKey == null) { return; } var currMonitorName = monitorSubKey.Value.Name.Split('\\').Last().Trim(); byte[] monitorIdentBytes = MonitorNameToEdidIdentifier(currMonitorName); if (monitorIdentBytes == null) { MessageBox.Show("Monitor name must be in the format ABC_HHHH where ABC are letters and HHHH is a hex-encoded uint16", "Invalid monitor name"); return; } MonitorTimings[] monTimings = null; int actualLen = 0; int invalidLen = 0; try { var valueNames = monitorSubKey.Value.GetValueNames(); monTimings = new MonitorTimings[valueNames.Length]; foreach (var monVal in valueNames) { try { monTimings[actualLen++] = MonitorTimings.CreateFromByteArray(StructureExtensions.StringToByteArrayFastest(monVal)); } catch (Exception) { invalidLen++; } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error reading monitor key values"); return; } if (monTimings == null) { return; } else if (actualLen > 6) { MessageBox.Show("nvstres.dll supports a maximum of 6 timings per monitor", "Too many monitor timings"); return; } if (invalidLen > 0) { var res = MessageBox.Show(actualLen.ToString() + " invalid monitor timings will be skipped. Continue?", "Invalid timings found", MessageBoxButtons.YesNo); if (res != DialogResult.Yes) { return; } } byte[] resData = null; const ushort RESOURCE_NAME = 8; const ushort RESOURCE_TYPE = 10; const ushort RESOURCE_LANG = 0; int numFilesPatched = 0; string[] defaultFilenames = { "nvstres", "nvstres64" }; foreach (string defaultFilename in defaultFilenames) { string theFileName = null; using (var dlg = new OpenFileDialog()) { dlg.FileName = defaultFilename; dlg.DefaultExt = ".dll"; dlg.Filter = "DLL files (.dll)|*.dll"; dlg.InitialDirectory = GetNvidia3DVisionFolder(); if (dlg.ShowDialog() == DialogResult.OK) { theFileName = dlg.FileName; } } if (theFileName == null) { return; } if (resData == null) { try { resData = ResourceManager.GetResourceFromExecutable(theFileName, (IntPtr)RESOURCE_NAME, (IntPtr)RESOURCE_TYPE); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error reading resource"); continue; } if (resData == null) { MessageBox.Show("No timings resource in " + theFileName, "Error finding resource"); continue; } var currTimings = new ResourceMonitorTimings(); var oneSize = Marshal.SizeOf(currTimings); var numEntries = resData.Length / oneSize; if (oneSize * numEntries != resData.Length) { MessageBox.Show(String.Format("Timings resource has uneven length of {0} expected {1}", resData.Length, oneSize * numEntries), "Error parsing resource"); continue; } int foundIdx = -1; int firstFreeIdx = -1; var allTimings = new ResourceMonitorTimings[numEntries]; for (int i = 0; i < numEntries; i++) { var entryData = resData.Skip(i * oneSize).Take(oneSize).ToArray(); allTimings[i] = entryData.ToStructure <ResourceMonitorTimings>(); if (currMonitorName.Equals(allTimings[i].GetMonitorName(), StringComparison.OrdinalIgnoreCase)) { foundIdx = i; } else if (firstFreeIdx < 0 && allTimings[i].IsEmpty()) { firstFreeIdx = i; } } if (foundIdx < 0 && firstFreeIdx < 0) { MessageBox.Show(String.Format("Timings for monitor {0} not found and the resource is full!", currMonitorName), "Cannot add to resource"); continue; } var existingTimings = allTimings.ElementAtOrDefault(foundIdx); var newTimings = new ResourceMonitorTimings(); newTimings.timings = new ResourceTiming[actualLen]; newTimings.vendorId = BitConverter.ToUInt16(monitorIdentBytes, 0); newTimings.productId = BitConverter.ToUInt16(monitorIdentBytes, 2); for (int i = 0; i < actualLen; i++) { newTimings.timings[i] = ResourceTiming.FromMonitorTimings(monTimings[i]); if (existingTimings.timings != null) { newTimings.timings[i].horFlags = existingTimings.timings[0].horFlags; newTimings.timings[i].verFlags = existingTimings.timings[0].verFlags; } } Array.Sort(newTimings.timings, 0, actualLen, new FunctionalComparer <ResourceTiming>( (x, y) => (x.refreshRateHz == y.refreshRateHz) ? (x.freq10sKhz.CompareTo(y.freq10sKhz)) : (x.refreshRateHz.CompareTo(y.refreshRateHz)) )); using (var dlg = new TimingReview(currMonitorName, existingTimings.timings, newTimings.timings)) { var dlgRes = dlg.ShowDialog(); if (dlgRes != DialogResult.OK) { return; } newTimings.timings = dlg.GetNewTimings(); Array.Resize(ref newTimings.timings, 6); } int copyIdx = (foundIdx < 0) ? firstFreeIdx : foundIdx; Array.Copy(StructureExtensions.ToByteArray(newTimings), 0, resData, oneSize * copyIdx, oneSize); } IntPtr resHandle = IntPtr.Zero; bool resUpdatedOk = false; try { resHandle = ResourceManager.BeginUpdateResource(theFileName, false); resUpdatedOk = ResourceManager.UpdateResourceWithBytes(resHandle, (IntPtr)RESOURCE_TYPE, (IntPtr)RESOURCE_NAME, RESOURCE_LANG, resData); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error updating resource"); continue; } finally { if (resHandle != IntPtr.Zero) { var resFinishedOk = ResourceManager.EndUpdateResource(resHandle, !resUpdatedOk); if (resUpdatedOk) { resUpdatedOk = resFinishedOk; } } } if (resUpdatedOk == false) { MessageBox.Show("Error updating resource in " + theFileName, "Error updating resource"); continue; } else { MessageBox.Show("Applied changes to " + theFileName, "Finished updating resource"); numFilesPatched++; } } if (numFilesPatched > 0) { MessageBox.Show(numFilesPatched.ToString() + " files have been patched.\nYou will likely need to REBOOT for any changes to take effect", "Done with patching"); } }