correctly set modified flag after auto-save
[claws.git] / src / plugins / acpi_notifier / acpi_notifier.c
blob9125af905947d054269d562b6511a69b07a95d9c
1 /*
2 * acpi_notifier -- for Claws Mail
4 * Copyright (C) 2005-2019 Colin Leroy <colin@colino.net>
5 * and the Claws Mail Team
7 * Sylpheed is a GTK based, lightweight, and fast e-mail client
8 * Copyright (C) 1999-2019 Hiroyuki Yamamoto and the Claws Mail Team
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #include "claws-features.h"
28 #endif
30 #include <glib.h>
31 #include <glib/gi18n.h>
33 #include <string.h>
35 #include <gtk/gtk.h>
37 #include "defs.h"
38 #include "claws.h"
39 #include "version.h"
40 #include "prefs.h"
41 #include "prefs_gtk.h"
42 #include "main.h"
43 #include "menu.h"
44 #include "hooks.h"
45 #include "plugin.h"
46 #include "alertpanel.h"
47 #include "utils.h"
48 #include "folder_item_prefs.h"
49 #include "gtk/gtkutils.h"
50 #include "gtk/combobox.h"
51 #include "file-utils.h"
53 #define PREFS_BLOCK_NAME "AcpiNotifier"
54 #define PLUGIN_NAME _("Acpi Notifier")
56 typedef struct _PredefinedAcpis {
57 gchar *name;
58 gchar *on_param;
59 gchar *off_param;
60 gchar *file_path;
61 gboolean is_program;
62 gchar *help;
63 } PredefinedAcpis;
65 /**
66 * Add your implementation here (and send me the patch!)
68 char *acpi_help[] = {
69 "",
70 N_("Make sure that the kernel module 'acerhk' is loaded.\n"
71 "You can get it from http://www.cakey.de/acerhk/"),
72 N_("Make sure that the kernel module 'acer_acpi' is loaded.\n"
73 "You can get it from http://code.google.com/p/aceracpi/"),
74 N_("Make sure that the kernel module 'asus_laptop' is loaded."),
75 N_("Make sure that the kernel module 'asus_acpi' is loaded."),
76 N_("Make sure that the kernel module 'ibm_acpi' is loaded."),
77 N_("Make sure that you have apanelc installed.\n"
78 "You can get it from http://apanel.sourceforge.net/"),
79 NULL
81 PredefinedAcpis known_implementations[] = {
82 {"Other file", "", "", "", FALSE, NULL},
84 {"ACER (acerhk)", "1", "0", "/proc/driver/acerhk/led", FALSE, NULL},
86 {"ACER (acer_acpi)", "1", "0", "/proc/acpi/acer/mailled", FALSE, NULL},
88 {"ASUS (asus_laptop)", "1", "0", "/sys/class/leds/asus:mail/brightness", FALSE, NULL},
90 {"ASUS (asus_acpi)", "1", "0", "/proc/acpi/asus/mled", FALSE, NULL},
92 {"IBM (ibm_acpi)", "7 on", "7 off", "/proc/acpi/ibm/led", FALSE, NULL},
94 {"Lenovo (tp_smapi)", "on", "off", "/proc/acpi/ibm/light", FALSE, NULL},
96 {"Fujitsu (apanel)", "led on", "led off", "apanelc", TRUE, NULL},
98 {NULL, NULL, NULL, NULL, FALSE, NULL}
101 static gulong folder_hook_id = HOOK_NONE;
102 static gulong alertpanel_hook_id = HOOK_NONE;
104 struct AcpiNotifierPage
106 PrefsPage page;
108 GtkWidget *no_mail_off_btn;
109 GtkWidget *no_mail_blink_btn;
110 GtkWidget *no_mail_on_btn;
111 GtkWidget *unread_mail_off_btn;
112 GtkWidget *unread_mail_blink_btn;
113 GtkWidget *unread_mail_on_btn;
114 GtkWidget *new_mail_off_btn;
115 GtkWidget *new_mail_blink_btn;
116 GtkWidget *new_mail_on_btn;
117 GtkWidget *default_implementations_optmenu;
118 GtkWidget *on_value_entry;
119 GtkWidget *off_value_entry;
120 GtkWidget *file_entry;
121 GtkWidget *hbox_acpi_file;
122 GtkWidget *hbox_acpi_values;
123 GtkWidget *warning_label;
124 GtkWidget *warning_box;
125 GtkWidget *blink_on_err_chkbtn;
128 typedef struct _AcpiNotifierPrefs AcpiNotifierPrefs;
130 struct _AcpiNotifierPrefs
132 gint no_mail_action;
133 gint unread_mail_action;
134 gint new_mail_action;
135 gboolean blink_on_err;
136 gchar *on_param;
137 gchar *off_param;
138 gchar *file_path;
141 AcpiNotifierPrefs acpiprefs;
143 static struct AcpiNotifierPage acpi_prefs_page;
145 enum {
146 OFF = 0,
147 BLINK,
149 } BlinkType;
151 static PrefParam param[] = {
152 {"no_mail_action", "0", &acpiprefs.no_mail_action, P_INT,
153 NULL, NULL, NULL},
154 {"unread_mail_action", "0", &acpiprefs.unread_mail_action, P_INT,
155 NULL, NULL, NULL},
156 {"new_mail_action", "1", &acpiprefs.new_mail_action, P_INT,
157 NULL, NULL, NULL},
158 {"blink_on_err", "TRUE", &acpiprefs.blink_on_err, P_BOOL,
159 NULL, NULL, NULL},
160 {"on_param", NULL, &acpiprefs.on_param, P_STRING,
161 NULL, NULL, NULL},
162 {"off_param", NULL, &acpiprefs.off_param, P_STRING,
163 NULL, NULL, NULL},
164 {"file_path", NULL, &acpiprefs.file_path, P_STRING,
165 NULL, NULL, NULL},
166 {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
169 static gboolean check_impl (const gchar *filepath)
171 int i;
172 for (i = 0; known_implementations[i].name != NULL; i++) {
173 if (strcmp(known_implementations[i].file_path, filepath))
174 continue;
175 if (!known_implementations[i].is_program)
176 return is_file_exist(filepath);
177 else {
178 gchar *cmd = g_strdup_printf("which %s", filepath);
179 int found = system(cmd);
180 g_free(cmd);
181 return (found == 0);
184 return is_file_exist(filepath);
187 static gboolean is_program (const gchar *filepath)
189 int i;
190 for (i = 0; known_implementations[i].name != NULL; i++) {
191 if (strcmp(known_implementations[i].file_path, filepath))
192 continue;
193 return known_implementations[i].is_program;
195 return FALSE;
198 static void show_error (struct AcpiNotifierPage *page, const gchar *filepath)
200 int i;
201 if (!filepath) {
202 gtk_widget_hide(page->warning_box);
203 return;
205 for (i = 0; known_implementations[i].name != NULL; i++) {
206 if (strcmp(known_implementations[i].file_path, filepath))
207 continue;
208 if (known_implementations[i].help) {
209 gchar *tmp = g_strdup_printf("%s\n%s",
210 _("Control file doesn't exist."),
211 known_implementations[i].help);
212 gtk_label_set_text(GTK_LABEL(page->warning_label), tmp);
213 g_free(tmp);
214 } else {
215 gtk_label_set_text(GTK_LABEL(page->warning_label),
216 _("Control file doesn't exist."));
218 gtk_widget_show_all(page->warning_box);
219 return;
223 static void type_changed(GtkComboBox *combobox, gpointer data)
225 gint selected = gtk_combo_box_get_active(combobox);
226 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *)data;
228 if (selected != 0) {
229 gtk_widget_hide(page->hbox_acpi_file);
230 gtk_widget_hide(page->hbox_acpi_values);
231 gtk_entry_set_text(GTK_ENTRY(page->file_entry),
232 known_implementations[selected].file_path);
233 gtk_entry_set_text(GTK_ENTRY(page->on_value_entry),
234 known_implementations[selected].on_param);
235 gtk_entry_set_text(GTK_ENTRY(page->off_value_entry),
236 known_implementations[selected].off_param);
237 if (!check_impl(known_implementations[selected].file_path))
238 show_error(page, known_implementations[selected].file_path);
239 else
240 show_error(page, NULL);
241 } else {
242 gtk_widget_show_all(page->hbox_acpi_file);
243 gtk_widget_show_all(page->hbox_acpi_values);
247 static void file_entry_changed (GtkWidget *entry, gpointer data)
249 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *)data;
250 if (!page->warning_box)
251 return;
253 if (!check_impl(gtk_entry_get_text(GTK_ENTRY(entry))))
254 show_error(page, gtk_entry_get_text(GTK_ENTRY(entry)));
255 else
256 show_error(page, NULL);
259 static void acpi_prefs_create_widget_func(PrefsPage * _page,
260 GtkWindow * window,
261 gpointer data)
263 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *) _page;
265 GtkWidget *vbox;
266 GtkWidget *hbox;
267 GtkWidget *hbox_acpi_file;
268 GtkWidget *hbox_acpi_values;
269 GtkWidget *start_label;
270 GtkWidget *no_mail_label;
271 GtkWidget *no_mail_off_btn;
272 GtkWidget *no_mail_blink_btn;
273 GtkWidget *no_mail_on_btn;
274 GtkWidget *unread_mail_label;
275 GtkWidget *unread_mail_off_btn;
276 GtkWidget *unread_mail_blink_btn;
277 GtkWidget *unread_mail_on_btn;
278 GtkWidget *new_mail_label;
279 GtkWidget *new_mail_off_btn;
280 GtkWidget *new_mail_blink_btn;
281 GtkWidget *new_mail_on_btn;
282 GtkWidget *default_implementations_optmenu;
283 GtkListStore *menu;
284 GtkWidget *on_value_entry;
285 GtkWidget *off_value_entry;
286 GtkWidget *file_entry;
287 GtkWidget *warning_label;
288 GtkWidget *warning_box;
289 GtkWidget *image;
290 GtkWidget *blink_on_err_chkbtn;
291 GtkTreeIter iter; /* iter for the COMBOBOX_ADD macro */
293 int i;
294 int found = 0;
296 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
297 gtk_container_set_border_width (GTK_CONTAINER (vbox), VBOX_BORDER);
299 no_mail_label = gtk_label_new(_(" : no new or unread mail"));
300 unread_mail_label = gtk_label_new(_(" : unread mail"));
301 new_mail_label = gtk_label_new(_(" : new mail"));
303 no_mail_off_btn = gtk_radio_button_new_with_label(NULL, _("off"));
304 no_mail_blink_btn = gtk_radio_button_new_with_label_from_widget(
305 GTK_RADIO_BUTTON(no_mail_off_btn), _("blinking"));
306 no_mail_on_btn = gtk_radio_button_new_with_label_from_widget(
307 GTK_RADIO_BUTTON(no_mail_off_btn), _("on"));
309 unread_mail_off_btn = gtk_radio_button_new_with_label(NULL, _("off"));
310 unread_mail_blink_btn = gtk_radio_button_new_with_label_from_widget(
311 GTK_RADIO_BUTTON(unread_mail_off_btn), _("blinking"));
312 unread_mail_on_btn = gtk_radio_button_new_with_label_from_widget(
313 GTK_RADIO_BUTTON(unread_mail_off_btn), _("on"));
315 new_mail_off_btn = gtk_radio_button_new_with_label(NULL, _("off"));
316 new_mail_blink_btn = gtk_radio_button_new_with_label_from_widget(
317 GTK_RADIO_BUTTON(new_mail_off_btn), _("blinking"));
318 new_mail_on_btn = gtk_radio_button_new_with_label_from_widget(
319 GTK_RADIO_BUTTON(new_mail_off_btn), _("on"));
321 on_value_entry = gtk_entry_new();
322 off_value_entry = gtk_entry_new();
323 file_entry = gtk_entry_new();
324 gtk_widget_set_size_request(on_value_entry, 40, -1);
325 gtk_widget_set_size_request(off_value_entry, 40, -1);
327 /* Create the ACPI type menu */
328 default_implementations_optmenu = gtkut_sc_combobox_create(NULL, FALSE);
329 menu = GTK_LIST_STORE(gtk_combo_box_get_model(
330 GTK_COMBO_BOX(default_implementations_optmenu)));
331 g_signal_connect(G_OBJECT(default_implementations_optmenu), "changed",
332 G_CALLBACK(type_changed), page);
334 /* Populate it with known implementations */
335 for (i = 0; known_implementations[i].name != NULL; i++) {
336 COMBOBOX_ADD(menu, known_implementations[i].name, i);
339 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
340 start_label = gtk_label_new(_("LED "));
341 gtk_box_pack_start(GTK_BOX(hbox), start_label, FALSE, FALSE, 0);
342 gtk_box_pack_start(GTK_BOX(hbox), no_mail_off_btn, FALSE, FALSE, 0);
343 gtk_box_pack_start(GTK_BOX(hbox), no_mail_blink_btn, FALSE, FALSE, 0);
344 gtk_box_pack_start(GTK_BOX(hbox), no_mail_on_btn, FALSE, FALSE, 0);
345 gtk_box_pack_start(GTK_BOX(hbox), no_mail_label, FALSE, FALSE, 0);
346 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
348 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
349 start_label = gtk_label_new(_("LED "));
350 gtk_box_pack_start(GTK_BOX(hbox),
351 start_label, FALSE, FALSE, 0);
352 gtk_box_pack_start(GTK_BOX(hbox),
353 unread_mail_off_btn, FALSE, FALSE, 0);
354 gtk_box_pack_start(GTK_BOX(hbox),
355 unread_mail_blink_btn, FALSE, FALSE, 0);
356 gtk_box_pack_start(GTK_BOX(hbox),
357 unread_mail_on_btn, FALSE, FALSE, 0);
358 gtk_box_pack_start(GTK_BOX(hbox),
359 unread_mail_label, FALSE, FALSE, 0);
360 gtk_box_pack_start(GTK_BOX(vbox),
361 hbox, FALSE, FALSE, 0);
363 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
364 start_label = gtk_label_new(_("LED "));
365 gtk_box_pack_start(GTK_BOX(hbox),
366 start_label, FALSE, FALSE, 0);
367 gtk_box_pack_start(GTK_BOX(hbox),
368 new_mail_off_btn, FALSE, FALSE, 0);
369 gtk_box_pack_start(GTK_BOX(hbox),
370 new_mail_blink_btn, FALSE, FALSE, 0);
371 gtk_box_pack_start(GTK_BOX(hbox),
372 new_mail_on_btn, FALSE, FALSE, 0);
373 gtk_box_pack_start(GTK_BOX(hbox),
374 new_mail_label, FALSE, FALSE, 0);
375 gtk_box_pack_start(GTK_BOX(vbox),
376 hbox, FALSE, FALSE, 0);
378 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
379 start_label = gtk_label_new(_("ACPI type: "));
380 gtk_box_pack_start(GTK_BOX(hbox),
381 start_label, FALSE, FALSE, 0);
382 gtk_box_pack_start(GTK_BOX(hbox),
383 default_implementations_optmenu, FALSE, FALSE, 0);
384 gtk_box_pack_start(GTK_BOX(vbox),
385 hbox, FALSE, FALSE, 0);
387 hbox_acpi_file = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
388 start_label = gtk_label_new(_("ACPI file: "));
389 gtk_box_pack_start(GTK_BOX(hbox_acpi_file),
390 start_label, FALSE, FALSE, 0);
391 gtk_box_pack_start(GTK_BOX(hbox_acpi_file),
392 file_entry, FALSE, FALSE, 0);
393 gtk_box_pack_start(GTK_BOX(vbox),
394 hbox_acpi_file, FALSE, FALSE, 0);
395 g_signal_connect(G_OBJECT(file_entry), "changed",
396 G_CALLBACK(file_entry_changed), page);
398 hbox_acpi_values = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
399 start_label = gtk_label_new(_("values - On: "));
400 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
401 start_label, FALSE, FALSE, 0);
402 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
403 on_value_entry, FALSE, FALSE, 0);
404 start_label = gtk_label_new(_(" - Off: "));
405 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
406 start_label, FALSE, FALSE, 0);
407 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
408 off_value_entry, FALSE, FALSE, 0);
409 gtk_box_pack_start(GTK_BOX(vbox),
410 hbox_acpi_values, FALSE, FALSE, 0);
412 warning_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
414 image = gtk_button_new_from_icon_name("dialog-warning",
415 GTK_ICON_SIZE_SMALL_TOOLBAR);
416 gtk_box_pack_start(GTK_BOX(warning_box), image, FALSE, FALSE, 0);
417 warning_label = gtk_label_new(
418 _("Control file doesn't exist."));
419 gtk_box_pack_start(GTK_BOX(warning_box), warning_label, FALSE, FALSE, 0);
420 gtk_box_pack_start(GTK_BOX(vbox), warning_box, FALSE, FALSE, 0);
422 gtk_widget_show_all(vbox);
423 gtk_widget_hide(warning_box);
425 blink_on_err_chkbtn = gtk_check_button_new_with_label(
426 _("Blink when user interaction is required"));
427 gtk_box_pack_start(GTK_BOX(vbox), blink_on_err_chkbtn, FALSE, FALSE, 0);
428 gtk_toggle_button_set_active(
429 GTK_TOGGLE_BUTTON(blink_on_err_chkbtn),
430 acpiprefs.blink_on_err);
431 gtk_widget_show(blink_on_err_chkbtn);
433 switch (acpiprefs.no_mail_action) {
434 case OFF:
435 gtk_toggle_button_set_active(
436 GTK_TOGGLE_BUTTON(no_mail_off_btn), TRUE);
437 break;
438 case BLINK:
439 gtk_toggle_button_set_active(
440 GTK_TOGGLE_BUTTON(no_mail_blink_btn), TRUE);
441 break;
442 case ON:
443 gtk_toggle_button_set_active(
444 GTK_TOGGLE_BUTTON(no_mail_on_btn), TRUE);
445 break;
448 switch (acpiprefs.unread_mail_action) {
449 case OFF:
450 gtk_toggle_button_set_active(
451 GTK_TOGGLE_BUTTON(unread_mail_off_btn), TRUE);
452 break;
453 case BLINK:
454 gtk_toggle_button_set_active(
455 GTK_TOGGLE_BUTTON(unread_mail_blink_btn), TRUE);
456 break;
457 case ON:
458 gtk_toggle_button_set_active(
459 GTK_TOGGLE_BUTTON(unread_mail_on_btn), TRUE);
460 break;
463 switch (acpiprefs.new_mail_action) {
464 case OFF:
465 gtk_toggle_button_set_active(
466 GTK_TOGGLE_BUTTON(new_mail_off_btn), TRUE);
467 break;
468 case BLINK:
469 gtk_toggle_button_set_active(
470 GTK_TOGGLE_BUTTON(new_mail_blink_btn), TRUE);
471 break;
472 case ON:
473 gtk_toggle_button_set_active(
474 GTK_TOGGLE_BUTTON(new_mail_on_btn), TRUE);
475 break;
478 if (acpiprefs.file_path != NULL) {
479 for (i = 0; known_implementations[i].name != NULL; i++) {
480 if (!strcmp(acpiprefs.file_path,
481 known_implementations[i].file_path)) {
482 gtk_combo_box_set_active(
483 GTK_COMBO_BOX(default_implementations_optmenu), i);
484 found = i;
488 if (found == 0) {
489 for (i = 0; known_implementations[i].name != NULL; i++) {
490 if (check_impl(known_implementations[i].file_path)) {
491 gtk_combo_box_set_active(
492 GTK_COMBO_BOX(default_implementations_optmenu), i);
493 found = i;
497 page->page.widget = vbox;
499 page->no_mail_off_btn = no_mail_off_btn;
500 page->no_mail_blink_btn = no_mail_blink_btn;
501 page->no_mail_on_btn = no_mail_on_btn;
502 page->unread_mail_off_btn = unread_mail_off_btn;
503 page->unread_mail_blink_btn = unread_mail_blink_btn;
504 page->unread_mail_on_btn = unread_mail_on_btn;
505 page->new_mail_off_btn = new_mail_off_btn;
506 page->new_mail_blink_btn = new_mail_blink_btn;
507 page->new_mail_on_btn = new_mail_on_btn;
508 page->default_implementations_optmenu = default_implementations_optmenu;
509 page->on_value_entry = on_value_entry;
510 page->off_value_entry = off_value_entry;
511 page->file_entry = file_entry;
512 page->hbox_acpi_file = hbox_acpi_file;
513 page->hbox_acpi_values = hbox_acpi_values;
514 page->warning_box = warning_box;
515 page->warning_label = warning_label;
516 page->blink_on_err_chkbtn = blink_on_err_chkbtn;
518 if (found != 0) {
519 gtk_widget_hide(hbox_acpi_file);
520 gtk_widget_hide(hbox_acpi_values);
521 gtk_entry_set_text(GTK_ENTRY(file_entry),
522 known_implementations[found].file_path);
523 gtk_entry_set_text(GTK_ENTRY(on_value_entry),
524 known_implementations[found].on_param);
525 gtk_entry_set_text(GTK_ENTRY(off_value_entry),
526 known_implementations[found].off_param);
528 if (!check_impl(known_implementations[found].file_path))
529 show_error(page, known_implementations[found].file_path);
530 } else {
531 gtk_combo_box_set_active(
532 GTK_COMBO_BOX(default_implementations_optmenu), 0);
533 gtk_widget_show_all(hbox_acpi_file);
534 gtk_widget_show_all(hbox_acpi_values);
535 if (acpiprefs.file_path != NULL)
536 gtk_entry_set_text(GTK_ENTRY(file_entry),
537 acpiprefs.file_path);
538 if (acpiprefs.on_param != NULL)
539 gtk_entry_set_text(GTK_ENTRY(on_value_entry),
540 acpiprefs.on_param);
541 if (acpiprefs.off_param != NULL)
542 gtk_entry_set_text(GTK_ENTRY(off_value_entry),
543 acpiprefs.off_param);
544 if (!acpiprefs.file_path || !check_impl(acpiprefs.file_path))
545 show_error(page, acpiprefs.file_path);
549 static void acpi_prefs_destroy_widget_func(PrefsPage *_page)
553 static void acpi_prefs_save_func(PrefsPage * _page)
555 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *) _page;
556 PrefFile *pfile;
557 gchar *rcpath;
558 gint selected = 0;
560 g_free(acpiprefs.file_path);
561 acpiprefs.file_path = gtk_editable_get_chars(
562 GTK_EDITABLE(page->file_entry), 0, -1);
563 g_free(acpiprefs.on_param);
564 acpiprefs.on_param = gtk_editable_get_chars(
565 GTK_EDITABLE(page->on_value_entry), 0, -1);
566 g_free(acpiprefs.off_param);
567 acpiprefs.off_param = gtk_editable_get_chars(
568 GTK_EDITABLE(page->off_value_entry), 0, -1);
570 if (gtk_toggle_button_get_active(
571 GTK_TOGGLE_BUTTON(page->no_mail_off_btn)))
572 acpiprefs.no_mail_action = OFF;
573 else if (gtk_toggle_button_get_active(
574 GTK_TOGGLE_BUTTON(page->no_mail_blink_btn)))
575 acpiprefs.no_mail_action = BLINK;
576 else if (gtk_toggle_button_get_active(
577 GTK_TOGGLE_BUTTON(page->no_mail_on_btn)))
578 acpiprefs.no_mail_action = ON;
580 if (gtk_toggle_button_get_active(
581 GTK_TOGGLE_BUTTON(page->unread_mail_off_btn)))
582 acpiprefs.unread_mail_action = OFF;
583 else if (gtk_toggle_button_get_active(
584 GTK_TOGGLE_BUTTON(page->unread_mail_blink_btn)))
585 acpiprefs.unread_mail_action = BLINK;
586 else if (gtk_toggle_button_get_active(
587 GTK_TOGGLE_BUTTON(page->unread_mail_on_btn)))
588 acpiprefs.unread_mail_action = ON;
590 if (gtk_toggle_button_get_active(
591 GTK_TOGGLE_BUTTON(page->new_mail_off_btn)))
592 acpiprefs.new_mail_action = OFF;
593 else if (gtk_toggle_button_get_active(
594 GTK_TOGGLE_BUTTON(page->new_mail_blink_btn)))
595 acpiprefs.new_mail_action = BLINK;
596 else if (gtk_toggle_button_get_active(
597 GTK_TOGGLE_BUTTON(page->new_mail_on_btn)))
598 acpiprefs.new_mail_action = ON;
600 acpiprefs.blink_on_err = gtk_toggle_button_get_active(
601 GTK_TOGGLE_BUTTON(page->blink_on_err_chkbtn));
603 selected = gtk_combo_box_get_active(GTK_COMBO_BOX(page->default_implementations_optmenu));
605 if (selected != 0) {
606 g_free(acpiprefs.file_path);
607 acpiprefs.file_path = g_strdup(
608 known_implementations[selected].file_path);
609 g_free(acpiprefs.on_param);
610 acpiprefs.on_param = g_strdup(
611 known_implementations[selected].on_param);
612 g_free(acpiprefs.off_param);
613 acpiprefs.off_param = g_strdup(
614 known_implementations[selected].off_param);
617 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
618 pfile = prefs_write_open(rcpath);
619 g_free(rcpath);
620 if (!pfile || (prefs_set_block_label(pfile, PREFS_BLOCK_NAME) < 0))
621 return;
623 if (prefs_write_param(param, pfile->fp) < 0) {
624 g_warning("failed to write " PREFS_BLOCK_NAME
625 " configuration to file");
626 prefs_file_close_revert(pfile);
627 return;
629 if (fprintf(pfile->fp, "\n") < 0) {
630 FILE_OP_ERROR(rcpath, "fprintf");
631 prefs_file_close_revert(pfile);
632 } else
633 prefs_file_close(pfile);
636 static void acpi_set(gboolean on)
638 FILE *fp = NULL;
640 if (!acpiprefs.file_path) {
641 debug_print("acpiprefs.file_path NULL\n");
642 return;
644 if (!check_impl(acpiprefs.file_path)) {
645 debug_print("acpiprefs.file_path not implemented\n");
646 return;
648 if (!acpiprefs.on_param || !acpiprefs.off_param) {
649 debug_print("no param\n");
650 return;
653 if (!is_program(acpiprefs.file_path)) {
654 fp = claws_fopen(acpiprefs.file_path, "wb");
655 if (fp == NULL)
656 return;
658 if (on) {
659 claws_fwrite(acpiprefs.on_param, 1, strlen(acpiprefs.on_param), fp);
660 } else {
661 claws_fwrite(acpiprefs.off_param, 1, strlen(acpiprefs.off_param), fp);
663 claws_safe_fclose(fp);
664 } else {
665 gchar *cmd = g_strdup_printf("%s %s",
666 acpiprefs.file_path,
667 on ? acpiprefs.on_param:acpiprefs.off_param);
668 execute_command_line(cmd, TRUE, NULL);
669 g_free(cmd);
673 static guint should_quit = FALSE;
674 static int last_blink = 0;
676 static gint acpi_blink(gpointer data)
678 if (!should_quit) {
679 acpi_set(last_blink);
680 last_blink = !last_blink;
681 return TRUE;
682 } else {
683 acpi_set(FALSE);
684 return FALSE;
688 static int blink_timeout_id = 0;
689 static int alertpanel_blink_timeout_id = 0;
690 static gint my_new = -1, my_unread = -1;
691 static int my_action = -1;
693 static gboolean acpi_update_hook(gpointer source, gpointer data)
695 int action = 0;
696 guint new, unread, unreadmarked, marked, total;
697 guint replied, forwarded, locked, ignored, watched;
699 if (alertpanel_blink_timeout_id)
700 return FALSE;
702 folder_count_total_msgs(&new, &unread, &unreadmarked, &marked, &total,
703 &replied, &forwarded, &locked, &ignored, &watched);
705 if (my_new != new || my_unread != unread) {
706 my_new = new;
707 my_unread = unread;
708 if (my_new > 0) {
709 action = acpiprefs.new_mail_action;
710 } else if (my_unread > 0) {
711 action = acpiprefs.unread_mail_action;
712 } else {
713 action = acpiprefs.no_mail_action;
716 if (action != my_action) {
717 my_action = action;
719 if (action != BLINK && blink_timeout_id != 0) {
720 g_source_remove(blink_timeout_id);
721 blink_timeout_id = 0;
724 switch (action) {
725 case ON:
726 acpi_set(TRUE);
727 break;
728 case BLINK:
729 acpi_set(TRUE);
730 last_blink = FALSE;
731 blink_timeout_id = g_timeout_add(1000, acpi_blink, NULL);
732 break;
733 case OFF:
734 acpi_set(FALSE);
735 break;
740 return FALSE;
743 static gboolean acpi_alertpanel_hook(gpointer source, gpointer data)
745 gboolean *opened = (gboolean *)source;
747 if (*opened == TRUE) {
748 if (blink_timeout_id)
749 g_source_remove(blink_timeout_id);
750 blink_timeout_id = 0;
752 if (alertpanel_blink_timeout_id)
753 return FALSE;
755 acpi_set(TRUE);
756 last_blink = FALSE;
757 alertpanel_blink_timeout_id = g_timeout_add(250, acpi_blink, NULL);
758 } else {
759 if (alertpanel_blink_timeout_id)
760 g_source_remove(alertpanel_blink_timeout_id);
761 alertpanel_blink_timeout_id = 0;
762 my_new = -1;
763 my_unread = -1;
764 my_action = -1;
765 acpi_update_hook(NULL, NULL);
767 return FALSE;
770 void acpi_prefs_init(void)
772 static gchar *path[3];
773 gchar *rcpath;
775 path[0] = _("Plugins");
776 path[1] = PLUGIN_NAME;
777 path[2] = NULL;
779 prefs_set_default(param);
780 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
781 prefs_read_config(param, PREFS_BLOCK_NAME, rcpath, NULL);
782 g_free(rcpath);
784 acpi_prefs_page.page.path = path;
785 acpi_prefs_page.page.create_widget = acpi_prefs_create_widget_func;
786 acpi_prefs_page.page.destroy_widget = acpi_prefs_destroy_widget_func;
787 acpi_prefs_page.page.save_page = acpi_prefs_save_func;
788 acpi_prefs_page.page.weight = 40.0;
790 prefs_gtk_register_page((PrefsPage *) &acpi_prefs_page);
791 folder_hook_id = hooks_register_hook (FOLDER_ITEM_UPDATE_HOOKLIST,
792 acpi_update_hook, NULL);
793 alertpanel_hook_id = hooks_register_hook (ALERTPANEL_OPENED_HOOKLIST,
794 acpi_alertpanel_hook, NULL);
795 should_quit = FALSE;
798 void acpi_prefs_done(void)
800 should_quit = TRUE;
801 acpi_set(FALSE);
802 if (claws_is_exiting())
803 return;
804 prefs_gtk_unregister_page((PrefsPage *) &acpi_prefs_page);
805 hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, folder_hook_id);
806 hooks_unregister_hook(ALERTPANEL_OPENED_HOOKLIST, alertpanel_hook_id);
810 void acpi_init(void)
812 gint i;
813 for (i = 0; acpi_help[i] != NULL; i++)
814 known_implementations[i].help =
815 *acpi_help[i] ? _(acpi_help[i]) : "";
816 acpi_prefs_init();
819 void acpi_done(void)
821 acpi_prefs_done();
824 gint plugin_init(gchar **error)
826 if( !check_plugin_version(MAKE_NUMERIC_VERSION(3,8,1,46),
827 VERSION_NUMERIC, PLUGIN_NAME, error) )
828 return -1;
830 acpi_init();
831 return 0;
834 gboolean plugin_done(void)
836 if (blink_timeout_id)
837 g_source_remove(blink_timeout_id);
838 if (alertpanel_blink_timeout_id)
839 g_source_remove(alertpanel_blink_timeout_id);
841 acpi_done();
842 return TRUE;
845 const gchar *plugin_name(void)
847 return PLUGIN_NAME;
850 const gchar *plugin_desc(void)
852 return _("This plugin handles various ACPI mail LEDs.");
855 const gchar *plugin_type(void)
857 return "GTK3";
860 const gchar *plugin_licence(void)
862 return "GPL3+";
865 const gchar *plugin_version(void)
867 return VERSION;
870 struct PluginFeature *plugin_provides(void)
872 static struct PluginFeature features[] =
873 { {PLUGIN_NOTIFIER, N_("Laptop LED")},
874 {PLUGIN_NOTHING, NULL}};
875 return features;