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