]> gitweb.michael.orlitzky.com - xfce4-hdaps.git/blob - panel-plugin/xfce4-hdaps.c
Fixed build with --enable-debug=full thanks to Evgeni Golov.
[xfce4-hdaps.git] / panel-plugin / xfce4-hdaps.c
1 /*
2 * xfce4-hdaps, an XFCE4 panel plugin for the HDAPS system.
3 *
4 * Copyright Michael Orlitzky
5 *
6 * http://michael.orlitzky.com/
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * http://www.fsf.org/licensing/licenses/gpl.html
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include "hdaps.h"
26 #include "xfce4-hdaps.h"
27 #include "xfce4-hdaps-dialogs.h"
28
29 /* We need a default device. Since we require kernels
30 newer than 2.6.28, it's probably sdX, and I'm guessing
31 that sda is most likely. */
32 #define DEFAULT_DEVICE_NAME "sda"
33
34 /* How often do we poll, in milliseconds?
35 This should be configured, but we set the default here. */
36 #define DEFAULT_POLL_FREQUENCY 500
37
38
39 /* Prototype, needed to register below. */
40 static void hdaps_construct(XfcePanelPlugin *plugin);
41
42 /* Register the plugin with the panel. */
43 XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL(hdaps_construct);
44
45
46 void hdaps_save(XfcePanelPlugin *plugin, HdapsPlugin *hdaps) {
47
48 XfceRc *rc;
49 gchar *file;
50
51 /* Get the config file location. XFCE should know this. */
52 file = xfce_panel_plugin_save_location(plugin, TRUE);
53
54 if (G_UNLIKELY(file == NULL)) {
55 DBG("Failed to find the configuration file. Bailing.");
56 return;
57 }
58
59 /* Open the config file read/write. */
60 rc = xfce_rc_simple_open(file, FALSE);
61
62 /* And we can free the file path now that we've
63 opened the file. */
64 g_free(file);
65
66 if (G_UNLIKELY(rc == NULL)) {
67 DBG("Failed to open the configuration file. Bailing.");
68 return;
69 }
70
71
72 /* Write any user-configured values to the resource file. */
73 if (hdaps->device_name) {
74 xfce_rc_write_entry(rc, "device_name", hdaps->device_name);
75 }
76
77 xfce_rc_write_int_entry(rc, "poll_frequency", hdaps->poll_frequency);
78
79 /* close the rc file */
80 xfce_rc_close(rc);
81 }
82
83
84
85 void hdaps_set_icon(HdapsPlugin *hdaps, int status) {
86 GdkPixbuf *icon;
87 gint size;
88
89 /* Panel info magic. */
90 size = xfce_panel_plugin_get_size(hdaps->plugin) - 6;
91
92 /* Try to load an icon from the current icon theme. */
93 if (status == HDAPS_ERROR) {
94 /* Error */
95 icon = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
96 "emblem-noread",
97 size, 0, NULL);
98 }
99 else if (status == HDAPS_OFF) {
100 icon = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
101 "drive-harddisk",
102 size, 0, NULL);
103 }
104 else {
105 /* status > HDAPS_OFF means it's on. */
106 icon = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
107 "emblem-nowrite",
108 size, 0, NULL);
109 }
110
111 /* Get rid of the previous icon. */
112 if (hdaps->icon) {
113 gtk_widget_destroy(hdaps->icon);
114 }
115
116 if (icon) {
117 hdaps->icon = gtk_image_new_from_pixbuf(icon);
118 g_object_unref(G_OBJECT(icon));
119 }
120 else {
121 hdaps->icon = gtk_image_new_from_icon_name("dialog-warning", GTK_ICON_SIZE_BUTTON);
122 }
123
124 gtk_box_pack_start(GTK_BOX(hdaps->hvbox), GTK_WIDGET(hdaps->icon), FALSE, FALSE, 0);
125 gtk_widget_show(hdaps->icon);
126
127 return;
128 }
129
130
131
132 void hdaps_set_tooltip(HdapsPlugin *hdaps, int status) {
133
134 if (status == HDAPS_ERROR) {
135 gtk_tooltips_set_tip(hdaps->tooltip, hdaps->eventbox, "HDAPS Error", NULL);
136 }
137 else if (status == HDAPS_OFF) {
138 gtk_tooltips_set_tip(hdaps->tooltip, hdaps->eventbox, "HDAPS Off", NULL);
139 }
140 else {
141 gtk_tooltips_set_tip(hdaps->tooltip, hdaps->eventbox, "HDAPS On", NULL);
142 }
143 }
144
145
146 static void hdaps_set_defaults(HdapsPlugin *hdaps) {
147 DBG("Configuring all settings to defaults.");
148
149 /* Here we determine the default device name. There are essentially
150 two "defaults," one soft, and the other hard. The soft default
151 is to choose the first supported HDAPS device in the system. This
152 would benefit users who, for example, only have one supported drive
153 named hda. If we can't find any supported HDAPS devices, we use the
154 hard default of DEFAULT_DEVICE_NAME. */
155 char hdaps_devices[MAX_HDAPS_DEVICES][FILENAME_MAX];
156 int found_devices = get_hdaps_device_list(hdaps_devices);
157
158 if (found_devices > 0) {
159 hdaps->device_name = g_strdup(hdaps_devices[0]);
160 }
161 else {
162 hdaps->device_name = g_strdup(DEFAULT_DEVICE_NAME);
163 }
164
165 snprintf(hdaps->sysfs_file, FILENAME_MAX, UNLOAD_HEADS_FMT, hdaps->device_name);
166
167 /* The other default is easier. */
168 hdaps->poll_frequency = DEFAULT_POLL_FREQUENCY;
169 }
170
171
172 static void hdaps_read(HdapsPlugin *hdaps) {
173
174 XfceRc *rc;
175 gchar *file;
176 const gchar *saved_device_name;
177
178 /* Get the plugin config file location. XFCE should know this. */
179 file = xfce_panel_plugin_save_location(hdaps->plugin, TRUE);
180
181 if (G_UNLIKELY(file == NULL)) {
182 DBG("Something went wrong getting the configuration file location.");
183 DBG("Retaining default settings.");
184 return;
185 }
186
187 /* Open the config file read-only. */
188 rc = xfce_rc_simple_open(file, TRUE);
189
190 /* Don't need this anymore if we've got a file handle. */
191 g_free(file);
192
193 if (G_UNLIKELY(rc == NULL)) {
194 DBG("There was an error opening the configuration file.");
195 DBG("Retaining default settings.");
196 return;
197 }
198
199 /* Read the settings, one at a time. */
200
201 /* We use saved_device_name here because we need
202 to dupe the string after we read it in from the
203 config file. */
204 saved_device_name = xfce_rc_read_entry(rc,
205 "device_name",
206 DEFAULT_DEVICE_NAME);
207 hdaps->device_name = g_strdup(saved_device_name);
208 snprintf(hdaps->sysfs_file, FILENAME_MAX, UNLOAD_HEADS_FMT, hdaps->device_name);
209
210 /* Integers are easier. */
211 hdaps->poll_frequency = xfce_rc_read_int_entry(rc,
212 "poll_frequency",
213 DEFAULT_POLL_FREQUENCY);
214
215 /* And close the config file. */
216 xfce_rc_close(rc);
217 }
218
219
220
221
222 static HdapsPlugin *hdaps_new(XfcePanelPlugin *plugin) {
223 HdapsPlugin *hdaps;
224 GtkOrientation orientation;
225
226 /* Allocate memory for the plugin struct, and zero it. */
227 hdaps = panel_slice_new0(HdapsPlugin);
228
229 /* The HdapsPlugin gets a copy of the XfcePanelPlugin. */
230 hdaps->plugin = plugin;
231
232 /* Set default values right before reading in the user's settings.
233 This way, hdaps_read() doesn't have to set defaults on error
234 conditions. */
235 hdaps_set_defaults(hdaps);
236
237 /* Read any user settings into the HdapsPlugin. */
238 hdaps_read(hdaps);
239
240 /* Get the current orientation. Magic. */
241 orientation = xfce_panel_plugin_get_orientation(plugin);
242
243 /* This creates the event box and shows it. This
244 is necessary to,
245
246 a) See the widget
247 b) Interact with it via right-click, etc.
248 */
249 hdaps->eventbox = gtk_event_box_new();
250 gtk_widget_show(hdaps->eventbox);
251
252 /* Set up the hvbox for the widget, which supports
253 both horizontal and vertical (hv) orientations. */
254 hdaps->hvbox = xfce_hvbox_new(orientation, FALSE, 2);
255 gtk_widget_show(hdaps->hvbox);
256 gtk_container_add(GTK_CONTAINER(hdaps->eventbox), hdaps->hvbox);
257
258 /* We only change the icon when the status has changed,
259 so it's important that they start out n*sync. */
260 hdaps->previous_status = HDAPS_OFF;
261 hdaps_set_icon(hdaps, HDAPS_OFF);
262
263 /* Create the tooltip widget, and set its initial value.
264 * The first couple of lines are stolen from the battery
265 * status plugin. I make no claim as to their correctness.
266 */
267 hdaps->tooltip = gtk_tooltips_new();
268 g_object_ref(G_OBJECT(hdaps->tooltip));
269 gtk_object_sink(GTK_OBJECT(hdaps->tooltip));
270 hdaps_set_tooltip(hdaps, HDAPS_OFF);
271
272 return hdaps;
273 }
274
275
276
277 static void hdaps_free(XfcePanelPlugin *plugin,
278 HdapsPlugin *hdaps) {
279
280 GtkWidget *dialog;
281
282 /* Destroy the dialog if it's still open. */
283 dialog = g_object_get_data(G_OBJECT(plugin), "dialog");
284
285 if (G_UNLIKELY(dialog != NULL)) {
286 gtk_widget_destroy(dialog);
287 }
288
289 /* Destroy the panel widgets. When dumb comments like these
290 are left over, they're from the sample panel applet,
291 I swear. */
292 gtk_widget_destroy(hdaps->hvbox);
293
294 /* Remove the timeout that was set during creation. */
295 if (hdaps->timeout) {
296 g_source_remove(hdaps->timeout);
297 }
298
299 /* And free the string (if any) containing
300 the device name. */
301 if (G_LIKELY(hdaps->device_name != NULL)) {
302 g_free(hdaps->device_name);
303 }
304
305 /* Goodbye, tooltips. */
306 gtk_tooltips_set_tip(hdaps->tooltip, hdaps->eventbox, NULL, NULL);
307 g_object_unref(G_OBJECT(hdaps->tooltip));
308
309 /* ...and finally free the plugin structure. */
310 panel_slice_free(HdapsPlugin, hdaps);
311 }
312
313
314
315 static void hdaps_orientation_changed(XfcePanelPlugin *plugin,
316 GtkOrientation orientation,
317 HdapsPlugin *hdaps) {
318
319 /* Change the plugin's orientation. Basically magic to me. */
320 xfce_hvbox_set_orientation(XFCE_HVBOX(hdaps->hvbox), orientation);
321 }
322
323
324
325 static gboolean hdaps_size_changed(XfcePanelPlugin *plugin,
326 gint size,
327 HdapsPlugin *hdaps) {
328
329 GtkOrientation orientation;
330
331 /* Get the current orientation of the plugin. */
332 orientation = xfce_panel_plugin_get_orientation(plugin);
333
334 /* We want to make the widget "bigger" in the direction
335 of its orientation. Or is it the other way around? */
336 if (orientation == GTK_ORIENTATION_HORIZONTAL) {
337 gtk_widget_set_size_request(GTK_WIDGET(plugin), -1, size);
338 }
339 else {
340 gtk_widget_set_size_request(GTK_WIDGET(plugin), size, -1);
341 }
342
343 /* We handled the change, so we're supposed to return TRUE. */
344 return TRUE;
345 }
346
347
348
349 static gboolean hdaps_update_status(HdapsPlugin *hdaps) {
350 /* This checks the status of HDAPS and updates the
351 widget accordingly. */
352
353 /* This just gets the status. */
354 int status = parse_int_from_file(hdaps->sysfs_file);
355
356 /* The value in the sysfs_file represents the number of milliseconds
357 * that the drive heads will be parked. Of course, this will
358 * generally count down, and appear different each time we poll.
359 *
360 * So, to determine whether or not HDAPS has gone from "on"
361 * to "off," we treat all values greater than zero the same.
362 */
363 if (status > 0) {
364 status = HDAPS_ON;
365 }
366
367 if (status != hdaps->previous_status) {
368 /* And we only update the icon if we need to. */
369 hdaps_set_icon(hdaps, status);
370 hdaps_set_tooltip(hdaps, status);
371 hdaps->previous_status = status;
372 }
373
374 return TRUE;
375 }
376
377
378
379 void hdaps_reset_timeout(HdapsPlugin *hdaps) {
380 /* Remove, and then re-set the timeout function. Useful
381 for changing the poll frequency. */
382 if (hdaps->timeout) {
383 g_source_remove(hdaps->timeout);
384 }
385
386 hdaps->timeout = g_timeout_add(hdaps->poll_frequency, (GSourceFunc)hdaps_update_status, hdaps);
387 }
388
389
390
391 static void hdaps_construct(XfcePanelPlugin *plugin) {
392 HdapsPlugin *hdaps;
393
394 /* Set the "translation domain". I don't know what that does. */
395 xfce_textdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
396
397 /* First, create the plugin. */
398 hdaps = hdaps_new(plugin);
399
400 /* Add the plugin's eventbox to the panel. */
401 gtk_container_add(GTK_CONTAINER(plugin), hdaps->eventbox);
402
403 /* This configures the right-click menu to appear
404 on the plugin's eventbox. */
405 xfce_panel_plugin_add_action_widget(plugin, hdaps->eventbox);
406
407 /* Connect the common event handlers. */
408 g_signal_connect(G_OBJECT(plugin), "free-data",
409 G_CALLBACK(hdaps_free), hdaps);
410
411 g_signal_connect (G_OBJECT(plugin), "save",
412 G_CALLBACK(hdaps_save), hdaps);
413
414 g_signal_connect (G_OBJECT(plugin), "size-changed",
415 G_CALLBACK(hdaps_size_changed), hdaps);
416
417 g_signal_connect (G_OBJECT(plugin), "orientation-changed",
418 G_CALLBACK(hdaps_orientation_changed), hdaps);
419
420 /* Show the "configure" right-click menu item, and
421 connect its event handler. */
422 xfce_panel_plugin_menu_show_configure(plugin);
423 g_signal_connect(G_OBJECT(plugin), "configure-plugin",
424 G_CALLBACK(hdaps_configure), hdaps);
425
426 /* Show the "about" right-click menu item, and
427 connect its event handler. */
428 xfce_panel_plugin_menu_show_about(plugin);
429 g_signal_connect(G_OBJECT(plugin), "about",
430 G_CALLBACK(hdaps_about), hdaps);
431
432 /* Set the timeout for the function which checks the
433 HDAPS status. */
434 hdaps_reset_timeout(hdaps);
435
436 return;
437 }