Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
193 lines (160 loc) · 5.67 KB

SDL_syspower.c

File metadata and controls

193 lines (160 loc) · 5.67 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Jan 24, 2010
Jan 24, 2010
3
Copyright (C) 1997-2010 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifndef SDL_POWER_DISABLED
#ifdef SDL_POWER_MACOSX
#include <Carbon/Carbon.h>
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/ps/IOPSKeys.h>
#include "SDL_power.h"
/* Carbon is so verbose... */
#define STRMATCH(a,b) (CFStringCompare(a, b, 0) == kCFCompareEqualTo)
#define GETVAL(k,v) \
CFDictionaryGetValueIfPresent(dict, CFSTR(k), (const void **) v)
/* Note that AC power sources also include a laptop battery it is charging. */
static void
Jun 10, 2009
Jun 10, 2009
40
41
checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery,
SDL_bool * charging, int *seconds, int *percent)
Jun 10, 2009
Jun 10, 2009
43
CFStringRef strval; /* don't CFRelease() this. */
44
45
46
47
48
49
50
51
52
53
CFBooleanRef bval;
CFNumberRef numval;
SDL_bool charge = SDL_FALSE;
SDL_bool choose = SDL_FALSE;
SDL_bool is_ac = SDL_FALSE;
int secs = -1;
int maxpct = -1;
int pct = -1;
if ((GETVAL(kIOPSIsPresentKey, &bval)) && (bval == kCFBooleanFalse)) {
Jun 10, 2009
Jun 10, 2009
54
return; /* nothing to see here. */
55
56
57
58
59
60
61
62
63
}
if (!GETVAL(kIOPSPowerSourceStateKey, &strval)) {
return;
}
if (STRMATCH(strval, CFSTR(kIOPSACPowerValue))) {
is_ac = *have_ac = SDL_TRUE;
} else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) {
Jun 10, 2009
Jun 10, 2009
64
return; /* not a battery? */
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
}
if ((GETVAL(kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) {
charge = SDL_TRUE;
}
if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
SInt32 val = -1;
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
if (val > 0) {
*have_battery = SDL_TRUE;
maxpct = (int) val;
}
}
if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
SInt32 val = -1;
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
if (val > 0) {
*have_battery = SDL_TRUE;
maxpct = (int) val;
}
}
if (GETVAL(kIOPSTimeToEmptyKey, &numval)) {
SInt32 val = -1;
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
/* Mac OS X reports 0 minutes until empty if you're plugged in. :( */
if ((val == 0) && (is_ac)) {
Jun 10, 2009
Jun 10, 2009
95
val = -1; /* !!! FIXME: calc from timeToFull and capacity? */
96
97
98
99
}
secs = (int) val;
if (secs > 0) {
Jun 10, 2009
Jun 10, 2009
100
secs *= 60; /* value is in minutes, so convert to seconds. */
101
102
103
104
105
106
107
108
109
110
}
}
if (GETVAL(kIOPSCurrentCapacityKey, &numval)) {
SInt32 val = -1;
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
pct = (int) val;
}
if ((pct > 0) && (maxpct > 0)) {
Jun 10, 2009
Jun 10, 2009
111
pct = (int) ((((double) pct) / ((double) maxpct)) * 100.0);
112
113
114
115
116
117
118
119
120
121
122
123
}
if (pct > 100) {
pct = 100;
}
/*
* We pick the battery that claims to have the most minutes left.
* (failing a report of minutes, we'll take the highest percent.)
*/
if ((secs < 0) && (*seconds < 0)) {
if ((pct < 0) && (*percent < 0)) {
Jun 10, 2009
Jun 10, 2009
124
choose = SDL_TRUE; /* at least we know there's a battery. */
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
}
if (pct > *percent) {
choose = SDL_TRUE;
}
} else if (secs > *seconds) {
choose = SDL_TRUE;
}
if (choose) {
*seconds = secs;
*percent = pct;
*charging = charge;
}
}
#undef GETVAL
#undef STRMATCH
SDL_bool
Jun 10, 2009
Jun 10, 2009
145
SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
{
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
*seconds = -1;
*percent = -1;
*state = SDL_POWERSTATE_UNKNOWN;
if (blob != NULL) {
CFArrayRef list = IOPSCopyPowerSourcesList(blob);
if (list != NULL) {
/* don't CFRelease() the list items, or dictionaries! */
SDL_bool have_ac = SDL_FALSE;
SDL_bool have_battery = SDL_FALSE;
SDL_bool charging = SDL_FALSE;
const CFIndex total = CFArrayGetCount(list);
CFIndex i;
for (i = 0; i < total; i++) {
CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i);
Jun 10, 2009
Jun 10, 2009
164
165
CFDictionaryRef dict =
IOPSGetPowerSourceDescription(blob, ps);
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
if (dict != NULL) {
checkps(dict, &have_ac, &have_battery, &charging,
seconds, percent);
}
}
if (!have_battery) {
*state = SDL_POWERSTATE_NO_BATTERY;
} else if (charging) {
*state = SDL_POWERSTATE_CHARGING;
} else if (have_ac) {
*state = SDL_POWERSTATE_CHARGED;
} else {
*state = SDL_POWERSTATE_ON_BATTERY;
}
CFRelease(list);
}
CFRelease(blob);
}
Jun 10, 2009
Jun 10, 2009
187
return SDL_TRUE; /* always the definitive answer on Mac OS X. */
188
189
190
191
192
193
}
#endif /* SDL_POWER_MACOSX */
#endif /* SDL_POWER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */