/* *@@sourcefile apmh.c: * contains helpers for accessing APM.SYS (Advanced Power Management). * * These functions have been moved to this file with V0.9.14 * and were previously used in XWorkplace code. * * Usage: All OS/2 programs. * * Function prefixes: * -- apmh* APM helper functions * * Note: Version numbering in this file relates to XWorkplace version * numbering. * *@@header "helpers\apmh.h" *@@added V0.9.14 (2001-08-01) [umoeller] */ /* * Copyright (C) 1998-2001 Ulrich M”ller. * This file is part of the "XWorkplace helpers" source package. * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, in version 2 as it comes in the * "COPYING" file of the XWorkplace main distribution. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #define OS2EMX_PLAIN_CHAR // this is needed for "os2emx.h"; if this is defined, // emx will define PSZ as _signed_ char, otherwise // as unsigned char #define INCL_DOSDEVICES #define INCL_DOSDEVIOCTL #define INCL_DOSERRORS #include #include "setup.h" // code generation and debugging options #include "helpers\apmh.h" #include "helpers\standards.h" /* *@@category: Helpers\Control program helpers\Advanced Power Management * See apmh.c. */ /* ****************************************************************** * * APM monitor * ********************************************************************/ /* *@@ apmhIOCtl: * shortcut for DosDevIOCtl on the APM.SYS driver. */ APIRET apmhIOCtl(HFILE hfAPMSys, ULONG ulFunction, PVOID pvParamPck, ULONG cbParamPck) { APIRET arc; APMGIO_DPKT DataPacket; ULONG ulRetSize = sizeof(DataPacket); DataPacket.ReturnCode = GIOERR_PowerNoError; if (!(arc = DosDevIOCtl(hfAPMSys, APMGIO_Category, ulFunction, pvParamPck, cbParamPck, &cbParamPck, &DataPacket, sizeof(DataPacket), &ulRetSize))) if (DataPacket.ReturnCode) arc = DataPacket.ReturnCode + 10000; return arc; } /* *@@ apmhOpen: * opens the APM.SYS driver and creates * an APM structure in *ppApm. * * In the APM structure, the version fields are * set to the version flags returned from the * BIOS and APM.SYS itself. */ APIRET apmhOpen(PAPM *ppApm) { // open APM.SYS APIRET arc; HFILE hfAPMSys = NULLHANDLE; ULONG ulAction; if (!(arc = DosOpen("\\DEV\\APM$", &hfAPMSys, &ulAction, 0, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL))) { // query version of APM-BIOS and APM driver GETPOWERINFO getpowerinfo; memset(&getpowerinfo, 0, sizeof(getpowerinfo)); getpowerinfo.usParmLength = sizeof(getpowerinfo); if (!(arc = apmhIOCtl(hfAPMSys, POWER_GETPOWERINFO, &getpowerinfo, getpowerinfo.usParmLength))) { PAPM papm; if (!(papm = NEW(APM))) arc = ERROR_NOT_ENOUGH_MEMORY; else { ZERO(papm); papm->hfAPMSys = hfAPMSys; // swap lower-byte(major vers.) to higher-byte(minor vers.) papm->usBIOSVersion = (getpowerinfo.usBIOSVersion & 0xff) << 8 | (getpowerinfo.usBIOSVersion >> 8); papm->usDriverVersion = (getpowerinfo.usDriverVersion & 0xff) << 8 | (getpowerinfo.usDriverVersion >> 8); // set general APM version to the lower of the two papm->usLowestAPMVersion = (papm->usBIOSVersion < papm->usDriverVersion) ? papm->usBIOSVersion : papm->usDriverVersion; *ppApm = papm; } } } if ((arc) && (hfAPMSys)) DosClose(hfAPMSys); return arc; } /* *@@ apmhReadStatus: * reads in the current battery status. * * After this, the status fields in APM * are valid (if NO_ERROR is returned). * If the values changed since the previous * call, *pfChanged is set to TRUE; FALSE * otherwise. * *@@changed V0.9.19 (2002-05-28) [umoeller]: added fUsingAC */ APIRET apmhReadStatus(PAPM pApm, // in: APM structure created by apmhOpen PBOOL pfChanged) // out: values changed (ptr can be NULL) { APIRET arc = NO_ERROR; BOOL fChanged = FALSE; if ((pApm) && (pApm->hfAPMSys)) { APMGIO_QSTATUS_PPKT PowerStatus; PowerStatus.ParmLength = sizeof(PowerStatus); if (!(arc = apmhIOCtl(pApm->hfAPMSys, APMGIO_QueryStatus, &PowerStatus, PowerStatus.ParmLength))) { if ( (pApm->fAlreadyRead) || (pApm->bBatteryStatus != PowerStatus.BatteryStatus) || (pApm->bBatteryLife != PowerStatus.BatteryLife) || (pApm->fUsingAC != PowerStatus.ACStatus) ) { pApm->bBatteryStatus = PowerStatus.BatteryStatus; pApm->bBatteryLife = PowerStatus.BatteryLife; pApm->fUsingAC = PowerStatus.ACStatus; pApm->fAlreadyRead = FALSE; fChanged = TRUE; } } if (pfChanged) *pfChanged = fChanged; } else arc = ERROR_INVALID_PARAMETER; return arc; } /* *@@ apmhClose: * closes the APM device driver and frees * the APM structure. *ppApm is set to NULL. */ VOID apmhClose(PAPM *ppApm) { if (ppApm && *ppApm) { PAPM pApm = *ppApm; if (pApm->hfAPMSys) DosClose(pApm->hfAPMSys); free(pApm); *ppApm = NULL; } } /* *@@ apmhHasBattery: * quick'n'dirty helper which returns TRUE only * if APM is supported on the system and the * system actually has a battery (i.e. is a laptop). * *@@added V0.9.16 (2001-10-15) [umoeller] */ BOOL apmhHasBattery(VOID) { BOOL brc = FALSE; PAPM p = NULL; if (!apmhOpen(&p)) { if (!apmhReadStatus(p, NULL)) brc = (p->bBatteryStatus != 0xFF); apmhClose(&p); } return brc; }