Hardware/ATI/ADL.cs
author StephaneLenclud
Thu, 18 Apr 2013 23:25:10 +0200
branchMiniDisplay
changeset 444 9b09e2ee0968
parent 344 3145aadca3d2
permissions -rw-r--r--
Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
moel@1
     1
/*
moel@1
     2
 
moel@344
     3
  This Source Code Form is subject to the terms of the Mozilla Public
moel@344
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
moel@344
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
moel@1
     6
 
moel@344
     7
  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@1
     9
*/
moel@1
    10
moel@1
    11
using System;
moel@1
    12
using System.Runtime.InteropServices;
moel@333
    13
using System.Text.RegularExpressions;
moel@1
    14
moel@1
    15
namespace OpenHardwareMonitor.Hardware.ATI {
moel@1
    16
  
moel@1
    17
  [StructLayout(LayoutKind.Sequential)]
moel@165
    18
  internal struct ADLAdapterInfo {
moel@1
    19
    public int Size;
moel@1
    20
    public int AdapterIndex;
moel@1
    21
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    22
    public string UDID;
moel@1
    23
    public int BusNumber;
moel@3
    24
    public int DeviceNumber;
moel@1
    25
    public int FunctionNumber;
moel@1
    26
    public int VendorID;
moel@1
    27
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    28
    public string AdapterName;
moel@1
    29
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    30
    public string DisplayName;
moel@1
    31
    public int Present;
moel@1
    32
    public int Exist;
moel@1
    33
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    34
    public string DriverPath;
moel@1
    35
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    36
    public string DriverPathExt;
moel@1
    37
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    38
    public string PNPString;
moel@1
    39
    public int OSDisplayIndex;
moel@1
    40
  }
moel@1
    41
moel@1
    42
  [StructLayout(LayoutKind.Sequential)]
moel@165
    43
  internal struct ADLPMActivity {
moel@1
    44
    public int Size;
moel@1
    45
    public int EngineClock;
moel@1
    46
    public int MemoryClock;
moel@1
    47
    public int Vddc;
moel@1
    48
    public int ActivityPercent;
moel@1
    49
    public int CurrentPerformanceLevel;
moel@1
    50
    public int CurrentBusSpeed;
moel@1
    51
    public int CurrentBusLanes;
moel@1
    52
    public int MaximumBusLanes;
moel@1
    53
    public int Reserved;
moel@1
    54
  }
moel@1
    55
moel@1
    56
  [StructLayout(LayoutKind.Sequential)]
moel@165
    57
  internal struct ADLTemperature {
moel@1
    58
    public int Size;
moel@1
    59
    public int Temperature;
moel@1
    60
  }
moel@1
    61
moel@1
    62
  [StructLayout(LayoutKind.Sequential)]
moel@165
    63
  internal struct ADLFanSpeedValue {
moel@1
    64
    public int Size;
moel@1
    65
    public int SpeedType;
moel@1
    66
    public int FanSpeed;
moel@1
    67
    public int Flags;
moel@1
    68
  }
moel@1
    69
moel@1
    70
  [StructLayout(LayoutKind.Sequential)]
moel@165
    71
  internal struct ADLFanSpeedInfo {
moel@1
    72
    public int Size;
moel@1
    73
    public int Flags;
moel@1
    74
    public int MinPercent;
moel@1
    75
    public int MaxPercent;
moel@1
    76
    public int MinRPM;
moel@1
    77
    public int MaxRPM;
moel@1
    78
  }
moel@1
    79
moel@165
    80
  internal class ADL {
moel@1
    81
    public const int ADL_MAX_PATH = 256;
moel@1
    82
    public const int ADL_MAX_ADAPTERS = 40;
moel@1
    83
    public const int ADL_MAX_DISPLAYS = 40;
moel@1
    84
    public const int ADL_MAX_DEVICENAME = 32;
moel@6
    85
    public const int ADL_OK = 0;
moel@15
    86
    public const int ADL_ERR = -1;
moel@1
    87
    public const int ADL_DRIVER_OK = 0;
moel@1
    88
    public const int ADL_MAX_GLSYNC_PORTS = 8;
moel@1
    89
    public const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
moel@1
    90
    public const int ADL_MAX_NUM_DISPLAYMODES = 1024;
moel@1
    91
moel@1
    92
    public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
moel@1
    93
    public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
moel@1
    94
moel@1
    95
    public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = 1;
moel@1
    96
    public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2;
moel@1
    97
    public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4;
moel@1
    98
    public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8;
moel@247
    99
    public const int ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED = 1;
moel@1
   100
moel@333
   101
    public const int ATI_VENDOR_ID = 0x1002;
moel@3
   102
moel@1
   103
    private delegate int ADL_Main_Control_CreateDelegate(
moel@1
   104
      ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
moel@1
   105
    private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info,
moel@1
   106
      int size);
moel@1
   107
moel@1
   108
    public delegate int ADL_Main_Control_DestroyDelegate();
moel@1
   109
    public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate(
moel@1
   110
      ref int numAdapters);    
moel@1
   111
    public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex,
moel@1
   112
      out int adapterID);
moel@12
   113
    public delegate int ADL_Display_AdapterID_GetDelegate(int adapterIndex,
moel@12
   114
      out int adapterID);      	
moel@1
   115
    public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
moel@1
   116
      out int status);
