| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  power_x11.cpp                                                        */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-01-01 11:16:22 +01:00
										 |  |  | /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* 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.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-06 23:38:44 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  | Adapted from corresponding SDL 2.0 code. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   Simple DirectMedia Layer | 
					
						
							|  |  |  |   Copyright (C) 1997-2017 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. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | #include "power_x11.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 11:14:33 -04:00
										 |  |  | #include "core/error_macros.h"
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | #include <dirent.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // CODE CHUNK IMPORTED FROM SDL 2.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static const char *proc_apm_path = "/proc/apm"; | 
					
						
							|  |  |  | static const char *proc_acpi_battery_path = "/proc/acpi/battery"; | 
					
						
							|  |  |  | static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter"; | 
					
						
							|  |  |  | static const char *sys_class_power_supply_path = "/sys/class/power_supply"; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | FileAccessRef PowerX11::open_power_file(const char *base, const char *node, const char *key) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	String path = String(base) + String("/") + String(node) + String("/") + String(key); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	FileAccessRef f = FileAccess::open(path, FileAccess::READ); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	return f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::read_power_file(const char *base, const char *node, const char *key, char *buf, size_t buflen) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	ssize_t br = 0; | 
					
						
							|  |  |  | 	FileAccessRef fd = open_power_file(base, node, key); | 
					
						
							|  |  |  | 	if (!fd) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), buflen - 1); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	fd->close(); | 
					
						
							|  |  |  | 	if (br < 0) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	buf[br] = '\0'; // null-terminate the string
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	char *ptr = *_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (*ptr == ' ') { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ptr++; /* skip whitespace. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (*ptr == '\0') { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return false; /* EOF. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*_key = ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((*ptr != ':') && (*ptr != '\0')) { | 
					
						
							|  |  |  | 		ptr++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (*ptr == '\0') { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return false; /* (unexpected) EOF. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	*(ptr++) = '\0'; /* terminate the key. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-04 22:00:16 +02:00
										 |  |  | 	while (*ptr == ' ') { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ptr++; /* skip whitespace. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (*ptr == '\0') { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return false; /* (unexpected) EOF. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*_val = ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((*ptr != '\n') && (*ptr != '\0')) { | 
					
						
							|  |  |  | 		ptr++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (*ptr != '\0') { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		*(ptr++) = '\0'; /* terminate the value. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	*_ptr = ptr; /* store for next time. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void PowerX11::check_proc_acpi_battery(const char *node, bool *have_battery, bool *charging) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	const char *base = proc_acpi_battery_path; | 
					
						
							|  |  |  | 	char info[1024]; | 
					
						
							|  |  |  | 	char state[1024]; | 
					
						
							|  |  |  | 	char *ptr = NULL; | 
					
						
							|  |  |  | 	char *key = NULL; | 
					
						
							|  |  |  | 	char *val = NULL; | 
					
						
							|  |  |  | 	bool charge = false; | 
					
						
							|  |  |  | 	bool choose = false; | 
					
						
							|  |  |  | 	int maximum = -1; | 
					
						
							|  |  |  | 	int remaining = -1; | 
					
						
							|  |  |  | 	int secs = -1; | 
					
						
							|  |  |  | 	int pct = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!read_power_file(base, node, "state", state, sizeof(state))) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (!read_power_file(base, node, "info", info, sizeof(info))) | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ptr = &state[0]; | 
					
						
							|  |  |  | 	while (make_proc_acpi_key_val(&ptr, &key, &val)) { | 
					
						
							|  |  |  | 		if (String(key) == "present") { | 
					
						
							|  |  |  | 			if (String(val) == "yes") { | 
					
						
							|  |  |  | 				*have_battery = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (String(key) == "charging state") { | 
					
						
							|  |  |  | 			/* !!! FIXME: what exactly _does_ charging/discharging mean? */ | 
					
						
							|  |  |  | 			if (String(val) == "charging/discharging") { | 
					
						
							|  |  |  | 				charge = true; | 
					
						
							|  |  |  | 			} else if (String(val) == "charging") { | 
					
						
							|  |  |  | 				charge = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (String(key) == "remaining capacity") { | 
					
						
							|  |  |  | 			String sval = val; | 
					
						
							|  |  |  | 			const int cvt = sval.to_int(); | 
					
						
							| 
									
										
										
										
											2017-07-26 23:29:51 +02:00
										 |  |  | 			remaining = cvt; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ptr = &info[0]; | 
					
						
							|  |  |  | 	while (make_proc_acpi_key_val(&ptr, &key, &val)) { | 
					
						
							|  |  |  | 		if (String(key) == "design capacity") { | 
					
						
							|  |  |  | 			String sval = val; | 
					
						
							|  |  |  | 			const int cvt = sval.to_int(); | 
					
						
							| 
									
										
										
										
											2017-07-26 23:29:51 +02:00
										 |  |  | 			maximum = cvt; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((maximum >= 0) && (remaining >= 0)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		pct = (int)((((float)remaining) / ((float)maximum)) * 100.0f); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		if (pct < 0) { | 
					
						
							|  |  |  | 			pct = 0; | 
					
						
							|  |  |  | 		} else if (pct > 100) { | 
					
						
							|  |  |  | 			pct = 100; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* !!! FIXME: calculate (secs). */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * We pick the battery that claims to have the most minutes left. | 
					
						
							|  |  |  | 	 *  (failing a report of minutes, we'll take the highest percent.) | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 	// -- GODOT start --
 | 
					
						
							|  |  |  | 	//if ((secs < 0) && (this->nsecs_left < 0)) {
 | 
					
						
							|  |  |  | 	if (this->nsecs_left < 0) { | 
					
						
							|  |  |  | 		// -- GODOT end --
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		if ((pct < 0) && (this->percent_left < 0)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			choose = true; /* at least we know there's a battery. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (pct > this->percent_left) { | 
					
						
							|  |  |  | 			choose = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else if (secs > this->nsecs_left) { | 
					
						
							|  |  |  | 		choose = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (choose) { | 
					
						
							|  |  |  | 		this->nsecs_left = secs; | 
					
						
							|  |  |  | 		this->percent_left = pct; | 
					
						
							|  |  |  | 		*charging = charge; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void PowerX11::check_proc_acpi_ac_adapter(const char *node, bool *have_ac) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	const char *base = proc_acpi_ac_adapter_path; | 
					
						
							|  |  |  | 	char state[256]; | 
					
						
							|  |  |  | 	char *ptr = NULL; | 
					
						
							|  |  |  | 	char *key = NULL; | 
					
						
							|  |  |  | 	char *val = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!read_power_file(base, node, "state", state, sizeof(state))) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ptr = &state[0]; | 
					
						
							|  |  |  | 	while (make_proc_acpi_key_val(&ptr, &key, &val)) { | 
					
						
							|  |  |  | 		String skey = key; | 
					
						
							|  |  |  | 		if (skey == "state") { | 
					
						
							|  |  |  | 			String sval = val; | 
					
						
							|  |  |  | 			if (sval == "on-line") { | 
					
						
							|  |  |  | 				*have_ac = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::GetPowerInfo_Linux_proc_acpi() { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	String node; | 
					
						
							|  |  |  | 	DirAccess *dirp = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); | 
					
						
							|  |  |  | 	bool have_battery = false; | 
					
						
							|  |  |  | 	bool have_ac = false; | 
					
						
							|  |  |  | 	bool charging = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	this->nsecs_left = -1; | 
					
						
							|  |  |  | 	this->percent_left = -1; | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 	this->power_state = OS::POWERSTATE_UNKNOWN; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	dirp->change_dir(proc_acpi_battery_path); | 
					
						
							| 
									
										
										
										
											2017-08-25 11:14:33 -04:00
										 |  |  | 	Error err = dirp->list_dir_begin(); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 11:14:33 -04:00
										 |  |  | 	if (err != OK) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return false; /* can't use this interface. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		node = dirp->get_next(); | 
					
						
							|  |  |  | 		while (node != "") { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			check_proc_acpi_battery(node.utf8().get_data(), &have_battery, &charging /*, seconds, percent*/); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			node = dirp->get_next(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	dirp->change_dir(proc_acpi_ac_adapter_path); | 
					
						
							| 
									
										
										
										
											2017-08-25 11:14:33 -04:00
										 |  |  | 	err = dirp->list_dir_begin(); | 
					
						
							|  |  |  | 	if (err != OK) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return false; /* can't use this interface. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		node = dirp->get_next(); | 
					
						
							|  |  |  | 		while (node != "") { | 
					
						
							|  |  |  | 			check_proc_acpi_ac_adapter(node.utf8().get_data(), &have_ac); | 
					
						
							|  |  |  | 			node = dirp->get_next(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!have_battery) { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_NO_BATTERY; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} else if (charging) { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_CHARGING; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} else if (have_ac) { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_CHARGED; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_ON_BATTERY; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-23 09:14:31 +02:00
										 |  |  | 	memdelete(dirp); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	return true; /* definitive answer. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::next_string(char **_ptr, char **_str) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	char *ptr = *_ptr; | 
					
						
							|  |  |  | 	char *str = *_str; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (*ptr == ' ') { /* skip any spaces... */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		ptr++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (*ptr == '\0') { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	str = ptr; | 
					
						
							|  |  |  | 	while ((*ptr != ' ') && (*ptr != '\n') && (*ptr != '\0')) | 
					
						
							|  |  |  | 		ptr++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (*ptr != '\0') | 
					
						
							|  |  |  | 		*(ptr++) = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*_str = str; | 
					
						
							|  |  |  | 	*_ptr = ptr; | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::int_string(char *str, int *val) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	String sval = str; | 
					
						
							|  |  |  | 	*val = sval.to_int(); | 
					
						
							|  |  |  | 	return (*str != '\0'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* http://lxr.linux.no/linux+v2.6.29/drivers/char/apm-emulation.c */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::GetPowerInfo_Linux_proc_apm() { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	bool need_details = false; | 
					
						
							|  |  |  | 	int ac_status = 0; | 
					
						
							|  |  |  | 	int battery_status = 0; | 
					
						
							|  |  |  | 	int battery_flag = 0; | 
					
						
							|  |  |  | 	int battery_percent = 0; | 
					
						
							|  |  |  | 	int battery_time = 0; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	FileAccessRef fd = FileAccess::open(proc_apm_path, FileAccess::READ); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	char buf[128]; | 
					
						
							|  |  |  | 	char *ptr = &buf[0]; | 
					
						
							|  |  |  | 	char *str = NULL; | 
					
						
							|  |  |  | 	ssize_t br; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!fd) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		return false; /* can't use this interface. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), sizeof(buf) - 1); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	fd->close(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (br < 0) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	buf[br] = '\0'; /* null-terminate the string. */ | 
					
						
							|  |  |  | 	if (!next_string(&ptr, &str)) { /* driver version */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* BIOS version */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* APM flags */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* AC line status */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} else if (!int_string(str, &ac_status)) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* battery status */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} else if (!int_string(str, &battery_status)) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* battery flag */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} else if (!int_string(str, &battery_flag)) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* remaining battery life percent */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	String sstr = str; | 
					
						
							|  |  |  | 	if (sstr[sstr.length() - 1] == '%') { | 
					
						
							|  |  |  | 		sstr[sstr.length() - 1] = '\0'; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!int_string(str, &battery_percent)) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* remaining battery life time */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} else if (!int_string(str, &battery_time)) { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (!next_string(&ptr, &str)) { /* remaining battery life time units */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} else if (String(str) == "min") { | 
					
						
							|  |  |  | 		battery_time *= 60; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (battery_flag == 0xFF) { /* unknown state */ | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_UNKNOWN; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else if (battery_flag & (1 << 7)) { /* no battery */ | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_NO_BATTERY; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else if (battery_flag & (1 << 3)) { /* charging */ | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_CHARGING; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		need_details = true; | 
					
						
							|  |  |  | 	} else if (ac_status == 1) { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_CHARGED; /* on AC, not charging. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		need_details = true; | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		this->power_state = OS::POWERSTATE_ON_BATTERY; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		need_details = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	this->percent_left = -1; | 
					
						
							|  |  |  | 	this->nsecs_left = -1; | 
					
						
							|  |  |  | 	if (need_details) { | 
					
						
							|  |  |  | 		const int pct = battery_percent; | 
					
						
							|  |  |  | 		const int secs = battery_time; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (pct >= 0) { /* -1 == unknown */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			this->percent_left = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (secs >= 0) { /* -1 == unknown */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			this->nsecs_left = secs; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* !!! FIXME: implement d-bus queries to org.freedesktop.UPower. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::GetPowerInfo_Linux_sys_class_power_supply(/*PowerState *state, int *seconds, int *percent*/) { | 
					
						
							|  |  |  | 	const char *base = sys_class_power_supply_path; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	String name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DirAccess *dirp = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); | 
					
						
							|  |  |  | 	dirp->change_dir(base); | 
					
						
							| 
									
										
										
										
											2017-08-25 11:14:33 -04:00
										 |  |  | 	Error err = dirp->list_dir_begin(); | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-25 11:14:33 -04:00
										 |  |  | 	if (err != OK) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 	this->power_state = OS::POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	this->nsecs_left = -1; | 
					
						
							|  |  |  | 	this->percent_left = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	name = dirp->get_next(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (name != "") { | 
					
						
							|  |  |  | 		bool choose = false; | 
					
						
							|  |  |  | 		char str[64]; | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		OS::PowerState st; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		int secs; | 
					
						
							|  |  |  | 		int pct; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((name == ".") || (name == "..")) { | 
					
						
							|  |  |  | 			name = dirp->get_next(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			continue; //skip these, of course.
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (!read_power_file(base, name.utf8().get_data(), "type", str, sizeof(str))) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 				name = dirp->get_next(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				continue; // Don't know _what_ we're looking at. Give up on it.
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				if (String(str) != "Battery\n") { | 
					
						
							|  |  |  | 					name = dirp->get_next(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					continue; // we don't care about UPS and such.
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* some drivers don't offer this, so if it's not explicitly reported assume it's present. */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (read_power_file(base, name.utf8().get_data(), "present", str, sizeof(str)) && (String(str) == "0\n")) { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 			st = OS::POWERSTATE_NO_BATTERY; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		} else if (!read_power_file(base, name.utf8().get_data(), "status", str, sizeof(str))) { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 			st = OS::POWERSTATE_UNKNOWN; /* uh oh */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} else if (String(str) == "Charging\n") { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 			st = OS::POWERSTATE_CHARGING; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} else if (String(str) == "Discharging\n") { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 			st = OS::POWERSTATE_ON_BATTERY; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} else if ((String(str) == "Full\n") || (String(str) == "Not charging\n")) { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 			st = OS::POWERSTATE_CHARGED; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 			st = OS::POWERSTATE_UNKNOWN; /* uh oh */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (!read_power_file(base, name.utf8().get_data(), "capacity", str, sizeof(str))) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			pct = -1; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			pct = String(str).to_int(); | 
					
						
							|  |  |  | 			pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (!read_power_file(base, name.utf8().get_data(), "time_to_empty_now", str, sizeof(str))) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			secs = -1; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			secs = String(str).to_int(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * 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) && (this->nsecs_left < 0)) { | 
					
						
							|  |  |  | 			if ((pct < 0) && (this->percent_left < 0)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				choose = true; /* at least we know there's a battery. */ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 			} else if (pct > this->percent_left) { | 
					
						
							|  |  |  | 				choose = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (secs > this->nsecs_left) { | 
					
						
							|  |  |  | 			choose = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (choose) { | 
					
						
							|  |  |  | 			this->nsecs_left = secs; | 
					
						
							|  |  |  | 			this->percent_left = pct; | 
					
						
							|  |  |  | 			this->power_state = st; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		name = dirp->get_next(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memdelete(dirp); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	return true; /* don't look any further*/ | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PowerX11::UpdatePowerInfo() { | 
					
						
							|  |  |  | 	if (GetPowerInfo_Linux_sys_class_power_supply()) { // try method 1
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (GetPowerInfo_Linux_proc_acpi()) { // try further
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (GetPowerInfo_Linux_proc_apm()) { // try even further
 | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-06 21:36:34 +01:00
										 |  |  | PowerX11::PowerX11() : | 
					
						
							|  |  |  | 		nsecs_left(-1), | 
					
						
							|  |  |  | 		percent_left(-1), | 
					
						
							|  |  |  | 		power_state(OS::POWERSTATE_UNKNOWN) { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PowerX11::~PowerX11() { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | OS::PowerState PowerX11::get_power_state() { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	if (UpdatePowerInfo()) { | 
					
						
							|  |  |  | 		return power_state; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 		return OS::POWERSTATE_UNKNOWN; | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PowerX11::get_power_seconds_left() { | 
					
						
							|  |  |  | 	if (UpdatePowerInfo()) { | 
					
						
							|  |  |  | 		return nsecs_left; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PowerX11::get_power_percent_left() { | 
					
						
							|  |  |  | 	if (UpdatePowerInfo()) { | 
					
						
							|  |  |  | 		return percent_left; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2016-07-23 13:15:55 +02:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 15:47:28 +01:00
										 |  |  | } |