Hardware/ATI/ADL.cs
author moel.mich
Fri, 29 Jan 2010 19:20:44 +0000
changeset 8 39067efce486
parent 6 56c9d6c8c08b
child 12 a105b5eee02f
permissions -rw-r--r--
Fixed ADL dll loading. The name of the dll is always atiadlxx, except when running as 32-bit app on 64-bit systems (atiadlxy in that case).
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2010
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.Runtime.InteropServices;
    41 
    42 namespace OpenHardwareMonitor.Hardware.ATI {
    43   
    44   [StructLayout(LayoutKind.Sequential)]
    45   public struct ADLAdapterInfo {
    46     public int Size;
    47     public int AdapterIndex;
    48     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    49     public string UDID;
    50     public int BusNumber;
    51     public int DeviceNumber;
    52     public int FunctionNumber;
    53     public int VendorID;
    54     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    55     public string AdapterName;
    56     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    57     public string DisplayName;
    58     public int Present;
    59     public int Exist;
    60     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    61     public string DriverPath;
    62     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    63     public string DriverPathExt;
    64     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
    65     public string PNPString;
    66     public int OSDisplayIndex;
    67   }
    68 
    69   [StructLayout(LayoutKind.Sequential)]
    70   public struct ADLPMActivity {
    71     public int Size;
    72     public int EngineClock;
    73     public int MemoryClock;
    74     public int Vddc;
    75     public int ActivityPercent;
    76     public int CurrentPerformanceLevel;
    77     public int CurrentBusSpeed;
    78     public int CurrentBusLanes;
    79     public int MaximumBusLanes;
    80     public int Reserved;
    81   }
    82 
    83   [StructLayout(LayoutKind.Sequential)]
    84   public struct ADLTemperature {
    85     public int Size;
    86     public int Temperature;
    87   }
    88 
    89   [StructLayout(LayoutKind.Sequential)]
    90   public struct ADLFanSpeedValue {
    91     public int Size;
    92     public int SpeedType;
    93     public int FanSpeed;
    94     public int Flags;
    95   }
    96 
    97   [StructLayout(LayoutKind.Sequential)]
    98   public struct ADLFanSpeedInfo {
    99     public int Size;
   100     public int Flags;
   101     public int MinPercent;
   102     public int MaxPercent;
   103     public int MinRPM;
   104     public int MaxRPM;
   105   }
   106 
   107   public class ADL {
   108     public const int ADL_MAX_PATH = 256;
   109     public const int ADL_MAX_ADAPTERS = 40;
   110     public const int ADL_MAX_DISPLAYS = 40;
   111     public const int ADL_MAX_DEVICENAME = 32;
   112     public const int ADL_OK = 0;
   113     public const int ADL_FAIL = -1;
   114     public const int ADL_DRIVER_OK = 0;
   115     public const int ADL_MAX_GLSYNC_PORTS = 8;
   116     public const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
   117     public const int ADL_MAX_NUM_DISPLAYMODES = 1024;
   118 
   119     public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
   120     public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
   121 
   122     public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = 1;
   123     public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2;
   124     public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4;
   125     public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8;
   126 
   127     public const int ATI_VENDOR_ID1 = 1002;
   128     public const int ATI_VENDOR_ID2 = 0x1002;
   129 
   130     private delegate int ADL_Main_Control_CreateDelegate(
   131       ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
   132     private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info,
   133       int size);
   134 
   135     public delegate int ADL_Main_Control_DestroyDelegate();
   136     public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate(
   137       ref int numAdapters);    
   138     public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex,
   139       out int adapterID);
   140     public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
   141       out int status);
   142     public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate(
   143       int iAdapterIndex, ref ADLPMActivity activity);
   144     public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex,
   145         int thermalControllerIndex, ref ADLTemperature temperature);
   146     public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex,
   147         int thermalControllerIndex, ref	ADLFanSpeedValue fanSpeedValue);
   148     public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
   149       int adapterIndex, int thermalControllerIndex,
   150       ref ADLFanSpeedInfo fanSpeedInfo);
   151 
   152     private static ADL_Main_Control_CreateDelegate
   153       _ADL_Main_Control_Create;
   154     private static ADL_Adapter_AdapterInfo_GetDelegate
   155       _ADL_Adapter_AdapterInfo_Get;
   156 
   157     public static ADL_Main_Control_DestroyDelegate
   158       ADL_Main_Control_Destroy;
   159     public static ADL_Adapter_NumberOfAdapters_GetDelegate
   160       ADL_Adapter_NumberOfAdapters_Get;
   161     public static ADL_Adapter_ID_GetDelegate
   162       ADL_Adapter_ID_Get;
   163     public static ADL_Adapter_Active_GetDelegate
   164       ADL_Adapter_Active_Get;
   165     public static ADL_Overdrive5_CurrentActivity_GetDelegate
   166       ADL_Overdrive5_CurrentActivity_Get;
   167     public static ADL_Overdrive5_Temperature_GetDelegate
   168       ADL_Overdrive5_Temperature_Get;
   169     public static ADL_Overdrive5_FanSpeed_GetDelegate
   170       ADL_Overdrive5_FanSpeed_Get;
   171     public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
   172       ADL_Overdrive5_FanSpeedInfo_Get;
   173 
   174     private static string dllName;
   175 
   176     private static void GetDelegate<T>(string entryPoint, out T newDelegate)
   177       where T : class 
   178     {
   179       DllImportAttribute attribute = new DllImportAttribute(dllName);
   180       attribute.CallingConvention = CallingConvention.StdCall;
   181       attribute.PreserveSig = true;
   182       attribute.EntryPoint = entryPoint;
   183       PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
   184     }
   185 
   186     private static void CreateDelegates(string name) {
   187       int p = (int)System.Environment.OSVersion.Platform;
   188       if ((p == 4) || (p == 128))
   189         dllName = name + ".so";
   190       else
   191         dllName = name + ".dll";
   192 
   193       GetDelegate("ADL_Main_Control_Create",
   194         out _ADL_Main_Control_Create);
   195       GetDelegate("ADL_Adapter_AdapterInfo_Get",
   196         out _ADL_Adapter_AdapterInfo_Get);
   197       GetDelegate("ADL_Main_Control_Destroy",
   198         out ADL_Main_Control_Destroy);
   199       GetDelegate("ADL_Adapter_NumberOfAdapters_Get",
   200         out ADL_Adapter_NumberOfAdapters_Get);
   201       GetDelegate("ADL_Adapter_ID_Get",
   202         out ADL_Adapter_ID_Get);
   203       GetDelegate("ADL_Adapter_Active_Get",
   204         out ADL_Adapter_Active_Get);
   205       GetDelegate("ADL_Overdrive5_CurrentActivity_Get",
   206         out ADL_Overdrive5_CurrentActivity_Get);
   207       GetDelegate("ADL_Overdrive5_Temperature_Get",
   208         out ADL_Overdrive5_Temperature_Get);
   209       GetDelegate("ADL_Overdrive5_FanSpeed_Get",
   210         out ADL_Overdrive5_FanSpeed_Get);
   211       GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
   212         out ADL_Overdrive5_FanSpeedInfo_Get);
   213     }
   214 
   215     static ADL() {
   216       CreateDelegates("atiadlxx");
   217     }
   218 
   219     private ADL() { }
   220 
   221     public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
   222       try {
   223         return _ADL_Main_Control_Create(Main_Memory_Alloc,
   224           enumConnectedAdapters);
   225       } catch (DllNotFoundException) {
   226         CreateDelegates("atiadlxy");
   227         return _ADL_Main_Control_Create(Main_Memory_Alloc,
   228           enumConnectedAdapters);
   229       }
   230     }
   231 
   232     public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) {
   233       int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo));
   234       int size = info.Length * elementSize;
   235       IntPtr ptr = Marshal.AllocHGlobal(size);
   236       int result = _ADL_Adapter_AdapterInfo_Get(ptr, size);
   237       for (int i = 0; i < info.Length; i++)
   238         info[i] = (ADLAdapterInfo)
   239           Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize),
   240           typeof(ADLAdapterInfo));
   241       Marshal.FreeHGlobal(ptr);
   242       return result;
   243     }
   244 
   245     private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
   246 
   247     private static IntPtr Main_Memory_Alloc(int size) {
   248       return Marshal.AllocHGlobal(size);;
   249     }
   250 
   251     private static void Main_Memory_Free(IntPtr buffer) {
   252       if (IntPtr.Zero != buffer)
   253         Marshal.FreeHGlobal(buffer);
   254     }
   255   }
   256 }