moel@1
   117
    public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate(
moel@1
   118
      int iAdapterIndex, ref ADLPMActivity activity);
moel@1
   119
    public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex,
moel@1
   120
        int thermalControllerIndex, ref ADLTemperature temperature);
moel@1
   121
    public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex,
moel@1
   122
        int thermalControllerIndex, ref	ADLFanSpeedValue fanSpeedValue);
moel@1
   123
    public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
moel@1
   124
      int adapterIndex, int thermalControllerIndex,
moel@1
   125
      ref ADLFanSpeedInfo fanSpeedInfo);
moel@247
   126
    public delegate int ADL_Overdrive5_FanSpeedToDefault_SetDelegate(
moel@247
   127
      int adapterIndex, int thermalControllerIndex);
moel@247
   128
    public delegate int ADL_Overdrive5_FanSpeed_SetDelegate(int adapterIndex,
moel@247
   129
      int thermalControllerIndex, ref	ADLFanSpeedValue fanSpeedValue);
moel@1
   130
moel@1
   131
    private static ADL_Main_Control_CreateDelegate
moel@1
   132
      _ADL_Main_Control_Create;
moel@1
   133
    private static ADL_Adapter_AdapterInfo_GetDelegate
moel@1
   134
      _ADL_Adapter_AdapterInfo_Get;
moel@1
   135
moel@167
   136
    public static ADL_Main_Control_DestroyDelegate
moel@1
   137
      ADL_Main_Control_Destroy;
moel@1
   138
    public static ADL_Adapter_NumberOfAdapters_GetDelegate
moel@1
   139
      ADL_Adapter_NumberOfAdapters_Get;
moel@12
   140
    public static ADL_Adapter_ID_GetDelegate 
moel@12
   141
      _ADL_Adapter_ID_Get;
moel@12
   142
    public static ADL_Display_AdapterID_GetDelegate 
moel@12
   143
      _ADL_Display_AdapterID_Get;
moel@12
   144
    public static ADL_Adapter_Active_GetDelegate 
moel@1
   145
      ADL_Adapter_Active_Get;
moel@1
   146
    public static ADL_Overdrive5_CurrentActivity_GetDelegate
moel@1
   147
      ADL_Overdrive5_CurrentActivity_Get;
moel@1
   148
    public static ADL_Overdrive5_Temperature_GetDelegate
moel@1
   149
      ADL_Overdrive5_Temperature_Get;
moel@1
   150
    public static ADL_Overdrive5_FanSpeed_GetDelegate
