zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_syspower.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #ifndef SDL_POWER_DISABLED
24 #if SDL_POWER_MACOSX
25 
26 #include <Carbon/Carbon.h>
27 #include <IOKit/ps/IOPowerSources.h>
28 #include <IOKit/ps/IOPSKeys.h>
29 
30 #include "SDL_power.h"
31 
32 /* Carbon is so verbose... */
33 #define STRMATCH(a,b) (CFStringCompare(a, b, 0) == kCFCompareEqualTo)
34 #define GETVAL(k,v) \
35  CFDictionaryGetValueIfPresent(dict, CFSTR(k), (const void **) v)
36 
37 /* Note that AC power sources also include a laptop battery it is charging. */
38 static void
39 checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery,
40  SDL_bool * charging, int *seconds, int *percent)
41 {
42  CFStringRef strval; /* don't CFRelease() this. */
43  CFBooleanRef bval;
44  CFNumberRef numval;
45  SDL_bool charge = SDL_FALSE;
46  SDL_bool choose = SDL_FALSE;
47  SDL_bool is_ac = SDL_FALSE;
48  int secs = -1;
49  int maxpct = -1;
50  int pct = -1;
51 
52  if ((GETVAL(kIOPSIsPresentKey, &bval)) && (bval == kCFBooleanFalse)) {
53  return; /* nothing to see here. */
54  }
55 
56  if (!GETVAL(kIOPSPowerSourceStateKey, &strval)) {
57  return;
58  }
59 
60  if (STRMATCH(strval, CFSTR(kIOPSACPowerValue))) {
61  is_ac = *have_ac = SDL_TRUE;
62  } else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) {
63  return; /* not a battery? */
64  }
65 
66  if ((GETVAL(kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) {
67  charge = SDL_TRUE;
68  }
69 
70  if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
71  SInt32 val = -1;
72  CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
73  if (val > 0) {
74  *have_battery = SDL_TRUE;
75  maxpct = (int) val;
76  }
77  }
78 
79  if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
80  SInt32 val = -1;
81  CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
82  if (val > 0) {
83  *have_battery = SDL_TRUE;
84  maxpct = (int) val;
85  }
86  }
87 
88  if (GETVAL(kIOPSTimeToEmptyKey, &numval)) {
89  SInt32 val = -1;
90  CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
91 
92  /* Mac OS X reports 0 minutes until empty if you're plugged in. :( */
93  if ((val == 0) && (is_ac)) {
94  val = -1; /* !!! FIXME: calc from timeToFull and capacity? */
95  }
96 
97  secs = (int) val;
98  if (secs > 0) {
99  secs *= 60; /* value is in minutes, so convert to seconds. */
100  }
101  }
102 
103  if (GETVAL(kIOPSCurrentCapacityKey, &numval)) {
104  SInt32 val = -1;
105  CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
106  pct = (int) val;
107  }
108 
109  if ((pct > 0) && (maxpct > 0)) {
110  pct = (int) ((((double) pct) / ((double) maxpct)) * 100.0);
111  }
112 
113  if (pct > 100) {
114  pct = 100;
115  }
116 
117  /*
118  * We pick the battery that claims to have the most minutes left.
119  * (failing a report of minutes, we'll take the highest percent.)
120  */
121  if ((secs < 0) && (*seconds < 0)) {
122  if ((pct < 0) && (*percent < 0)) {
123  choose = SDL_TRUE; /* at least we know there's a battery. */
124  }
125  if (pct > *percent) {
126  choose = SDL_TRUE;
127  }
128  } else if (secs > *seconds) {
129  choose = SDL_TRUE;
130  }
131 
132  if (choose) {
133  *seconds = secs;
134  *percent = pct;
135  *charging = charge;
136  }
137 }
138 
139 #undef GETVAL
140 #undef STRMATCH
141 
142 
143 SDL_bool
144 SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent)
145 {
146  CFTypeRef blob = IOPSCopyPowerSourcesInfo();
147 
148  *seconds = -1;
149  *percent = -1;
150  *state = SDL_POWERSTATE_UNKNOWN;
151 
152  if (blob != NULL) {
153  CFArrayRef list = IOPSCopyPowerSourcesList(blob);
154  if (list != NULL) {
155  /* don't CFRelease() the list items, or dictionaries! */
156  SDL_bool have_ac = SDL_FALSE;
157  SDL_bool have_battery = SDL_FALSE;
158  SDL_bool charging = SDL_FALSE;
159  const CFIndex total = CFArrayGetCount(list);
160  CFIndex i;
161  for (i = 0; i < total; i++) {
162  CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i);
163  CFDictionaryRef dict =
164  IOPSGetPowerSourceDescription(blob, ps);
165  if (dict != NULL) {
166  checkps(dict, &have_ac, &have_battery, &charging,
167  seconds, percent);
168  }
169  }
170 
171  if (!have_battery) {
172  *state = SDL_POWERSTATE_NO_BATTERY;
173  } else if (charging) {
174  *state = SDL_POWERSTATE_CHARGING;
175  } else if (have_ac) {
176  *state = SDL_POWERSTATE_CHARGED;
177  } else {
178  *state = SDL_POWERSTATE_ON_BATTERY;
179  }
180 
181  CFRelease(list);
182  }
183  CFRelease(blob);
184  }
185 
186  return SDL_TRUE; /* always the definitive answer on Mac OS X. */
187 }
188 
189 #endif /* SDL_POWER_MACOSX */
190 #endif /* SDL_POWER_DISABLED */
191 
192 /* vi: set ts=4 sw=4 expandtab: */
GLuint const GLfloat * val
Definition: glew.h:2715
#define NULL
Definition: ftobjs.h:61
SDL_bool
Definition: SDL_stdinc.h:116
int
Definition: SDL_systhread.c:37
SDL_PowerState
The basic state for the system&#39;s power supply.
Definition: SDL_power.h:42
SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *)
int i
Definition: pngrutil.c:1377