StephaneLenclud@433: /* StephaneLenclud@433: StephaneLenclud@433: This Source Code Form is subject to the terms of the Mozilla Public StephaneLenclud@433: License, v. 2.0. If a copy of the MPL was not distributed with this StephaneLenclud@433: file, You can obtain one at http://mozilla.org/MPL/2.0/. StephaneLenclud@433: StephaneLenclud@433: Copyright (C) 2009-2012 Michael Möller StephaneLenclud@433: StephaneLenclud@433: */ StephaneLenclud@433: StephaneLenclud@433: using System; StephaneLenclud@433: using System.Collections.Generic; StephaneLenclud@433: using System.Drawing; StephaneLenclud@433: using System.Text; StephaneLenclud@436: using System.Diagnostics; StephaneLenclud@433: using System.Windows.Forms; StephaneLenclud@435: using System.Windows; StephaneLenclud@433: using OpenHardwareMonitor.Hardware; StephaneLenclud@433: using OpenHardwareMonitor.Utilities; StephaneLenclud@433: using System.Runtime.InteropServices; StephaneLenclud@436: using UacHelpers; StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: namespace OpenHardwareMonitor.GUI StephaneLenclud@433: { StephaneLenclud@433: public class SoundGraphDisplay : IDisposable StephaneLenclud@433: { StephaneLenclud@433: private IComputer computer; StephaneLenclud@433: private PersistentSettings settings; StephaneLenclud@433: private UnitManager unitManager; StephaneLenclud@433: private List list = new List(); StephaneLenclud@436: private SoundGraph.Server iServer; StephaneLenclud@436: StephaneLenclud@439: private int iNextSensorToDisplay=0; StephaneLenclud@439: private int iTickCounter=0; StephaneLenclud@438: StephaneLenclud@433: StephaneLenclud@433: public SoundGraphDisplay(IComputer computer, PersistentSettings settings, StephaneLenclud@433: UnitManager unitManager) StephaneLenclud@433: { StephaneLenclud@433: this.computer = computer; StephaneLenclud@433: this.settings = settings; StephaneLenclud@433: this.unitManager = unitManager; StephaneLenclud@433: computer.HardwareAdded += new HardwareEventHandler(HardwareAdded); StephaneLenclud@433: computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved); StephaneLenclud@433: StephaneLenclud@436: //Start our client if needed StephaneLenclud@436: Process[] processes = Process.GetProcessesByName("SoundGraphAccess"); StephaneLenclud@436: if (!(processes.Length > 0)) StephaneLenclud@436: { StephaneLenclud@445: try StephaneLenclud@445: { StephaneLenclud@444: //Try to launch the sound graph process from the same folder as this executable StephaneLenclud@445: string exeName = System.IO.Path.GetDirectoryName(Application.ExecutablePath); StephaneLenclud@444: exeName += @"\SoundGraphAccess.exe"; StephaneLenclud@445: Process client = UserAccountControl.CreateProcessAsStandardUser(exeName, ""); StephaneLenclud@445: } StephaneLenclud@445: catch (Exception e) StephaneLenclud@445: { StephaneLenclud@445: Debug.WriteLine("SoundGraphAccess.exe start-up failed: " + e.ToString()); StephaneLenclud@445: } StephaneLenclud@436: } StephaneLenclud@436: StephaneLenclud@437: //Start our SoundGraph server StephaneLenclud@437: iServer = new SoundGraph.Server(@"\\.\pipe\sga-inbound", @"\\.\pipe\sga-outbound"); StephaneLenclud@436: iServer.Start(); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void HardwareRemoved(IHardware hardware) StephaneLenclud@433: { StephaneLenclud@433: hardware.SensorAdded -= new SensorEventHandler(SensorAdded); StephaneLenclud@433: hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved); StephaneLenclud@433: foreach (ISensor sensor in hardware.Sensors) StephaneLenclud@433: SensorRemoved(sensor); StephaneLenclud@433: foreach (IHardware subHardware in hardware.SubHardware) StephaneLenclud@433: HardwareRemoved(subHardware); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void HardwareAdded(IHardware hardware) StephaneLenclud@433: { StephaneLenclud@433: foreach (ISensor sensor in hardware.Sensors) StephaneLenclud@433: SensorAdded(sensor); StephaneLenclud@433: hardware.SensorAdded += new SensorEventHandler(SensorAdded); StephaneLenclud@433: hardware.SensorRemoved += new SensorEventHandler(SensorRemoved); StephaneLenclud@433: foreach (IHardware subHardware in hardware.SubHardware) StephaneLenclud@433: HardwareAdded(subHardware); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void SensorAdded(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: if (settings.GetValue(new Identifier(sensor.Identifier, StephaneLenclud@438: "FrontView").ToString(), false)) StephaneLenclud@433: Add(sensor, false); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void SensorRemoved(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: if (Contains(sensor)) StephaneLenclud@433: Remove(sensor, false); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public void Dispose() StephaneLenclud@433: { StephaneLenclud@433: foreach (SensorFrontView icon in list) StephaneLenclud@433: icon.Dispose(); StephaneLenclud@433: StephaneLenclud@437: Quit(); StephaneLenclud@436: iServer.Stop(); StephaneLenclud@433: StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@442: public void Redraw(bool aPacked, bool aDisplayTime) StephaneLenclud@433: { StephaneLenclud@443: const int KNumberOfTickBeforeSwitch = 4; StephaneLenclud@443: const int KMaxCharacterPerLine = 16; StephaneLenclud@442: string packedFirstLine=""; //We have 16 chars per line on our VFD StephaneLenclud@442: string packedSecondLine=""; StephaneLenclud@442: int count = 0; StephaneLenclud@442: StephaneLenclud@443: string time = DateTime.Now.ToShortTimeString(); StephaneLenclud@443: StephaneLenclud@439: //Update all sensors from our front view StephaneLenclud@438: foreach (SensorFrontView sensor in list) StephaneLenclud@438: { StephaneLenclud@442: count++; StephaneLenclud@438: sensor.Update(); StephaneLenclud@442: StephaneLenclud@444: if (aDisplayTime && count == 1) StephaneLenclud@444: { StephaneLenclud@444: //First slot is take by time display StephaneLenclud@444: count++; StephaneLenclud@444: packedFirstLine = time + " "; StephaneLenclud@444: } StephaneLenclud@444: StephaneLenclud@442: if (aPacked) StephaneLenclud@442: { StephaneLenclud@444: //Build strings for packed mode StephaneLenclud@442: string packedText = ""; StephaneLenclud@442: packedText = sensor.iFirstLine.Substring(0, 3) + ":" + sensor.iSecondLine; StephaneLenclud@442: if (count == 1) StephaneLenclud@442: { StephaneLenclud@444: packedFirstLine = packedText + " "; //Minimum one space to separate sensors on the same line StephaneLenclud@442: } StephaneLenclud@442: else if (count == 2) StephaneLenclud@442: { StephaneLenclud@444: //Add enough spaces to align to right hand side StephaneLenclud@443: while (packedFirstLine.Length + packedText.Length < KMaxCharacterPerLine) StephaneLenclud@442: { StephaneLenclud@442: packedFirstLine += " "; StephaneLenclud@442: } StephaneLenclud@442: packedFirstLine += packedText; StephaneLenclud@442: } StephaneLenclud@442: else if (count == 3) StephaneLenclud@442: { StephaneLenclud@444: packedSecondLine = packedText + " "; //Minimum one space to separate sensors on the same line StephaneLenclud@442: } StephaneLenclud@442: else if (count == 4) StephaneLenclud@442: { StephaneLenclud@444: //Add enough spaces to align to right hand side StephaneLenclud@443: while (packedSecondLine.Length + packedText.Length < KMaxCharacterPerLine) StephaneLenclud@442: { StephaneLenclud@442: packedSecondLine += " "; StephaneLenclud@442: } StephaneLenclud@442: packedSecondLine += packedText; StephaneLenclud@442: } StephaneLenclud@442: } StephaneLenclud@438: //SetText(sensor.iFirstLine, sensor.iSecondLine); StephaneLenclud@438: } StephaneLenclud@438: StephaneLenclud@438: //Alternate between sensors StephaneLenclud@438: if (list.Count > 0) StephaneLenclud@438: { StephaneLenclud@442: if (aPacked) StephaneLenclud@439: { StephaneLenclud@442: //string packedLine = ""; StephaneLenclud@442: iTickCounter++; StephaneLenclud@443: if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick StephaneLenclud@442: { StephaneLenclud@442: iTickCounter = 0; StephaneLenclud@442: if (iNextSensorToDisplay==1) StephaneLenclud@442: { StephaneLenclud@442: iNextSensorToDisplay=0; StephaneLenclud@442: } StephaneLenclud@442: else StephaneLenclud@442: { StephaneLenclud@442: iNextSensorToDisplay=1; StephaneLenclud@442: } StephaneLenclud@442: } StephaneLenclud@442: StephaneLenclud@444: //TODO: Do something like that to cycle lines if ever we want to StephaneLenclud@444: //SetText(time, (iNextSensorToDisplay == 1 && packedSecondLine.Length > 0 ? packedSecondLine : packedFirstLine)); StephaneLenclud@442: StephaneLenclud@444: //Display packed sensors on our FrontView display StephaneLenclud@444: SetText(packedFirstLine, packedSecondLine); StephaneLenclud@442: } StephaneLenclud@442: else StephaneLenclud@442: { StephaneLenclud@443: string secondLine = list[iNextSensorToDisplay].iSecondLine; StephaneLenclud@443: if (aDisplayTime) StephaneLenclud@443: { StephaneLenclud@443: //Add enough spaces StephaneLenclud@443: while (secondLine.Length + time.Length < KMaxCharacterPerLine) StephaneLenclud@443: { StephaneLenclud@443: secondLine += " "; StephaneLenclud@443: } StephaneLenclud@443: secondLine += time; StephaneLenclud@443: } StephaneLenclud@442: //Display current sensor on our FrontView display StephaneLenclud@443: SetText(list[iNextSensorToDisplay].iFirstLine, secondLine); StephaneLenclud@442: iTickCounter++; StephaneLenclud@443: if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick StephaneLenclud@442: { StephaneLenclud@442: iTickCounter = 0; StephaneLenclud@442: iNextSensorToDisplay++; StephaneLenclud@442: } StephaneLenclud@439: } StephaneLenclud@438: } StephaneLenclud@438: StephaneLenclud@439: if (iNextSensorToDisplay == list.Count) StephaneLenclud@438: { StephaneLenclud@438: //Go back to first sensor StephaneLenclud@439: iNextSensorToDisplay = 0; StephaneLenclud@438: } StephaneLenclud@438: StephaneLenclud@438: StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public bool Contains(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: foreach (SensorFrontView icon in list) StephaneLenclud@433: if (icon.Sensor == sensor) StephaneLenclud@433: return true; StephaneLenclud@433: return false; StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public void Add(ISensor sensor, bool balloonTip) StephaneLenclud@433: { StephaneLenclud@433: if (Contains(sensor)) StephaneLenclud@433: { StephaneLenclud@433: return; StephaneLenclud@433: } StephaneLenclud@433: else StephaneLenclud@433: { StephaneLenclud@433: //SL: StephaneLenclud@438: list.Add(new SensorFrontView(this, sensor, balloonTip, settings, unitManager)); StephaneLenclud@433: //UpdateMainIconVisibilty(); StephaneLenclud@438: settings.SetValue(new Identifier(sensor.Identifier, "FrontView").ToString(), true); StephaneLenclud@439: iNextSensorToDisplay = 0; StephaneLenclud@444: if (list.Count == 1) StephaneLenclud@444: { StephaneLenclud@444: //Just added first sensor in FrontView, unable FrontView plug-in mode StephaneLenclud@444: Init(); StephaneLenclud@444: } StephaneLenclud@433: } StephaneLenclud@438: StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public void Remove(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: Remove(sensor, true); StephaneLenclud@439: iNextSensorToDisplay = 0; StephaneLenclud@444: if (list.Count == 0) StephaneLenclud@444: { StephaneLenclud@444: //No sensor to display in FrontView, just disable FrontView plug-in mode StephaneLenclud@444: Uninit(); StephaneLenclud@444: } StephaneLenclud@444: StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void Remove(ISensor sensor, bool deleteConfig) StephaneLenclud@433: { StephaneLenclud@433: if (deleteConfig) StephaneLenclud@433: { StephaneLenclud@433: settings.Remove( StephaneLenclud@438: new Identifier(sensor.Identifier, "FrontView").ToString()); StephaneLenclud@433: } StephaneLenclud@433: SensorFrontView instance = null; StephaneLenclud@433: foreach (SensorFrontView icon in list) StephaneLenclud@433: if (icon.Sensor == sensor) StephaneLenclud@433: instance = icon; StephaneLenclud@433: if (instance != null) StephaneLenclud@433: { StephaneLenclud@433: list.Remove(instance); StephaneLenclud@438: //UpdateMainIconVisibilty(); StephaneLenclud@433: instance.Dispose(); StephaneLenclud@433: } StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: private void UpdateMainIconVisibilty() StephaneLenclud@433: { StephaneLenclud@433: /* StephaneLenclud@433: if (mainIconEnabled) StephaneLenclud@433: { StephaneLenclud@433: mainIcon.Visible = list.Count == 0; StephaneLenclud@433: } StephaneLenclud@433: else StephaneLenclud@433: { StephaneLenclud@433: mainIcon.Visible = false; StephaneLenclud@433: } StephaneLenclud@433: */ StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@436: public void Init() StephaneLenclud@434: { StephaneLenclud@436: iServer.SendMessage("init:"); StephaneLenclud@434: } StephaneLenclud@434: StephaneLenclud@435: public void Uninit() StephaneLenclud@434: { StephaneLenclud@436: iServer.SendMessage("uninit:"); StephaneLenclud@434: } StephaneLenclud@434: StephaneLenclud@435: public void SetText(string aUpperLine, string aLowerLine) StephaneLenclud@434: { StephaneLenclud@438: iServer.SendMessage("set-vfd-text:" + aUpperLine + "\n" + aLowerLine); StephaneLenclud@434: } StephaneLenclud@434: StephaneLenclud@437: public void Quit() StephaneLenclud@437: { StephaneLenclud@437: iServer.SendMessage("quit:"); StephaneLenclud@437: } StephaneLenclud@437: StephaneLenclud@433: /* StephaneLenclud@433: public bool IsMainIconEnabled StephaneLenclud@433: { StephaneLenclud@433: get { return mainIconEnabled; } StephaneLenclud@433: set StephaneLenclud@433: { StephaneLenclud@433: if (mainIconEnabled != value) StephaneLenclud@433: { StephaneLenclud@433: mainIconEnabled = value; StephaneLenclud@433: UpdateMainIconVisibilty(); StephaneLenclud@433: } StephaneLenclud@433: } StephaneLenclud@433: }*/ StephaneLenclud@434: StephaneLenclud@435: StephaneLenclud@433: } StephaneLenclud@433: }