moel@1
   151
      ADL_Overdrive5_FanSpeed_Get;
moel@1
   152
    public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
moel@1
   153
      ADL_Overdrive5_FanSpeedInfo_Get;
moel@247
   154
    public static ADL_Overdrive5_FanSpeedToDefault_SetDelegate
moel@247
   155
      ADL_Overdrive5_FanSpeedToDefault_Set;
moel@247
   156
    public static ADL_Overdrive5_FanSpeed_SetDelegate
moel@247
   157
      ADL_Overdrive5_FanSpeed_Set;
moel@1
   158
moel@8
   159
    private static string dllName;
moel@1
   160
moel@1
   161
    private static void GetDelegate<T>(string entryPoint, out T newDelegate)
moel@1
   162
      where T : class 
moel@1
   163
    {
moel@8
   164
      DllImportAttribute attribute = new DllImportAttribute(dllName);
moel@361
   165
      attribute.CallingConvention = CallingConvention.Cdecl;
moel@1
   166
      attribute.PreserveSig = true;
moel@1
   167
      attribute.EntryPoint = entryPoint;
moel@1
   168
      PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
moel@1
   169
    }
moel@1
   170
moel@8
   171
    private static void CreateDelegates(string name) {
moel@195
   172
      int p = (int)Environment.OSVersion.Platform;
moel@8
   173
      if ((p == 4) || (p == 128))
moel@8
   174
        dllName = name + ".so";
moel@8
   175
      else
moel@8
   176
        dllName = name + ".dll";
moel@8
   177
moel@8
   178
      GetDelegate("ADL_Main_Control_Create",
moel@8
   179
        out _ADL_Main_Control_Create);
moel@8
   180
      GetDelegate("ADL_Adapter_AdapterInfo_Get",
moel@8
   181
        out _ADL_Adapter_AdapterInfo_Get);
moel@8
   182
      GetDelegate("ADL_Main_Control_Destroy",
moel@8
   183
        out ADL_Main_Control_Destroy);
moel@8
   184
      GetDelegate("ADL_Adapter_NumberOfAdapters_Get",
moel@8
   185
        out ADL_Adapter_NumberOfAdapters_Get);
moel@8
   186
      GetDelegate("ADL_Adapter_ID_Get",
moel@12
   187
        out _ADL_Adapter_ID_Get);
moel@12
   188
      GetDelegate("ADL_Display_AdapterID_Get", 
moel@12
   189
        out _ADL_Display_AdapterID_Get);
moel@8
   190
      GetDelegate("ADL_Adapter_Active_Get",
moel@8
   191
        out ADL_Adapter_Active_Get);
moel@8
   192
      GetDelegate("ADL_Overdrive5_CurrentActivity_Get",
moel@8
   193
        out ADL_Overdrive5_CurrentActivity_Get);
moel@8
   194
      GetDelegate("ADL_Overdrive5_Temperature_Get",
moel@8
   195
        out ADL_Overdrive5_Temperature_Get);
moel@8
   196
      GetDelegate("ADL_Overdrive5_FanSpeed_Get",
moel@8
   197
        out ADL_Overdrive5_FanSpeed_Get);
moel@8
   198
      GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
moel@8
   199
        out ADL_Overdrive5_FanSpeedInfo_Get);
moel@247
   200
      GetDelegate("ADL_Overdrive5_FanSpeedToDefault_Set",
moel@247
   201
        out ADL_Overdrive5_FanSpeedToDefault_Set);
moel@247
   202
      GetDelegate("ADL_Overdrive5_FanSpeed_Set",
moel@247
   203
        out ADL_Overdrive5_FanSpeed_Set);
moel@8
   204
    }
moel@8
   205
moel@1
   206
    static ADL() {
moel@8
   207
      CreateDelegates("atiadlxx");
moel@1
   208
    }
moel@1
   209
moel@1
   210
    private ADL() { }
moel@1
   211
moel@1
   212
    public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
