My slstatus configuration
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

199 行
3.8 KiB

  1. /* See LICENSE file for copyright and license details. */
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "../util.h"
  5. #if defined(__linux__)
  6. #include <limits.h>
  7. #include <stdint.h>
  8. #include <unistd.h>
  9. static const char *
  10. pick(const char *bat, const char *f1, const char *f2, char *path,
  11. size_t length)
  12. {
  13. if (esnprintf(path, length, f1, bat) > 0 &&
  14. access(path, R_OK) == 0) {
  15. return f1;
  16. }
  17. if (esnprintf(path, length, f2, bat) > 0 &&
  18. access(path, R_OK) == 0) {
  19. return f2;
  20. }
  21. return NULL;
  22. }
  23. const char *
  24. battery_perc(const char *bat)
  25. {
  26. int perc;
  27. char path[PATH_MAX];
  28. if (esnprintf(path, sizeof(path),
  29. "/sys/class/power_supply/%s/capacity", bat) < 0) {
  30. return NULL;
  31. }
  32. if (pscanf(path, "%d", &perc) != 1) {
  33. return NULL;
  34. }
  35. return bprintf("%d", perc);
  36. }
  37. const char *
  38. battery_state(const char *bat)
  39. {
  40. static struct {
  41. char *state;
  42. char *symbol;
  43. } map[] = {
  44. { "Charging", "+" },
  45. { "Discharging", "-" },
  46. };
  47. size_t i;
  48. char path[PATH_MAX], state[12];
  49. if (esnprintf(path, sizeof(path),
  50. "/sys/class/power_supply/%s/status", bat) < 0) {
  51. return NULL;
  52. }
  53. if (pscanf(path, "%12s", state) != 1) {
  54. return NULL;
  55. }
  56. for (i = 0; i < LEN(map); i++) {
  57. if (!strcmp(map[i].state, state)) {
  58. break;
  59. }
  60. }
  61. return (i == LEN(map)) ? "?" : map[i].symbol;
  62. }
  63. const char *
  64. battery_remaining(const char *bat)
  65. {
  66. uintmax_t charge_now, current_now, m, h;
  67. double timeleft;
  68. char path[PATH_MAX], state[12];
  69. if (esnprintf(path, sizeof(path),
  70. "/sys/class/power_supply/%s/status", bat) < 0) {
  71. return NULL;
  72. }
  73. if (pscanf(path, "%12s", state) != 1) {
  74. return NULL;
  75. }
  76. if (!pick(bat, "/sys/class/power_supply/%s/charge_now",
  77. "/sys/class/power_supply/%s/energy_now", path,
  78. sizeof(path)) ||
  79. pscanf(path, "%ju", &charge_now) < 0) {
  80. return NULL;
  81. }
  82. if (!strcmp(state, "Discharging")) {
  83. if (!pick(bat, "/sys/class/power_supply/%s/current_now",
  84. "/sys/class/power_supply/%s/power_now", path,
  85. sizeof(path)) ||
  86. pscanf(path, "%ju", &current_now) < 0) {
  87. return NULL;
  88. }
  89. if (current_now == 0) {
  90. return NULL;
  91. }
  92. timeleft = (double)charge_now / (double)current_now;
  93. h = timeleft;
  94. m = (timeleft - (double)h) * 60;
  95. return bprintf("%juh %jum", h, m);
  96. }
  97. return "";
  98. }
  99. #elif defined(__OpenBSD__)
  100. #include <fcntl.h>
  101. #include <machine/apmvar.h>
  102. #include <sys/ioctl.h>
  103. #include <unistd.h>
  104. static int
  105. load_apm_power_info(struct apm_power_info *apm_info)
  106. {
  107. int fd;
  108. fd = open("/dev/apm", O_RDONLY);
  109. if (fd < 0) {
  110. warn("open '/dev/apm':");
  111. return 0;
  112. }
  113. memset(apm_info, 0, sizeof(struct apm_power_info));
  114. if (ioctl(fd, APM_IOC_GETPOWER, apm_info) < 0) {
  115. warn("ioctl 'APM_IOC_GETPOWER':");
  116. close(fd);
  117. return 0;
  118. }
  119. return close(fd), 1;
  120. }
  121. const char *
  122. battery_perc(const char *unused)
  123. {
  124. struct apm_power_info apm_info;
  125. if (load_apm_power_info(&apm_info)) {
  126. return bprintf("%d", apm_info.battery_life);
  127. }
  128. return NULL;
  129. }
  130. const char *
  131. battery_state(const char *unused)
  132. {
  133. struct {
  134. unsigned int state;
  135. char *symbol;
  136. } map[] = {
  137. { APM_AC_ON, "+" },
  138. { APM_AC_OFF, "-" },
  139. };
  140. struct apm_power_info apm_info;
  141. size_t i;
  142. if (load_apm_power_info(&apm_info)) {
  143. for (i = 0; i < LEN(map); i++) {
  144. if (map[i].state == apm_info.ac_state) {
  145. break;
  146. }
  147. }
  148. return (i == LEN(map)) ? "?" : map[i].symbol;
  149. }
  150. return NULL;
  151. }
  152. const char *
  153. battery_remaining(const char *unused)
  154. {
  155. struct apm_power_info apm_info;
  156. if (load_apm_power_info(&apm_info)) {
  157. if (apm_info.ac_state != APM_AC_ON) {
  158. return bprintf("%uh %02um",
  159. apm_info.minutes_left / 60,
  160. apm_info.minutes_left % 60);
  161. } else {
  162. return "";
  163. }
  164. }
  165. return NULL;
  166. }
  167. #endif