| 1 |  | 
|---|
| 2 | /* | 
|---|
| 3 | *@@sourcefile apmh.c: | 
|---|
| 4 | *      contains helpers for accessing APM.SYS (Advanced Power Management). | 
|---|
| 5 | * | 
|---|
| 6 | *      These functions have been moved to this file with V0.9.14 | 
|---|
| 7 | *      and were previously used in XWorkplace code. | 
|---|
| 8 | * | 
|---|
| 9 | *      Usage: All OS/2 programs. | 
|---|
| 10 | * | 
|---|
| 11 | *      Function prefixes: | 
|---|
| 12 | *      --  apmh*   APM helper functions | 
|---|
| 13 | * | 
|---|
| 14 | *      Note: Version numbering in this file relates to XWorkplace version | 
|---|
| 15 | *            numbering. | 
|---|
| 16 | * | 
|---|
| 17 | *@@header "helpers\apmh.h" | 
|---|
| 18 | *@@added V0.9.14 (2001-08-01) [umoeller] | 
|---|
| 19 | */ | 
|---|
| 20 |  | 
|---|
| 21 | /* | 
|---|
| 22 | *      Copyright (C) 1998-2001 Ulrich Mller. | 
|---|
| 23 | *      This file is part of the "XWorkplace helpers" source package. | 
|---|
| 24 | *      This is free software; you can redistribute it and/or modify | 
|---|
| 25 | *      it under the terms of the GNU General Public License as published | 
|---|
| 26 | *      by the Free Software Foundation, in version 2 as it comes in the | 
|---|
| 27 | *      "COPYING" file of the XWorkplace main distribution. | 
|---|
| 28 | *      This program is distributed in the hope that it will be useful, | 
|---|
| 29 | *      but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 30 | *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 31 | *      GNU General Public License for more details. | 
|---|
| 32 | */ | 
|---|
| 33 |  | 
|---|
| 34 | #define OS2EMX_PLAIN_CHAR | 
|---|
| 35 | // this is needed for "os2emx.h"; if this is defined, | 
|---|
| 36 | // emx will define PSZ as _signed_ char, otherwise | 
|---|
| 37 | // as unsigned char | 
|---|
| 38 |  | 
|---|
| 39 | #define INCL_DOSDEVICES | 
|---|
| 40 | #define INCL_DOSDEVIOCTL | 
|---|
| 41 | #define INCL_DOSERRORS | 
|---|
| 42 | #include <os2.h> | 
|---|
| 43 |  | 
|---|
| 44 | #include "setup.h"                      // code generation and debugging options | 
|---|
| 45 |  | 
|---|
| 46 | #include "helpers\apmh.h" | 
|---|
| 47 | #include "helpers\standards.h" | 
|---|
| 48 |  | 
|---|
| 49 | /* | 
|---|
| 50 | *@@category: Helpers\Control program helpers\Advanced Power Management | 
|---|
| 51 | *      See apmh.c. | 
|---|
| 52 | */ | 
|---|
| 53 |  | 
|---|
| 54 | /* ****************************************************************** | 
|---|
| 55 | * | 
|---|
| 56 | *   APM monitor | 
|---|
| 57 | * | 
|---|
| 58 | ********************************************************************/ | 
|---|
| 59 |  | 
|---|
| 60 | /* | 
|---|
| 61 | *@@ apmhIOCtl: | 
|---|
| 62 | *      shortcut for DosDevIOCtl on the APM.SYS driver. | 
|---|
| 63 | */ | 
|---|
| 64 |  | 
|---|
| 65 | APIRET apmhIOCtl(HFILE hfAPMSys, | 
|---|
| 66 | ULONG ulFunction, | 
|---|
| 67 | PVOID pvParamPck, | 
|---|
| 68 | ULONG cbParamPck) | 
|---|
| 69 | { | 
|---|
| 70 | APIRET          arc; | 
|---|
| 71 | APMGIO_DPKT     DataPacket; | 
|---|
| 72 | ULONG           ulRetSize = sizeof(DataPacket); | 
|---|
| 73 | DataPacket.ReturnCode = GIOERR_PowerNoError; | 
|---|
| 74 | if (!(arc = DosDevIOCtl(hfAPMSys, | 
|---|
| 75 | APMGIO_Category, | 
|---|
| 76 | ulFunction, | 
|---|
| 77 | pvParamPck, cbParamPck, &cbParamPck, | 
|---|
| 78 | &DataPacket, sizeof(DataPacket), &ulRetSize))) | 
|---|
| 79 | if (DataPacket.ReturnCode) | 
|---|
| 80 | arc = DataPacket.ReturnCode + 10000; | 
|---|
| 81 |  | 
|---|
| 82 | return arc; | 
|---|
| 83 | } | 
|---|
| 84 |  | 
|---|
| 85 | /* | 
|---|
| 86 | *@@ apmhOpen: | 
|---|
| 87 | *      opens the APM.SYS driver and creates | 
|---|
| 88 | *      an APM structure in *ppApm. | 
|---|
| 89 | * | 
|---|
| 90 | *      In the APM structure, the version fields are | 
|---|
| 91 | *      set to the version flags returned from the | 
|---|
| 92 | *      BIOS and APM.SYS itself. | 
|---|
| 93 | */ | 
|---|
| 94 |  | 
|---|
| 95 | APIRET apmhOpen(PAPM *ppApm) | 
|---|
| 96 | { | 
|---|
| 97 | // open APM.SYS | 
|---|
| 98 | APIRET arc; | 
|---|
| 99 | HFILE hfAPMSys = NULLHANDLE; | 
|---|
| 100 | ULONG ulAction; | 
|---|
| 101 |  | 
|---|
| 102 | if (!(arc = DosOpen("\\DEV\\APM$", | 
|---|
| 103 | &hfAPMSys, | 
|---|
| 104 | &ulAction, | 
|---|
| 105 | 0, | 
|---|
| 106 | FILE_NORMAL, | 
|---|
| 107 | OPEN_ACTION_OPEN_IF_EXISTS, | 
|---|
| 108 | OPEN_FLAGS_FAIL_ON_ERROR | 
|---|
| 109 | | OPEN_SHARE_DENYNONE | 
|---|
| 110 | | OPEN_ACCESS_READWRITE, | 
|---|
| 111 | NULL))) | 
|---|
| 112 | { | 
|---|
| 113 | // query version of APM-BIOS and APM driver | 
|---|
| 114 | GETPOWERINFO    getpowerinfo; | 
|---|
| 115 | memset(&getpowerinfo, 0, sizeof(getpowerinfo)); | 
|---|
| 116 | getpowerinfo.usParmLength = sizeof(getpowerinfo); | 
|---|
| 117 |  | 
|---|
| 118 | if (!(arc = apmhIOCtl(hfAPMSys, | 
|---|
| 119 | POWER_GETPOWERINFO, | 
|---|
| 120 | &getpowerinfo, | 
|---|
| 121 | getpowerinfo.usParmLength))) | 
|---|
| 122 | { | 
|---|
| 123 | PAPM papm; | 
|---|
| 124 | if (!(papm = NEW(APM))) | 
|---|
| 125 | arc = ERROR_NOT_ENOUGH_MEMORY; | 
|---|
| 126 | else | 
|---|
| 127 | { | 
|---|
| 128 | ZERO(papm); | 
|---|
| 129 |  | 
|---|
| 130 | papm->hfAPMSys = hfAPMSys; | 
|---|
| 131 |  | 
|---|
| 132 | // swap lower-byte(major vers.) to higher-byte(minor vers.) | 
|---|
| 133 | papm->usBIOSVersion =     (getpowerinfo.usBIOSVersion & 0xff) << 8 | 
|---|
| 134 | | (getpowerinfo.usBIOSVersion >> 8); | 
|---|
| 135 | papm->usDriverVersion =   (getpowerinfo.usDriverVersion & 0xff) << 8 | 
|---|
| 136 | | (getpowerinfo.usDriverVersion >> 8); | 
|---|
| 137 |  | 
|---|
| 138 | // set general APM version to the lower of the two | 
|---|
| 139 | papm->usLowestAPMVersion = (papm->usBIOSVersion < papm->usDriverVersion) | 
|---|
| 140 | ? papm->usBIOSVersion | 
|---|
| 141 | : papm->usDriverVersion; | 
|---|
| 142 |  | 
|---|
| 143 | *ppApm = papm; | 
|---|
| 144 | } | 
|---|
| 145 | } | 
|---|
| 146 | } | 
|---|
| 147 |  | 
|---|
| 148 | if ((arc) && (hfAPMSys)) | 
|---|
| 149 | DosClose(hfAPMSys); | 
|---|
| 150 |  | 
|---|
| 151 | return arc; | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 | /* | 
|---|
| 155 | *@@ apmhReadStatus: | 
|---|
| 156 | *      reads in the current battery status. | 
|---|
| 157 | * | 
|---|
| 158 | *      After this, the status fields in APM | 
|---|
| 159 | *      are valid (if NO_ERROR is returned). | 
|---|
| 160 | *      If the values changed since the previous | 
|---|
| 161 | *      call, *pfChanged is set to TRUE; FALSE | 
|---|
| 162 | *      otherwise. | 
|---|
| 163 | * | 
|---|
| 164 | *@@changed V0.9.19 (2002-05-28) [umoeller]: added fUsingAC | 
|---|
| 165 | */ | 
|---|
| 166 |  | 
|---|
| 167 | APIRET apmhReadStatus(PAPM pApm,        // in: APM structure created by apmhOpen | 
|---|
| 168 | PBOOL pfChanged)  // out: values changed (ptr can be NULL) | 
|---|
| 169 | { | 
|---|
| 170 | APIRET  arc = NO_ERROR; | 
|---|
| 171 | BOOL    fChanged = FALSE; | 
|---|
| 172 |  | 
|---|
| 173 | if ((pApm) && (pApm->hfAPMSys)) | 
|---|
| 174 | { | 
|---|
| 175 | APMGIO_QSTATUS_PPKT  PowerStatus; | 
|---|
| 176 | PowerStatus.ParmLength = sizeof(PowerStatus); | 
|---|
| 177 |  | 
|---|
| 178 | if (!(arc = apmhIOCtl(pApm->hfAPMSys, | 
|---|
| 179 | APMGIO_QueryStatus, | 
|---|
| 180 | &PowerStatus, | 
|---|
| 181 | PowerStatus.ParmLength))) | 
|---|
| 182 | { | 
|---|
| 183 | if (    (pApm->fAlreadyRead) | 
|---|
| 184 | || (pApm->bBatteryStatus != PowerStatus.BatteryStatus) | 
|---|
| 185 | || (pApm->bBatteryLife != PowerStatus.BatteryLife) | 
|---|
| 186 | || (pApm->fUsingAC != PowerStatus.ACStatus) | 
|---|
| 187 | ) | 
|---|
| 188 | { | 
|---|
| 189 | pApm->bBatteryStatus = PowerStatus.BatteryStatus; | 
|---|
| 190 | pApm->bBatteryLife = PowerStatus.BatteryLife; | 
|---|
| 191 | pApm->fUsingAC = PowerStatus.ACStatus; | 
|---|
| 192 |  | 
|---|
| 193 | pApm->fAlreadyRead = FALSE; | 
|---|
| 194 | fChanged = TRUE; | 
|---|
| 195 | } | 
|---|
| 196 | } | 
|---|
| 197 |  | 
|---|
| 198 | if (pfChanged) | 
|---|
| 199 | *pfChanged = fChanged; | 
|---|
| 200 | } | 
|---|
| 201 | else | 
|---|
| 202 | arc = ERROR_INVALID_PARAMETER; | 
|---|
| 203 |  | 
|---|
| 204 | return arc; | 
|---|
| 205 | } | 
|---|
| 206 |  | 
|---|
| 207 | /* | 
|---|
| 208 | *@@ apmhClose: | 
|---|
| 209 | *      closes the APM device driver and frees | 
|---|
| 210 | *      the APM structure. *ppApm is set to NULL. | 
|---|
| 211 | */ | 
|---|
| 212 |  | 
|---|
| 213 | VOID apmhClose(PAPM *ppApm) | 
|---|
| 214 | { | 
|---|
| 215 | if (ppApm && *ppApm) | 
|---|
| 216 | { | 
|---|
| 217 | PAPM pApm = *ppApm; | 
|---|
| 218 | if (pApm->hfAPMSys) | 
|---|
| 219 | DosClose(pApm->hfAPMSys); | 
|---|
| 220 | free(pApm); | 
|---|
| 221 | *ppApm = NULL; | 
|---|
| 222 | } | 
|---|
| 223 | } | 
|---|
| 224 |  | 
|---|
| 225 | /* | 
|---|
| 226 | *@@ apmhHasBattery: | 
|---|
| 227 | *      quick'n'dirty helper which returns TRUE only | 
|---|
| 228 | *      if APM is supported on the system and the | 
|---|
| 229 | *      system actually has a battery (i.e. is a laptop). | 
|---|
| 230 | * | 
|---|
| 231 | *@@added V0.9.16 (2001-10-15) [umoeller] | 
|---|
| 232 | */ | 
|---|
| 233 |  | 
|---|
| 234 | BOOL apmhHasBattery(VOID) | 
|---|
| 235 | { | 
|---|
| 236 | BOOL brc = FALSE; | 
|---|
| 237 |  | 
|---|
| 238 | PAPM p = NULL; | 
|---|
| 239 | if (!apmhOpen(&p)) | 
|---|
| 240 | { | 
|---|
| 241 | if (!apmhReadStatus(p, NULL)) | 
|---|
| 242 | brc = (p->bBatteryStatus != 0xFF); | 
|---|
| 243 |  | 
|---|
| 244 | apmhClose(&p); | 
|---|
| 245 | } | 
|---|
| 246 |  | 
|---|
| 247 | return brc; | 
|---|
| 248 | } | 
|---|