summaryrefslogtreecommitdiff
path: root/platform/osx
diff options
context:
space:
mode:
authorJulian Murgia <the.straton@gmail.com>2016-07-23 13:15:55 +0200
committerRémi Verschelde <rverschelde@gmail.com>2017-03-04 18:04:29 +0100
commit94103c0c025f04e75d5e163d9f0bdde27bb0c848 (patch)
treed5bb55acd30270cace54dae5537b009887de1e68 /platform/osx
parentef174abf6d640e69c402b5e9628743173c313439 (diff)
Add API to access battery power state
Done: - X11, server (tested) - Windows (developed, would be nice to retest) - OSX (not tested) Prepared (not developed): - Android (code is here, but may not compile) - iphone - winrt - bb10 - haiku - javascript
Diffstat (limited to 'platform/osx')
-rw-r--r--platform/osx/SCsub1
-rw-r--r--platform/osx/detect.py1
-rw-r--r--platform/osx/os_osx.h7
-rw-r--r--platform/osx/os_osx.mm15
-rw-r--r--platform/osx/power_osx.cpp233
-rw-r--r--platform/osx/power_osx.h57
6 files changed, 314 insertions, 0 deletions
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 00f23687cf..1427c2e00d 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -10,6 +10,7 @@ files = [
# 'context_gl_osx.cpp',
'dir_access_osx.mm',
'joypad_osx.cpp',
+ 'power_osx.cpp',
]
env.Program('#bin/godot', files)
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index ccd86177ab..b59dfe1afb 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -100,3 +100,4 @@ def configure(env):
#env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
env["x86_libtheora_opt_gcc"] = True
+
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index d8c35472f2..9941774b40 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -32,6 +32,7 @@
#include "os/input.h"
#include "joypad_osx.h"
+#include "power_osx.h"
#include "drivers/unix/os_unix.h"
#include "main/input_default.h"
#include "servers/visual_server.h"
@@ -107,6 +108,8 @@ public:
Size2 window_size;
int current_screen;
Rect2 restore_rect;
+
+ power_osx *power_manager;
float _mouse_scale(float p_scale) {
if (display_scale>1.0)
@@ -200,6 +203,10 @@ public:
virtual bool is_window_maximized() const;
virtual void request_attention();
virtual String get_joy_guid(int p_device) const;
+
+ virtual PowerState get_power_state();
+ virtual int get_power_seconds_left();
+ virtual int get_power_percent_left();
void run();
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 7108d94b5b..0699978caf 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1119,6 +1119,8 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
input = memnew( InputDefault );
joypad_osx = memnew( JoypadOSX );
+ power_manager = memnew( power_osx );
+
_ensure_data_dir();
NSArray *screenArray = [NSScreen screens];
@@ -1758,10 +1760,23 @@ OS::MouseMode OS_OSX::get_mouse_mode() const {
return mouse_mode;
}
+
String OS_OSX::get_joy_guid(int p_device) const {
return input->get_joy_guid_remapped(p_device);
}
+PowerState OS_OSX::get_power_state() {
+ return power_manager->get_power_state();
+}
+
+int OS_OSX::get_power_seconds_left() {
+ return power_manager->get_power_seconds_left();
+}
+
+int OS_OSX::get_power_percent_left() {
+ return power_manager->get_power_percent_left();
+}
+
OS_OSX* OS_OSX::singleton=NULL;
OS_OSX::OS_OSX() {
diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp
new file mode 100644
index 0000000000..0b20a78b92
--- /dev/null
+++ b/platform/osx/power_osx.cpp
@@ -0,0 +1,233 @@
+/*************************************************************************/
+/* power_osx.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "power_osx.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/ps/IOPowerSources.h>
+#include <IOKit/ps/IOPSKeys.h>
+
+// CODE CHUNK IMPORTED FROM SDL 2.0
+
+/* 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. */
+void power_osx::checkps(CFDictionaryRef dict, bool * have_ac, bool * have_battery, bool * charging)
+{
+ CFStringRef strval; /* don't CFRelease() this. */
+ CFBooleanRef bval;
+ CFNumberRef numval;
+ bool charge = false;
+ bool choose = false;
+ bool is_ac = 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 = true;
+ } else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) {
+ return; /* not a battery? */
+ }
+
+ if ((GETVAL(kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) {
+ charge = true;
+ }
+
+ if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
+ SInt32 val = -1;
+ CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
+ if (val > 0) {
+ *have_battery = true;
+ maxpct = (int) val;
+ }
+ }
+
+ if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
+ SInt32 val = -1;
+ CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
+ if (val > 0) {
+ *have_battery = 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) && (nsecs_left < 0)) {
+ if ((pct < 0) && (percent_left < 0)) {
+ choose = true; /* at least we know there's a battery. */
+ }
+ if (pct > percent_left) {
+ choose = true;
+ }
+ } else if (secs > nsecs_left) {
+ choose = true;
+ }
+
+ if (choose) {
+ nsecs_left = secs;
+ percent_left = pct;
+ *charging = charge;
+ }
+}
+
+#undef GETVAL
+#undef STRMATCH
+
+// CODE CHUNK IMPORTED FROM SDL 2.0
+bool power_osx::GetPowerInfo_MacOSX()
+{
+ CFTypeRef blob = IOPSCopyPowerSourcesInfo();
+
+ nsecs_left = -1;
+ percent_left = -1;
+ power_state = POWERSTATE_UNKNOWN;
+
+ if (blob != NULL) {
+ CFArrayRef list = IOPSCopyPowerSourcesList(blob);
+ if (list != NULL) {
+ /* don't CFRelease() the list items, or dictionaries! */
+ bool have_ac = false;
+ bool have_battery = false;
+ bool charging = 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);
+ }
+ }
+
+ if (!have_battery) {
+ power_state = POWERSTATE_NO_BATTERY;
+ } else if (charging) {
+ power_state = POWERSTATE_CHARGING;
+ } else if (have_ac) {
+ power_state = POWERSTATE_CHARGED;
+ } else {
+ power_state = POWERSTATE_ON_BATTERY;
+ }
+
+ CFRelease(list);
+ }
+ CFRelease(blob);
+ }
+
+ return true; /* always the definitive answer on Mac OS X. */
+}
+
+
+
+bool power_osx::UpdatePowerInfo() {
+ if (GetPowerInfo_MacOSX()) {
+ return true;
+ }
+ return false;
+}
+
+
+PowerState power_osx::get_power_state() {
+ if (UpdatePowerInfo()) {
+ return power_state;
+ }
+ else {
+ return POWERSTATE_UNKNOWN;
+ }
+}
+
+int power_osx::get_power_seconds_left() {
+ if (UpdatePowerInfo()) {
+ return nsecs_left;
+ }
+ else {
+ return -1;
+ }
+}
+
+int power_osx::get_power_percent_left() {
+ if (UpdatePowerInfo()) {
+ return percent_left;
+ }
+ else {
+ return -1;
+ }
+}
+
+
+power_osx::power_osx() : nsecs_left(-1), percent_left(-1), power_state(POWERSTATE_UNKNOWN) {
+
+}
+
+power_osx::~power_osx() {
+
+} \ No newline at end of file
diff --git a/platform/osx/power_osx.h b/platform/osx/power_osx.h
new file mode 100644
index 0000000000..a8ab50d9f2
--- /dev/null
+++ b/platform/osx/power_osx.h
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* power_osx.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef PLATFORM_OSX_POWER_OSX_H_
+#define PLATFORM_OSX_POWER_OSX_H_
+
+#include "dir_access_osx.h"
+#include "os/file_access.h"
+#include "os/power.h"
+#include <CoreFoundation/CoreFoundation.h>
+
+class power_osx {
+
+private:
+ int nsecs_left;
+ int percent_left;
+ PowerState power_state;
+ void checkps(CFDictionaryRef dict, bool * have_ac, bool * have_battery, bool * charging);
+ bool GetPowerInfo_MacOSX(/*PowerState * state, int *seconds, int *percent*/);
+ bool UpdatePowerInfo();
+
+public:
+ power_osx();
+ virtual ~power_osx();
+
+ PowerState get_power_state();
+ int get_power_seconds_left();
+ int get_power_percent_left();
+};
+
+#endif /* PLATFORM_OSX_POWER_OSX_H_ */ \ No newline at end of file