Changeset 414 for trunk/src/helpers/acpih.c
- Timestamp:
- Feb 26, 2013, 3:44:10 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/acpih.c
r380 r414 17 17 18 18 /* 19 * Copyright (C) 2006-20 09Paul Ratcliffe.19 * Copyright (C) 2006-2013 Paul Ratcliffe. 20 20 * This file is part of the "XWorkplace helpers" source package. 21 21 * This is free software; you can redistribute it and/or modify … … 40 40 #include "setup.h" // code generation and debugging options 41 41 42 #include "helpers\apmh.h" // @@added V1.0.9 (2012-02-20) [slevine] 42 43 #include "helpers\acpih.h" 43 44 #include "helpers\standards.h" … … 51 52 HMODULE G_hmodACPI = NULLHANDLE; 52 53 ULONG G_ulCount = 0; 54 // @@added V1.0.9 (2012-02-20) [slevine]: additional ACPI support, code from David Azarewicz 55 ACPI_HANDLE G_ahAC = 0; 56 #define MAX_BATTERY_COUNT 4 57 ACPI_HANDLE G_ahBat[MAX_BATTERY_COUNT]; 58 ULONG G_uiBatteryCount = 0; 59 ULONG G_uiAlreadyWalked = 0; 53 60 54 61 ACPISTARTAPI *pAcpiStartApi = NULL; … … 56 63 ACPIGOTOSLEEP *pAcpiGoToSleep = NULL; 57 64 65 ACPITKGETOBJECTINFOALLOC *pAcpiTkGetObjectInfoAlloc = NULL; 66 ACPITKGETHANDLE *pAcpiTkGetHandle = NULL; 67 ACPITKOSFREE *pAcpiTkOsFree = NULL; 68 ACPITKWALKNAMESPACE *pAcpiTkWalkNamespace = NULL; 69 ACPITKEVALUATEOBJECT *pAcpiTkEvaluateObject = NULL; 70 // @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support 71 ACPITKPREPARETOSLEEP *pAcpiTkPrepareToSleep = NULL; 72 58 73 /* 59 74 *@@category: Helpers\Control program helpers\ACPI … … 71 86 72 87 if (!G_hmodACPI) 88 { 73 89 if (!(arc = DosLoadModule(NULL, 74 90 0, … … 82 98 if (!arc) 83 99 arc = DosQueryProcAddr(G_hmodACPI, 84 ORD_ACPIENDAPI,85 NULL,86 (PFN *) &pAcpiEndApi);100 ORD_ACPIENDAPI, 101 NULL, 102 (PFN *) &pAcpiEndApi); 87 103 88 104 if (!arc) 89 105 arc = DosQueryProcAddr(G_hmodACPI, 90 ORD_ACPIGOTOSLEEP,91 NULL,92 (PFN *) &pAcpiGoToSleep);106 ORD_ACPIGOTOSLEEP, 107 NULL, 108 (PFN *) &pAcpiGoToSleep); 93 109 if (arc) 94 110 { … … 100 116 return(arc); 101 117 } 102 } 118 119 // @@added V1.0.9 (2012-02-20) [slevine]: additional ACPI support, code from David Azarewicz 120 DosQueryProcAddr(G_hmodACPI, ORD_ACPITKGETOBJECTINFOALLOC, 121 NULL, (PFN *) &pAcpiTkGetObjectInfoAlloc); 122 DosQueryProcAddr(G_hmodACPI, ORD_ACPITKGETHANDLE, 123 NULL, (PFN *) &pAcpiTkGetHandle); 124 DosQueryProcAddr(G_hmodACPI, ORD_ACPITKOSFREE, 125 NULL, (PFN *) &pAcpiTkOsFree); 126 DosQueryProcAddr(G_hmodACPI, ORD_ACPITKWALKNAMESPACE, 127 NULL, (PFN *) &pAcpiTkWalkNamespace); 128 DosQueryProcAddr(G_hmodACPI, ORD_ACPITKEVALUATEOBJECT, 129 NULL, (PFN *) &pAcpiTkEvaluateObject); 130 // @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support 131 DosQueryProcAddr(G_hmodACPI, ORD_ACPITKPREPARETOSLEEP, 132 NULL, (PFN *) &pAcpiTkPrepareToSleep); 133 } 134 } 103 135 104 136 if (arc) … … 107 139 { 108 140 G_ulCount++; 141 142 // @@added V1.0.9 (2012-12-10) [slevine]: use AcpiTkPrepareToSleep rather than workaround 143 /* This function does not exist in older versions of acpi 144 * As a result the shutdown attempt will usually hang because 145 * the required code has not been committed into memory. 146 */ 147 if (pAcpiTkPrepareToSleep) 148 pAcpiTkPrepareToSleep(ACPI_STATE_S5); 149 109 150 return(pAcpiStartApi(phACPI)); 110 151 } … … 131 172 pAcpiEndApi = NULL; 132 173 pAcpiGoToSleep = NULL; 174 // @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support 175 pAcpiTkPrepareToSleep = NULL; 133 176 } 134 177 } … … 147 190 } 148 191 192 193 /** 194 *@@ AcpiCallbackWidget: 195 * ACPI callback helper for battery and power status queries. 196 * Code provided by David Azarewicz 197 *@@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz 198 */ 199 200 #define AE_DEPTH AE_OK 201 202 ACPI_STATUS AcpiCallbackWidget( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue ) 203 { 204 ACPI_DEVICE_INFO *pDevInfo = NULL; 205 ACPI_STATUS Status = pAcpiTkGetObjectInfoAlloc(ObjHandle, &pDevInfo); 206 207 if (Status == AE_OK) 208 { 209 if (pDevInfo->Type != ACPI_TYPE_DEVICE) 210 return AE_DEPTH; 211 212 if (!(pDevInfo->Valid & ACPI_VALID_HID)) 213 return AE_DEPTH; 214 215 if (!pDevInfo->HardwareId.String) 216 return AE_DEPTH; 217 218 if (strncmp(pDevInfo->HardwareId.String, "ACPI0003", 8) == 0) 219 { /* AC Power */ 220 Status = pAcpiTkGetHandle(ObjHandle, "_PSR", &G_ahAC); 221 if (Status) 222 G_ahAC = 0; 223 224 return AE_DEPTH; 225 } 226 227 if (strncmp(pDevInfo->HardwareId.String, "PNP0C0A", 7) == 0) 228 { /* Smart battery */ 229 if (G_uiBatteryCount < MAX_BATTERY_COUNT) 230 G_ahBat[G_uiBatteryCount++] = ObjHandle; 231 232 return AE_DEPTH; 233 } 234 } 235 236 if (pDevInfo) 237 pAcpiTkOsFree(pDevInfo); 238 239 return AE_OK; 240 } 241 242 /** 243 *@@ acpihGetPowerStatus: 244 * Returns power and battery status in caller provided buffers. 245 * Returns zero if success, non-zero if fail. 246 * Code provided by David Azarewicz 247 *@@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz 248 */ 249 250 APIRET acpihGetPowerStatus(PAPM pApm, PBOOL pfChanged) 251 { 252 ACPI_STATUS Status; 253 ACPI_BUFFER Result; 254 ACPI_OBJECT *Obj, Object[20]; 255 UINT32 uiI; 256 ULONG ulTmp, BRemaining, LastFull; 257 BOOL fChanged; 258 259 /* Make sure all the functions we need have valid pointers. 260 * @@added V1.0.9 (2012-02-25) [dazarewicz]: additional ACPI support 261 */ 262 if ( (pAcpiTkWalkNamespace == NULL) 263 || (pAcpiTkGetObjectInfoAlloc == NULL) 264 || (pAcpiTkGetHandle == NULL) 265 || (pAcpiTkOsFree == NULL) 266 || (pAcpiTkEvaluateObject == NULL) 267 || (pApm == NULL) 268 ) 269 return 1; 270 271 if (!G_uiAlreadyWalked) 272 { 273 Status = pAcpiTkWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 274 ACPI_UINT32_MAX, AcpiCallbackWidget, 275 pApm, NULL); 276 G_uiAlreadyWalked = 1; 277 } 278 279 fChanged = FALSE; 280 281 // VAC 3.08 long long compatibility support 282 #ifdef INCL_LONGLONG // VAC 3.6.5 - compiler supports long long 283 #define OBJECT_VALUE(index) (Object[index].Integer.Value) 284 #define OBJ_VALUE(index) (Obj[index].Integer.Value) 285 #else // VAC 3.08 - compiler does not support long long 286 #define OBJECT_VALUE(index) (Object[index].Integer.Value.ulLo) 287 #define OBJ_VALUE(index) (Obj[index].Integer.Value.ulLo) 288 #endif 289 290 if (G_ahAC) 291 { 292 // Have _PSR 293 Result.Length = sizeof(Object); 294 Result.Pointer = Object; 295 Status = pAcpiTkEvaluateObject(G_ahAC, NULL, NULL, &Result); 296 if (Status != AE_OK) 297 ulTmp = 2; // assume on backup power 298 else if (Object[0].Type != ACPI_TYPE_INTEGER) 299 ulTmp = 2; // assume on backup power 300 else 301 ulTmp = (UINT32)OBJECT_VALUE(0); 302 303 if (pApm->fUsingAC != (BYTE) ulTmp) 304 { 305 pApm->fUsingAC = (BYTE) ulTmp; 306 fChanged = TRUE; 307 } 308 } 309 310 for (uiI=0; uiI < G_uiBatteryCount; uiI++) 311 { 312 if (G_ahBat[uiI] == 0) 313 continue; 314 315 Result.Length = sizeof(Object); 316 Result.Pointer = Object; 317 // Get battery info 318 Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BIF", NULL, &Result); 319 if (Status != AE_OK) 320 { 321 G_ahBat[uiI] = 0; 322 continue; 323 } 324 325 Obj = Result.Pointer; 326 Obj = (ACPI_OBJECT *)Obj[0].Package.Elements; // Battery info package 327 LastFull = (UINT32)OBJ_VALUE(2); 328 if (LastFull == 0xffffffff) 329 { 330 G_ahBat[uiI] = 0; 331 continue; 332 } 333 334 Result.Length = sizeof(Object); 335 Result.Pointer = Object; 336 // Get battery status 337 Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BST", NULL, &Result); 338 if (Status != AE_OK) 339 { 340 G_ahBat[uiI] = 0; 341 continue; 342 } 343 344 Obj = Result.Pointer; 345 Obj = (ACPI_OBJECT *)Obj[0].Package.Elements; // Battery status package 346 347 // If voltage known 348 if ((UINT32)OBJ_VALUE(2) != 0xffffffff) 349 BRemaining = (UINT32)OBJ_VALUE(2); 350 351 // If battery units are mWh or mAh 352 // If not, it is a percentage 353 if ((UINT32)OBJ_VALUE(0) != 0xffffffff) 354 { 355 if (BRemaining > (LastFull >> 1)) // > 50% is high. < 50% is low 356 ulTmp = 1; // High 357 else 358 ulTmp = 2; // Low 359 360 if (OBJ_VALUE(0) & 4) 361 ulTmp = 2; // Critical 362 363 // If battery charging - it can't be critical 364 if (OBJ_VALUE(0) & 2) 365 ulTmp = 3; // Charging 366 367 if (pApm->bBatteryStatus != ulTmp) 368 { 369 pApm->bBatteryStatus = (BYTE)ulTmp; 370 fChanged = TRUE; 371 } 372 } 373 374 ulTmp = (BRemaining*100) / LastFull; 375 if (ulTmp > 100) 376 ulTmp = 100; 377 378 if (pApm->bBatteryLife != ulTmp) 379 { 380 pApm->bBatteryLife = (BYTE) ulTmp; 381 fChanged = TRUE; 382 } 383 } 384 385 if (pfChanged) 386 *pfChanged = fChanged; 387 388 pApm->fAlreadyRead = FALSE; 389 return 0; 390 391 #undef OBJECT_VALUE 392 #undef OBJ_VALUE 393 } 394 395 /* 396 *@@ acpihHasBattery: 397 * quick'n'dirty helper which returns TRUE only 398 * if ACPI is supported on the system and the 399 * system actually has a battery (i.e. is a laptop). 400 * Code provided by David Azarewicz. 401 * @@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz 402 */ 403 BOOL acpihHasBattery(VOID) 404 { 405 BOOL brc = FALSE; 406 ACPI_API_HANDLE hACPI; 407 APM Apm; 408 409 if (!acpihOpen(&hACPI)) 410 { 411 Apm.bBatteryStatus = 0xff; 412 if (!acpihGetPowerStatus(&Apm, NULL)) 413 brc = (Apm.bBatteryStatus != 0xFF); 414 415 acpihClose(&hACPI); 416 } 417 418 return brc; 419 } 420
Note:
See TracChangeset
for help on using the changeset viewer.