1 /* $Id$ */
2 /* Copyright (c) 2010-2015 Pierre Pronchery <khorben@defora.org> */
3 /* This file is part of DeforaOS Desktop Panel */
4 /* This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 3 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */
15
16
17
18 #include <sys/time.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <time.h>
22 #include <errno.h>
23 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
24 # include <sys/param.h>
25 # include <sys/sched.h>
26 # include <sys/sysctl.h>
27 #endif
28 #include <libintl.h>
29 #include <System.h>
30 #include "Panel/applet.h"
31 #define _(string) gettext(string)
32
33
34 /* Cpufreq */
35 /* private */
36 /* types */
37 typedef struct _PanelApplet
38 {
39 PanelAppletHelper * helper;
40 GtkWidget * hbox;
41 GtkWidget * label;
42 guint timeout;
43 int min;
44 int max;
45 int step;
46 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
47 char const * name;
48 #endif
49 } Cpufreq;
50
51
52 /* prototypes */
53 static Cpufreq * _cpufreq_init(PanelAppletHelper * helper, GtkWidget ** widget);
54 static void _cpufreq_destroy(Cpufreq * cpufreq);
55
56 /* callbacks */
57 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
58 static gboolean _cpufreq_on_timeout(gpointer data);
59 #endif
60
61
62 /* public */
63 /* variables */
64 PanelAppletDefinition applet =
65 {
66 "CPU frequency",
67 "gnome-monitor",
68 NULL,
69 _cpufreq_init,
70 _cpufreq_destroy,
71 NULL,
72 FALSE,
73 TRUE
74 };
75
76
77 /* private */
78 /* functions */
79 /* cpufreq_init */
_cpufreq_init(PanelAppletHelper * helper,GtkWidget ** widget)80 static Cpufreq * _cpufreq_init(PanelAppletHelper * helper, GtkWidget ** widget)
81 {
82 const int timeout = 1000;
83 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
84 Cpufreq * cpufreq;
85 PangoFontDescription * desc;
86 GtkWidget * image;
87 GtkWidget * label;
88 char freq[256];
89 size_t freqsize = sizeof(freq);
90 char const * p;
91
92 /* detect the correct sysctl */
93 if(sysctlbyname("hw.clockrate", &freq, &freqsize, NULL, 0) == 0)
94 p = "hw.clockrate";
95 else if(sysctlbyname("machdep.est.frequency.available", &freq,
96 &freqsize, NULL, 0) == 0)
97 p = "machdep.est.frequency.current";
98 else if(sysctlbyname("machdep.powernow.frequency.available", &freq,
99 &freqsize, NULL, 0) == 0)
100 p = "machdep.powernow.frequency.current";
101 else if(sysctlbyname("machdep.frequency.available", &freq, &freqsize,
102 NULL, 0) == 0)
103 p = "machdep.frequency.current";
104 else
105 {
106 error_set("%s: %s", applet.name, _("No support detected"));
107 return NULL;
108 }
109 if((cpufreq = malloc(sizeof(*cpufreq))) == NULL)
110 {
111 error_set("%s: %s", applet.name, strerror(errno));
112 return NULL;
113 }
114 cpufreq->helper = helper;
115 desc = pango_font_description_new();
116 pango_font_description_set_family(desc, "Monospace");
117 pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD);
118 #if GTK_CHECK_VERSION(3, 0, 0)
119 cpufreq->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
120 #else
121 cpufreq->hbox = gtk_hbox_new(FALSE, 4);
122 #endif
123 image = gtk_image_new_from_icon_name("gnome-monitor",
124 panel_window_get_icon_size(helper->window));
125 gtk_box_pack_start(GTK_BOX(cpufreq->hbox), image, FALSE, TRUE, 0);
126 cpufreq->min = 0;
127 cpufreq->max = 0;
128 cpufreq->step = 1;
129 cpufreq->name = p;
130 cpufreq->max = atoi(freq);
131 cpufreq->min = (p = strrchr(freq, ' ')) != NULL ? atoi(p)
132 : cpufreq->max;
133 cpufreq->label = gtk_label_new(" ");
134 #if GTK_CHECK_VERSION(3, 0, 0)
135 gtk_widget_override_font(cpufreq->label, desc);
136 #else
137 gtk_widget_modify_font(cpufreq->label, desc);
138 #endif
139 gtk_box_pack_start(GTK_BOX(cpufreq->hbox), cpufreq->label, FALSE, TRUE,
140 0);
141 label = gtk_label_new(_("MHz"));
142 gtk_box_pack_start(GTK_BOX(cpufreq->hbox), label, FALSE, TRUE, 0);
143 if(_cpufreq_on_timeout(cpufreq) == TRUE)
144 cpufreq->timeout = g_timeout_add(timeout, _cpufreq_on_timeout,
145 cpufreq);
146 pango_font_description_free(desc);
147 gtk_widget_show_all(cpufreq->hbox);
148 *widget = cpufreq->hbox;
149 return cpufreq;
150 #else
151 error_set("%s: %s", applet.name, _("Unsupported platform"));
152 return NULL;
153 #endif
154 }
155
156
157 /* cpufreq_destroy */
_cpufreq_destroy(Cpufreq * cpufreq)158 static void _cpufreq_destroy(Cpufreq * cpufreq)
159 {
160 g_source_remove(cpufreq->timeout);
161 gtk_widget_destroy(cpufreq->hbox);
162 free(cpufreq);
163 }
164
165
166 /* callbacks */
167 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
168 /* cpufreq_on_timeout */
_cpufreq_on_timeout(gpointer data)169 static gboolean _cpufreq_on_timeout(gpointer data)
170 {
171 Cpufreq * cpufreq = data;
172 PanelAppletHelper * helper = cpufreq->helper;
173 uint64_t freq;
174 size_t freqsize = sizeof(freq);
175 char buf[256];
176
177 if(sysctlbyname(cpufreq->name, &freq, &freqsize, NULL, 0) < 0)
178 {
179 error_set("%s: %s: %s", applet.name, cpufreq->name,
180 strerror(errno));
181 helper->error(NULL, error_get(NULL), 1);
182 return TRUE;
183 }
184 snprintf(buf, sizeof(buf), "%4u", (unsigned int)freq);
185 gtk_label_set_text(GTK_LABEL(cpufreq->label), buf);
186 # if GTK_CHECK_VERSION(2, 12, 0)
187 snprintf(buf, sizeof(buf), "%s%u %s", _("CPU frequency: "),
188 (unsigned int)freq, _("MHz"));
189 gtk_widget_set_tooltip_text(cpufreq->hbox, buf);
190 # endif
191 return TRUE;
192 }
193 #endif
194