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.Collections.Generic; moel@1: using System.Runtime.InteropServices; moel@1: moel@1: namespace OpenHardwareMonitor.Hardware.ATI { moel@1: moel@1: [StructLayout(LayoutKind.Sequential)] moel@1: public 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@1: public int DriverNumber; 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@1: public 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@1: public struct ADLTemperature { moel@1: public int Size; moel@1: public int Temperature; moel@1: } moel@1: moel@1: [StructLayout(LayoutKind.Sequential)] moel@1: public 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@1: public 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@1: public 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@1: public const int ADL_SUCCESS = 0; moel@1: public const int ADL_FAIL = -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@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@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@1: 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@1: public static ADL_Adapter_ID_GetDelegate moel@1: ADL_Adapter_ID_Get; moel@1: 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@1: private static string GetDllName() { moel@1: int p = (int)System.Environment.OSVersion.Platform; moel@1: if ((p == 4) || (p == 128)) { moel@1: if (IntPtr.Size == 4) { moel@1: return "atiadlxy.so"; moel@1: } else { moel@1: return "atiadlxx.so"; moel@1: } moel@1: } else { moel@1: if (IntPtr.Size == 4) { moel@1: return "atiadlxy.dll"; moel@1: } else { moel@1: return "atiadlxx.dll"; moel@1: } moel@1: } moel@1: } moel@1: moel@1: private static void GetDelegate(string entryPoint, out T newDelegate) moel@1: where T : class moel@1: { moel@1: DllImportAttribute attribute = new DllImportAttribute(GetDllName()); 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@1: static ADL() { moel@1: GetDelegate("ADL_Main_Control_Create", moel@1: out _ADL_Main_Control_Create); moel@1: GetDelegate("ADL_Adapter_AdapterInfo_Get", moel@1: out _ADL_Adapter_AdapterInfo_Get); moel@1: GetDelegate("ADL_Main_Control_Destroy", moel@1: out ADL_Main_Control_Destroy); moel@1: GetDelegate("ADL_Adapter_NumberOfAdapters_Get", moel@1: out ADL_Adapter_NumberOfAdapters_Get); moel@1: GetDelegate("ADL_Adapter_ID_Get", moel@1: out ADL_Adapter_ID_Get); moel@1: GetDelegate("ADL_Adapter_Active_Get", moel@1: out ADL_Adapter_Active_Get); moel@1: GetDelegate("ADL_Overdrive5_CurrentActivity_Get", moel@1: out ADL_Overdrive5_CurrentActivity_Get); moel@1: GetDelegate("ADL_Overdrive5_Temperature_Get", moel@1: out ADL_Overdrive5_Temperature_Get); moel@1: GetDelegate("ADL_Overdrive5_FanSpeed_Get", moel@1: out ADL_Overdrive5_FanSpeed_Get); moel@1: GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get", moel@1: out ADL_Overdrive5_FanSpeedInfo_Get); moel@1: } moel@1: moel@1: private ADL() { } moel@1: moel@1: public static int ADL_Main_Control_Create(int enumConnectedAdapters) { moel@1: return _ADL_Main_Control_Create(Main_Memory_Alloc, enumConnectedAdapters); 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@1: private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size); moel@1: moel@1: private static IntPtr Main_Memory_Alloc(int size) { moel@1: return Marshal.AllocHGlobal(size);; moel@1: } 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: }