moel@1: /* moel@1: moel@1: Version: MPL 1.1/GPL 2.0/LGPL 2.1 moel@1: moel@1: The contents of this file are subject to the Mozilla Public License Version moel@1: 1.1 (the "License"); you may not use this file except in compliance with moel@1: the License. You may obtain a copy of the License at moel@1: moel@1: http://www.mozilla.org/MPL/ moel@1: moel@1: Software distributed under the License is distributed on an "AS IS" basis, moel@1: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License moel@1: for the specific language governing rights and limitations under the License. moel@1: moel@1: The Original Code is the Open Hardware Monitor code. moel@1: moel@1: The Initial Developer of the Original Code is moel@1: Michael Möller . moel@1: Portions created by the Initial Developer are Copyright (C) 2009-2010 moel@1: the Initial Developer. All Rights Reserved. moel@1: moel@1: Contributor(s): moel@1: moel@1: Alternatively, the contents of this file may be used under the terms of moel@1: either the GNU General Public License Version 2 or later (the "GPL"), or moel@1: the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), moel@1: in which case the provisions of the GPL or the LGPL are applicable instead moel@1: of those above. If you wish to allow use of your version of this file only moel@1: under the terms of either the GPL or the LGPL, and not to allow others to moel@1: use your version of this file under the terms of the MPL, indicate your moel@1: decision by deleting the provisions above and replace them with the notice moel@1: and other provisions required by the GPL or the LGPL. If you do not delete moel@1: the provisions above, a recipient may use your version of this file under moel@1: the terms of any one of the MPL, the GPL or the LGPL. moel@1: moel@1: */ moel@1: moel@1: using System; moel@1: using System.Runtime.InteropServices; moel@1: moel@1: namespace OpenHardwareMonitor.Hardware.ATI { moel@1: moel@1: [StructLayout(LayoutKind.Sequential)] moel@165: internal struct ADLAdapterInfo { moel@1: public int Size; moel@1: public int AdapterIndex; moel@1: [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)] moel@1: public string UDID; moel@1: public int BusNumber; moel@3: public int DeviceNumber; moel@1: public int FunctionNumber; moel@1: public int VendorID; moel@1: [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)] moel@1: public string AdapterName; moel@1: [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)] moel@1: public string DisplayName; moel@1: public int Present; moel@1: public int Exist; moel@1: [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)] moel@1: public string DriverPath; moel@1: [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)] moel@1: public string DriverPathExt; moel@1: [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)] moel@1: public string PNPString; moel@1: public int OSDisplayIndex; moel@1: } moel@1: moel@1: [StructLayout(LayoutKind.Sequential)] moel@165: internal struct ADLPMActivity { moel@1: public int Size; moel@1: public int EngineClock; moel@1: public int MemoryClock; moel@1: public int Vddc; moel@1: public int ActivityPercent; moel@1: public int CurrentPerformanceLevel; moel@1: public int CurrentBusSpeed; moel@1: public int CurrentBusLanes; moel@1: public int MaximumBusLanes; moel@1: public int Reserved; moel@1: } moel@1: moel@1: [StructLayout(LayoutKind.Sequential)] moel@165: internal struct ADLTemperature { moel@1: public int Size; moel@1: public int Temperature; moel@1: } moel@1: moel@1: [StructLayout(LayoutKind.Sequential)] moel@165: internal struct ADLFanSpeedValue { moel@1: public int Size; moel@1: public int SpeedType; moel@1: public int FanSpeed; moel@1: public int Flags; moel@1: } moel@1: moel@1: [StructLayout(LayoutKind.Sequential)] moel@165: internal struct ADLFanSpeedInfo { moel@1: public int Size; moel@1: public int Flags; moel@1: public int MinPercent; moel@1: public int MaxPercent; moel@1: public int MinRPM; moel@1: public int MaxRPM; moel@1: } moel@1: moel@165: internal class ADL { moel@1: public const int ADL_MAX_PATH = 256; moel@1: public const int ADL_MAX_ADAPTERS = 40; moel@1: public const int ADL_MAX_DISPLAYS = 40; moel@1: public const int ADL_MAX_DEVICENAME = 32; moel@6: public const int ADL_OK = 0; moel@15: public const int ADL_ERR = -1; moel@1: public const int ADL_DRIVER_OK = 0; moel@1: public const int ADL_MAX_GLSYNC_PORTS = 8; moel@1: public const int ADL_MAX_GLSYNC_PORT_LEDS = 8; moel@1: public const int ADL_MAX_NUM_DISPLAYMODES = 1024; moel@1: moel@1: public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1; moel@1: public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2; moel@1: moel@1: public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = 1; moel@1: public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2; moel@1: public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4; moel@1: public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8; moel@1: moel@3: public const int ATI_VENDOR_ID1 = 1002; moel@3: public const int ATI_VENDOR_ID2 = 0x1002; moel@3: moel@1: private delegate int ADL_Main_Control_CreateDelegate( moel@1: ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters); moel@1: private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info, moel@1: int size); moel@1: moel@1: public delegate int ADL_Main_Control_DestroyDelegate(); moel@1: public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate( moel@1: ref int numAdapters); moel@1: public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex, moel@1: out int adapterID); moel@12: public delegate int ADL_Display_AdapterID_GetDelegate(int adapterIndex, moel@12: out int adapterID); moel@1: public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex, moel@1: out int status); moel@1: public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate( moel@1: int iAdapterIndex, ref ADLPMActivity activity); moel@1: public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex, moel@1: int thermalControllerIndex, ref ADLTemperature temperature); moel@1: public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex, moel@1: int thermalControllerIndex, ref ADLFanSpeedValue fanSpeedValue); moel@1: public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate( moel@1: int adapterIndex, int thermalControllerIndex, moel@1: ref ADLFanSpeedInfo fanSpeedInfo); moel@1: moel@1: private static ADL_Main_Control_CreateDelegate moel@1: _ADL_Main_Control_Create; moel@1: private static ADL_Adapter_AdapterInfo_GetDelegate moel@1: _ADL_Adapter_AdapterInfo_Get; moel@1: moel@167: public static ADL_Main_Control_DestroyDelegate moel@1: ADL_Main_Control_Destroy; moel@1: public static ADL_Adapter_NumberOfAdapters_GetDelegate moel@1: ADL_Adapter_NumberOfAdapters_Get; moel@12: public static ADL_Adapter_ID_GetDelegate moel@12: _ADL_Adapter_ID_Get; moel@12: public static ADL_Display_AdapterID_GetDelegate moel@12: _ADL_Display_AdapterID_Get; moel@12: public static ADL_Adapter_Active_GetDelegate moel@1: ADL_Adapter_Active_Get; moel@1: public static ADL_Overdrive5_CurrentActivity_GetDelegate moel@1: ADL_Overdrive5_CurrentActivity_Get; moel@1: public static ADL_Overdrive5_Temperature_GetDelegate moel@1: ADL_Overdrive5_Temperature_Get; moel@1: public static ADL_Overdrive5_FanSpeed_GetDelegate moel@1: ADL_Overdrive5_FanSpeed_Get; moel@1: public static ADL_Overdrive5_FanSpeedInfo_GetDelegate moel@1: ADL_Overdrive5_FanSpeedInfo_Get; moel@1: moel@8: private static string dllName; moel@1: moel@1: private static void GetDelegate(string entryPoint, out T newDelegate) moel@1: where T : class moel@1: { moel@8: DllImportAttribute attribute = new DllImportAttribute(dllName); moel@1: attribute.CallingConvention = CallingConvention.StdCall; moel@1: attribute.PreserveSig = true; moel@1: attribute.EntryPoint = entryPoint; moel@1: PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate); moel@1: } moel@1: moel@8: private static void CreateDelegates(string name) { moel@195: int p = (int)Environment.OSVersion.Platform; moel@8: if ((p == 4) || (p == 128)) moel@8: dllName = name + ".so"; moel@8: else moel@8: dllName = name + ".dll"; moel@8: moel@8: GetDelegate("ADL_Main_Control_Create", moel@8: out _ADL_Main_Control_Create); moel@8: GetDelegate("ADL_Adapter_AdapterInfo_Get", moel@8: out _ADL_Adapter_AdapterInfo_Get); moel@8: GetDelegate("ADL_Main_Control_Destroy", moel@8: out ADL_Main_Control_Destroy); moel@8: GetDelegate("ADL_Adapter_NumberOfAdapters_Get", moel@8: out ADL_Adapter_NumberOfAdapters_Get); moel@8: GetDelegate("ADL_Adapter_ID_Get", moel@12: out _ADL_Adapter_ID_Get); moel@12: GetDelegate("ADL_Display_AdapterID_Get", moel@12: out _ADL_Display_AdapterID_Get); moel@8: GetDelegate("ADL_Adapter_Active_Get", moel@8: out ADL_Adapter_Active_Get); moel@8: GetDelegate("ADL_Overdrive5_CurrentActivity_Get", moel@8: out ADL_Overdrive5_CurrentActivity_Get); moel@8: GetDelegate("ADL_Overdrive5_Temperature_Get", moel@8: out ADL_Overdrive5_Temperature_Get); moel@8: GetDelegate("ADL_Overdrive5_FanSpeed_Get", moel@8: out ADL_Overdrive5_FanSpeed_Get); moel@8: GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get", moel@8: out ADL_Overdrive5_FanSpeedInfo_Get); moel@8: } moel@8: moel@1: static ADL() { moel@8: CreateDelegates("atiadlxx"); moel@1: } moel@1: moel@1: private ADL() { } moel@1: moel@1: public static int ADL_Main_Control_Create(int enumConnectedAdapters) { moel@8: try { moel@160: try { moel@160: return _ADL_Main_Control_Create(Main_Memory_Alloc, moel@160: enumConnectedAdapters); moel@160: } catch { moel@160: CreateDelegates("atiadlxy"); moel@160: return _ADL_Main_Control_Create(Main_Memory_Alloc, moel@160: enumConnectedAdapters); moel@160: } moel@160: } catch { moel@195: return ADL_ERR; moel@8: } moel@1: } moel@1: moel@1: public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) { moel@1: int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo)); moel@1: int size = info.Length * elementSize; moel@1: IntPtr ptr = Marshal.AllocHGlobal(size); moel@1: int result = _ADL_Adapter_AdapterInfo_Get(ptr, size); moel@1: for (int i = 0; i < info.Length; i++) moel@1: info[i] = (ADLAdapterInfo) moel@1: Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize), moel@1: typeof(ADLAdapterInfo)); moel@1: Marshal.FreeHGlobal(ptr); moel@1: return result; moel@1: } moel@1: moel@12: public static int ADL_Adapter_ID_Get(int adapterIndex, moel@12: out int adapterID) { moel@12: try { moel@12: return _ADL_Adapter_ID_Get(adapterIndex, out adapterID); moel@12: } catch (EntryPointNotFoundException) { moel@12: try { moel@12: return _ADL_Display_AdapterID_Get(adapterIndex, out adapterID); moel@12: } catch (EntryPointNotFoundException) { moel@12: adapterID = 1; moel@12: return ADL_OK; moel@12: } moel@12: } moel@12: } moel@12: moel@1: private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size); moel@1: moel@200: // create a Main_Memory_Alloc delegate and keep it alive moel@200: private static ADL_Main_Memory_AllocDelegate Main_Memory_Alloc = moel@200: delegate(int size) { moel@200: return Marshal.AllocHGlobal(size); moel@200: }; moel@1: moel@1: private static void Main_Memory_Free(IntPtr buffer) { moel@1: if (IntPtr.Zero != buffer) moel@1: Marshal.FreeHGlobal(buffer); moel@1: } moel@1: } moel@1: }