# HG changeset patch
# User moel.mich
# Date 1265744553 0
# Node ID 0e09d845eb00d276eef3c3643ada9b2b06430903
# Parent  124f735b73aa01bee483baadbd8351c9aa4321de
Added support for NVIDIA fan rpm. Changed NVIDIA GPU enumeration.

diff -r 124f735b73aa -r 0e09d845eb00 Hardware/Nvidia/NVAPI.cs
--- a/Hardware/Nvidia/NVAPI.cs	Tue Feb 09 18:55:45 2010 +0000
+++ b/Hardware/Nvidia/NVAPI.cs	Tue Feb 09 19:42:33 2010 +0000
@@ -174,6 +174,8 @@
       out int gpuCount);
     public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
       [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
+    public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
+      NvPhysicalGpuHandle gpuHandle, out int value);
 
     private static bool available = false;
     private static nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
@@ -188,6 +190,8 @@
       NvAPI_GetPhysicalGPUsFromDisplay;
     public static NvAPI_EnumPhysicalGPUsDelegate
       NvAPI_EnumPhysicalGPUs;
+    public static NvAPI_GPU_GetTachReadingDelegate
+      NvAPI_GPU_GetTachReading;
 
     public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
       out string name) {
@@ -209,7 +213,12 @@
       where T : class 
     {
       IntPtr ptr = nvapi_QueryInterface(id);
-      newDelegate = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;      
+      if (ptr != IntPtr.Zero) {
+        newDelegate =
+          Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
+      } else {
+        newDelegate = null;
+      }
     }
 
     static NVAPI() { 
@@ -231,6 +240,7 @@
         GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
         GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
         GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
+        GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);        
         available = true;
       }
     }
diff -r 124f735b73aa -r 0e09d845eb00 Hardware/Nvidia/NvidiaGPU.cs
--- a/Hardware/Nvidia/NvidiaGPU.cs	Tue Feb 09 18:55:45 2010 +0000
+++ b/Hardware/Nvidia/NvidiaGPU.cs	Tue Feb 09 19:42:33 2010 +0000
@@ -40,7 +40,7 @@
 using System.Drawing;
 
 namespace OpenHardwareMonitor.Hardware.Nvidia {
-  public class NvidiaGPU : IHardware {
+  public class NvidiaGPU : Hardware, IHardware {
 
     private string name;
     private Image icon;
@@ -48,12 +48,18 @@
     private NvPhysicalGpuHandle handle;
 
     private Sensor[] temperatures;
+    private Sensor fan = null;
+
+    private bool available;
 
     public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle) {
       try {
         string gpuName;
-        NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName);
-        this.name = "NVIDIA " + gpuName;
+        if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) {
+          this.name = "NVIDIA " + gpuName.Trim();
+        } else {
+          this.name = "NVIDIA";
+        }
         this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png");
         this.adapterIndex = adapterIndex;
         this.handle = handle;
@@ -73,12 +79,28 @@
           }
           temperatures[i] = new Sensor(name, i, sensor.DefaultMaxTemp, 
             SensorType.Temperature, this);
+          ActivateSensor(temperatures[i]);
         }
+        
+        int value;
+        if (NVAPI.NvAPI_GPU_GetTachReading != null &&
+          NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) {
+          if (value > 0) {
+            fan = new Sensor("GPU", 0, SensorType.Fan, this);
+            ActivateSensor(fan);
+          }
+        }
+
+        available = temperatures.Length > 0 || fan != null;
       } catch (Exception e) {
         System.Windows.Forms.MessageBox.Show(e.Message + "\n" + e.StackTrace);
       }
     }
 
+    public bool IsAvailable {
+      get { return available; }
+    }
+
     public string Name {
       get { return name; }
     }
@@ -91,12 +113,6 @@
       get { return icon; }
     }
 
-    public ISensor[] Sensors {
-      get {
-        return temperatures;
-      }
-    }
-
     public string GetReport() {
       return null;
     }
@@ -106,21 +122,23 @@
       settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
       settings.Count = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
       settings.Sensor = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
-      NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
-        ref settings);
+      if (NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
+        ref settings) != NvStatus.OK) {
+        settings.Count = 0;        
+      }
       return settings;
     }
 
     public void Update() {
       NvGPUThermalSettings settings = GetThermalSettings();
       foreach (Sensor sensor in temperatures) 
-        sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;              
+        sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;
+
+      if (fan != null) {
+        int value = 0;
+        NVAPI.NvAPI_GPU_GetTachReading(handle, out value);
+        fan.Value = value;
+      }
     }
-
-    #pragma warning disable 67
-    public event SensorEventHandler SensorAdded;
-    public event SensorEventHandler SensorRemoved;
-    #pragma warning restore 67
-
   }
 }
diff -r 124f735b73aa -r 0e09d845eb00 Hardware/Nvidia/NvidiaGroup.cs
--- a/Hardware/Nvidia/NvidiaGroup.cs	Tue Feb 09 18:55:45 2010 +0000
+++ b/Hardware/Nvidia/NvidiaGroup.cs	Tue Feb 09 19:42:33 2010 +0000
@@ -65,10 +65,9 @@
       report.AppendLine();
 
       for (int i = 0; i < count; i++) {
-        string gpuName;
-        NVAPI.NvAPI_GPU_GetFullName(handles[i], out gpuName);
-        if (gpuName != null && gpuName.Trim() != "")
-          hardware.Add(new NvidiaGPU(i, handles[i]));
+        NvidiaGPU gpu = new NvidiaGPU(i, handles[i]);
+        if (gpu.IsAvailable)
+          hardware.Add(gpu);
       }
     }
 
diff -r 124f735b73aa -r 0e09d845eb00 Properties/AssemblyInfo.cs
--- a/Properties/AssemblyInfo.cs	Tue Feb 09 18:55:45 2010 +0000
+++ b/Properties/AssemblyInfo.cs	Tue Feb 09 19:42:33 2010 +0000
@@ -69,5 +69,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.1.16.0")]
-[assembly: AssemblyFileVersion("0.1.16.0")]
+[assembly: AssemblyVersion("0.1.17.0")]
+[assembly: AssemblyFileVersion("0.1.17.0")]