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