moel@8
   213
      try {
moel@160
   214
        try {
moel@160
   215
          return _ADL_Main_Control_Create(Main_Memory_Alloc,
moel@160
   216
            enumConnectedAdapters);
moel@160
   217
        } catch {
moel@160
   218
          CreateDelegates("atiadlxy");
moel@160
   219
          return _ADL_Main_Control_Create(Main_Memory_Alloc,
moel@160
   220
            enumConnectedAdapters);
moel@160
   221
        }
moel@160
   222
      } catch {
moel@195
   223
        return ADL_ERR;
moel@8
   224
      }
moel@1
   225
    }
moel@1
   226
moel@1
   227
    public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) {
moel@1
   228
      int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo));
moel@1
   229
      int size = info.Length * elementSize;
moel@1
   230
      IntPtr ptr = Marshal.AllocHGlobal(size);
moel@1
   231
      int result = _ADL_Adapter_AdapterInfo_Get(ptr, size);
moel@1
   232
      for (int i = 0; i < info.Length; i++)
moel@1
   233
        info[i] = (ADLAdapterInfo)
moel@1
   234
          Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize),
moel@1
   235
          typeof(ADLAdapterInfo));
moel@1
   236
      Marshal.FreeHGlobal(ptr);
moel@333
   237
moel@333
   238
      // the ADLAdapterInfo.VendorID field reported by ADL is wrong on 
moel@333
   239
      // Windows systems (parse error), so we fix this here
moel@333
   240
      for (int i = 0; i < info.Length; i++) {
moel@333
   241
        // try Windows UDID format
moel@333
   242
        Match m = Regex.Match(info[i].UDID, "PCI_VEN_([A-Fa-f0-9]{1,4})&.*");
moel@333
   243
        if (m.Success && m.Groups.Count == 2) {
moel@333
   244
          info[i].VendorID = Convert.ToInt32(m.Groups[1].Value, 16);
moel@333
   245
          continue;
moel@333
   246
        }
moel@333
   247
        // if above failed, try Unix UDID format
moel@333
   248
        m = Regex.Match(info[i].UDID, "[0-9]+:[0-9]+:([0-9]+):[0-9]+:[0-9]+");
moel@333
   249
        if (m.Success && m.Groups.Count == 2) {
moel@333
   250
          info[i].VendorID = Convert.ToInt32(m.Groups[1].Value, 10);
moel@333
   251
        }
moel@333
   252
      }
moel@333
   253
moel@1
   254
      return result;
moel@1
   255
    }
moel@1
   256
moel@12
   257
    public static int ADL_Adapter_ID_Get(int adapterIndex,
moel@12
   258
      out int adapterID) {
moel@12
   259
      try {
moel@12
   260
        return _ADL_Adapter_ID_Get(adapterIndex, out adapterID);
moel@12
   261
      } catch (EntryPointNotFoundException) {
moel@12
   262
        try {
moel@12
   263
          return _ADL_Display_AdapterID_Get(adapterIndex, out adapterID);
moel@12
   264
        } catch (EntryPointNotFoundException) {
moel@12
   265
          adapterID = 1;
moel@12
   266
          return ADL_OK;
moel@12
   267
        }
moel@12
   268
      }
moel@12
   269
    }
moel@12
   270
moel@1
   271
    private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
moel@1
   272
moel@200
   273
    // create a Main_Memory_Alloc delegate and keep it alive
moel@200
   274
    private static ADL_Main_Memory_AllocDelegate Main_Memory_Alloc =
moel@200
   275
      delegate(int size) {
moel@200
   276
        return Marshal.AllocHGlobal(size);
moel@200
   277
      };
moel@1
   278
moel@1
   279
    private static void Main_Memory_Free(IntPtr buffer) {
moel@1
   280
      if (IntPtr.Zero != buffer)
moel@1
   281
        Marshal.FreeHGlobal(buffer);
moel@1
   282
    }
moel@1
   283
  }
moel@1
   284
}