d31e37921f862cd6fac684100db52a2dde1de17d
[monky] / src / ibm.c
1 /* Conky, a system monitor, based on torsmo
2  *
3  * Any original torsmo code is licensed under the BSD license
4  *
5  * All code written since the fork of torsmo is licensed under the GPL
6  *
7  * Please see COPYING for details
8  *
9  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
10  * Copyright (c) 2007 Toni Spets
11  * Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al.
12  *      (see AUTHORS)
13  * All rights reserved.
14  *
15  * This program is free software: you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation, either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  * You should have received a copy of the GNU General Public License
25  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28
29 #include "conky.h"
30 #include "config.h"
31 #include "ibm.h"
32 #include "logging.h"
33 #include <stdio.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <stdlib.h>
37
38 /* Here come the IBM ACPI-specific things. For reference, see
39  * http://ibm-acpi.sourceforge.net/README
40  * If IBM ACPI is installed, /proc/acpi/ibm contains the following files:
41 bay
42 beep
43 bluetooth
44 brightness
45 cmos
46 dock
47 driver
48 ecdump
49 fan
50 hotkey
51 led
52 light
53 thermal
54 video
55 volume
56  * The content of these files is described in detail in the aforementioned
57  * README - some of them also in the following functions accessing them.
58  * Peter Tarjan (ptarjan@citromail.hu) */
59
60 #define IBM_ACPI_DIR "/proc/acpi/ibm"
61
62 /* get fan speed on IBM/Lenovo laptops running the ibm acpi.
63  * /proc/acpi/ibm/fan looks like this (3 lines):
64 status:         disabled
65 speed:          2944
66 commands:       enable, disable
67  * Peter Tarjan (ptarjan@citromail.hu) */
68
69 void get_ibm_acpi_fan(char *p_client_buffer, size_t client_buffer_size)
70 {
71         FILE *fp;
72         unsigned int speed = 0;
73         char fan[128];
74
75         if (!p_client_buffer || client_buffer_size <= 0) {
76                 return;
77         }
78
79         snprintf(fan, 127, "%s/fan", IBM_ACPI_DIR);
80
81         fp = fopen(fan, "r");
82         if (fp != NULL) {
83                 while (!feof(fp)) {
84                         char line[256];
85
86                         if (fgets(line, 255, fp) == NULL) {
87                                 break;
88                         }
89                         if (sscanf(line, "speed: %u", &speed)) {
90                                 break;
91                         }
92                 }
93         } else {
94                 CRIT_ERR("can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
95                         "ibm* from your "PACKAGE_NAME" config file.", fan, strerror(errno));
96         }
97
98         fclose(fp);
99         snprintf(p_client_buffer, client_buffer_size, "%d", speed);
100 }
101
102 /* get the measured temperatures from the temperature sensors
103  * on IBM/Lenovo laptops running the ibm acpi.
104  * There are 8 values in /proc/acpi/ibm/thermal, and according to
105  * http://ibm-acpi.sourceforge.net/README
106  * these mean the following (at least on an IBM R51...)
107  * 0:  CPU (also on the T series laptops)
108  * 1:  Mini PCI Module (?)
109  * 2:  HDD (?)
110  * 3:  GPU (also on the T series laptops)
111  * 4:  Battery (?)
112  * 5:  N/A
113  * 6:  Battery (?)
114  * 7:  N/A
115  * I'm not too sure about those with the question mark, but the values I'm
116  * reading from *my* thermal file (on a T42p) look realistic for the
117  * hdd and the battery.
118  * #5 and #7 are always -128.
119  * /proc/acpi/ibm/thermal looks like this (1 line):
120 temperatures:   41 43 31 46 33 -128 29 -128
121  * Peter Tarjan (ptarjan@citromail.hu) */
122
123 static double last_ibm_acpi_temp_time;
124 void get_ibm_acpi_temps(void)
125 {
126
127         FILE *fp;
128         char thermal[128];
129
130         /* don't update too often */
131         if (current_update_time - last_ibm_acpi_temp_time < 10.00) {
132                 return;
133         }
134         last_ibm_acpi_temp_time = current_update_time;
135
136         /* if (!p_client_buffer || client_buffer_size <= 0) {
137                 return;
138         } */
139
140         snprintf(thermal, 127, "%s/thermal", IBM_ACPI_DIR);
141         fp = fopen(thermal, "r");
142
143         if (fp != NULL) {
144                 while (!feof(fp)) {
145                         char line[256];
146
147                         if (fgets(line, 255, fp) == NULL) {
148                                 break;
149                         }
150                         if (sscanf(line, "temperatures: %d %d %d %d %d %d %d %d",
151                                         &ibm_acpi.temps[0], &ibm_acpi.temps[1], &ibm_acpi.temps[2],
152                                         &ibm_acpi.temps[3], &ibm_acpi.temps[4], &ibm_acpi.temps[5],
153                                         &ibm_acpi.temps[6], &ibm_acpi.temps[7])) {
154                                 break;
155                         }
156                 }
157         } else {
158                 CRIT_ERR("can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
159                         "ibm* from your "PACKAGE_NAME" config file.", thermal, strerror(errno));
160         }
161
162         fclose(fp);
163 }
164
165 /* get volume (0-14) on IBM/Lenovo laptops running the ibm acpi.
166  * "Volume" here is none of the mixer volumes, but a "master of masters"
167  * volume adjusted by the IBM volume keys.
168  * /proc/acpi/ibm/fan looks like this (4 lines):
169 level:          4
170 mute:           off
171 commands:       up, down, mute
172 commands:       level <level> (<level> is 0-15)
173  * Peter Tarjan (ptarjan@citromail.hu) */
174
175 void get_ibm_acpi_volume(char *p_client_buffer, size_t client_buffer_size)
176 {
177         FILE *fp;
178         char volume[128];
179         unsigned int vol = -1;
180         char mute[3] = "";
181
182         if (!p_client_buffer || client_buffer_size <= 0) {
183                 return;
184         }
185
186         snprintf(volume, 127, "%s/volume", IBM_ACPI_DIR);
187
188         fp = fopen(volume, "r");
189         if (fp != NULL) {
190                 while (!feof(fp)) {
191                         char line[256];
192                         unsigned int read_vol = -1;
193
194                         if (fgets(line, 255, fp) == NULL) {
195                                 break;
196                         }
197                         if (sscanf(line, "level: %u", &read_vol)) {
198                                 vol = read_vol;
199                                 continue;
200                         }
201                         if (sscanf(line, "mute: %s", mute)) {
202                                 break;
203                         }
204                 }
205         } else {
206                 CRIT_ERR("can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
207                         "ibm* from your "PACKAGE_NAME" config file.", volume, strerror(errno));
208         }
209
210         fclose(fp);
211
212         if (strcmp(mute, "on") == 0) {
213                 snprintf(p_client_buffer, client_buffer_size, "%s", "mute");
214                 return;
215         } else {
216                 snprintf(p_client_buffer, client_buffer_size, "%d", vol);
217                 return;
218         }
219 }
220
221 /* static FILE *fp = NULL; */
222
223 /* get LCD brightness on IBM/Lenovo laptops running the ibm acpi.
224  * /proc/acpi/ibm/brightness looks like this (3 lines):
225 level:          7
226 commands:       up, down
227 commands:       level <level> (<level> is 0-7)
228  * Peter Tarjan (ptarjan@citromail.hu) */
229
230 void get_ibm_acpi_brightness(char *p_client_buffer, size_t client_buffer_size)
231 {
232         FILE *fp;
233         unsigned int brightness = 0;
234         char filename[128];
235
236         if (!p_client_buffer || client_buffer_size <= 0) {
237                 return;
238         }
239
240         snprintf(filename, 127, "%s/brightness", IBM_ACPI_DIR);
241
242         fp = fopen(filename, "r");
243         if (fp != NULL) {
244                 while (!feof(fp)) {
245                         char line[256];
246
247                         if (fgets(line, 255, fp) == NULL) {
248                                 break;
249                         }
250                         if (sscanf(line, "level: %u", &brightness)) {
251                                 break;
252                         }
253                 }
254         } else {
255                 CRIT_ERR("can't open '%s': %s\nYou are not using the IBM ACPI. Remove "
256                         "ibm* from your "PACKAGE_NAME" config file.", filename, strerror(errno));
257         }
258
259         fclose(fp);
260
261         snprintf(p_client_buffer, client_buffer_size, "%d", brightness);
262 }
263