summaryrefslogtreecommitdiff
path: root/Source/external/SDL2/src/power/macosx/SDL_syspower.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/external/SDL2/src/power/macosx/SDL_syspower.c')
-rw-r--r--Source/external/SDL2/src/power/macosx/SDL_syspower.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/Source/external/SDL2/src/power/macosx/SDL_syspower.c b/Source/external/SDL2/src/power/macosx/SDL_syspower.c
new file mode 100644
index 0000000..f28b6c8
--- /dev/null
+++ b/Source/external/SDL2/src/power/macosx/SDL_syspower.c
@@ -0,0 +1,192 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_POWER_DISABLED
+#if SDL_POWER_MACOSX
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/ps/IOPowerSources.h>
+#include <IOKit/ps/IOPSKeys.h>
+
+#include "SDL_power.h"
+
+/* CoreFoundation 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
+checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery,
+ SDL_bool * charging, int *seconds, int *percent)
+{
+ CFStringRef strval; /* don't CFRelease() this. */
+ 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)) {
+ return; /* nothing to see here. */
+ }
+
+ if (!GETVAL(kIOPSPowerSourceStateKey, &strval)) {
+ return;
+ }
+
+ if (STRMATCH(strval, CFSTR(kIOPSACPowerValue))) {
+ is_ac = *have_ac = SDL_TRUE;
+ } else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) {
+ return; /* not a battery? */
+ }
+
+ 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)) {
+ val = -1; /* !!! FIXME: calc from timeToFull and capacity? */
+ }
+
+ secs = (int) val;
+ if (secs > 0) {
+ secs *= 60; /* value is in minutes, so convert to seconds. */
+ }
+ }
+
+ if (GETVAL(kIOPSCurrentCapacityKey, &numval)) {
+ SInt32 val = -1;
+ CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
+ pct = (int) val;
+ }
+
+ if ((pct > 0) && (maxpct > 0)) {
+ pct = (int) ((((double) pct) / ((double) maxpct)) * 100.0);
+ }
+
+ 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)) {
+ choose = SDL_TRUE; /* at least we know there's a battery. */
+ }
+ 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
+SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent)
+{
+ 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);
+ CFDictionaryRef dict =
+ IOPSGetPowerSourceDescription(blob, ps);
+ 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);
+ }
+
+ return SDL_TRUE; /* always the definitive answer on Mac OS X. */
+}
+
+#endif /* SDL_POWER_MACOSX */
+#endif /* SDL_POWER_DISABLED */
+
+/* vi: set ts=4 sw=4 expandtab: */