1 /*
2 * acpi_notifier -- for Claws Mail
3 *
4 * Copyright (C) 2005 Colin Leroy <colin@colino.net>
5 *
6 * Sylpheed is a GTK+ based, lightweight, and fast e-mail client
7 * Copyright (C) 1999-2005 Hiroyuki Yamamoto and the Claws Mail Team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #include "claws-features.h"
27 #endif
28
29 #include <glib.h>
30 #include <glib/gi18n.h>
31
32 #include <string.h>
33
34 #include <glib.h>
35 #include <gtk/gtk.h>
36
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 "gtkcmoptionmenu.h"
50 #include "file-utils.h"
51
52 #define PREFS_BLOCK_NAME "AcpiNotifier"
53 #define PLUGIN_NAME _("Acpi Notifier")
54
55 typedef struct _PredefinedAcpis {
56 gchar *name;
57 gchar *on_param;
58 gchar *off_param;
59 gchar *file_path;
60 gboolean is_program;
61 gchar *help;
62 } PredefinedAcpis;
63
64 /**
65 * Add your implementation here (and send me the patch!)
66 */
67 char *acpi_help[] = {
68 "",
69 N_("Make sure that the kernel module 'acerhk' is loaded.\n"
70 "You can get it from http://www.cakey.de/acerhk/"),
71 N_("Make sure that the kernel module 'acer_acpi' is loaded.\n"
72 "You can get it from http://code.google.com/p/aceracpi/"),
73 N_("Make sure that the kernel module 'asus_laptop' is loaded."),
74 N_("Make sure that the kernel module 'asus_acpi' is loaded."),
75 N_("Make sure that the kernel module 'ibm_acpi' is loaded."),
76 N_("Make sure that you have apanelc installed.\n"
77 "You can get it from http://apanel.sourceforge.net/"),
78 NULL
79 };
80 PredefinedAcpis known_implementations[] = {
81 {"Other file", "", "", "", FALSE, NULL},
82
83 {"ACER (acerhk)", "1", "0", "/proc/driver/acerhk/led", FALSE, NULL},
84
85 {"ACER (acer_acpi)", "1", "0", "/proc/acpi/acer/mailled", FALSE, NULL},
86
87 {"ASUS (asus_laptop)", "1", "0", "/sys/class/leds/asus:mail/brightness", FALSE, NULL},
88
89 {"ASUS (asus_acpi)", "1", "0", "/proc/acpi/asus/mled", FALSE, NULL},
90
91 {"IBM (ibm_acpi)", "7 on", "7 off", "/proc/acpi/ibm/led", FALSE, NULL},
92
93 {"Lenovo (tp_smapi)", "on", "off", "/proc/acpi/ibm/light", FALSE, NULL},
94
95 {"Fujitsu (apanel)", "led on", "led off", "apanelc", TRUE, NULL},
96
97 {NULL, NULL, NULL, NULL, FALSE, NULL}
98 };
99
100 static gulong folder_hook_id = HOOK_NONE;
101 static gulong alertpanel_hook_id = HOOK_NONE;
102
103 struct AcpiNotifierPage
104 {
105 PrefsPage page;
106
107 GtkWidget *no_mail_off_btn;
108 GtkWidget *no_mail_blink_btn;
109 GtkWidget *no_mail_on_btn;
110 GtkWidget *unread_mail_off_btn;
111 GtkWidget *unread_mail_blink_btn;
112 GtkWidget *unread_mail_on_btn;
113 GtkWidget *new_mail_off_btn;
114 GtkWidget *new_mail_blink_btn;
115 GtkWidget *new_mail_on_btn;
116 GtkWidget *default_implementations_optmenu;
117 GtkWidget *on_value_entry;
118 GtkWidget *off_value_entry;
119 GtkWidget *file_entry;
120 GtkWidget *hbox_acpi_file;
121 GtkWidget *hbox_acpi_values;
122 GtkWidget *warning_label;
123 GtkWidget *warning_box;
124 GtkWidget *blink_on_err_chkbtn;
125 };
126
127 typedef struct _AcpiNotifierPrefs AcpiNotifierPrefs;
128
129 struct _AcpiNotifierPrefs
130 {
131 gint no_mail_action;
132 gint unread_mail_action;
133 gint new_mail_action;
134 gboolean blink_on_err;
135 gchar *on_param;
136 gchar *off_param;
137 gchar *file_path;
138 };
139
140 AcpiNotifierPrefs acpiprefs;
141
142 static struct AcpiNotifierPage acpi_prefs_page;
143
144 enum {
145 OFF = 0,
146 BLINK,
147 ON
148 } BlinkType;
149
150 static PrefParam param[] = {
151 {"no_mail_action", "0", &acpiprefs.no_mail_action, P_INT,
152 NULL, NULL, NULL},
153 {"unread_mail_action", "0", &acpiprefs.unread_mail_action, P_INT,
154 NULL, NULL, NULL},
155 {"new_mail_action", "1", &acpiprefs.new_mail_action, P_INT,
156 NULL, NULL, NULL},
157 {"blink_on_err", "TRUE", &acpiprefs.blink_on_err, P_BOOL,
158 NULL, NULL, NULL},
159 {"on_param", NULL, &acpiprefs.on_param, P_STRING,
160 NULL, NULL, NULL},
161 {"off_param", NULL, &acpiprefs.off_param, P_STRING,
162 NULL, NULL, NULL},
163 {"file_path", NULL, &acpiprefs.file_path, P_STRING,
164 NULL, NULL, NULL},
165 {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
166 };
167
check_impl(const gchar * filepath)168 static gboolean check_impl (const gchar *filepath)
169 {
170 int i;
171 for (i = 0; known_implementations[i].name != NULL; i++) {
172 if (strcmp(known_implementations[i].file_path, filepath))
173 continue;
174 if (!known_implementations[i].is_program)
175 return is_file_exist(filepath);
176 else {
177 gchar *cmd = g_strdup_printf("which %s", filepath);
178 int found = system(cmd);
179 g_free(cmd);
180 return (found == 0);
181 }
182 }
183 return is_file_exist(filepath);
184 }
185
is_program(const gchar * filepath)186 static gboolean is_program (const gchar *filepath)
187 {
188 int i;
189 for (i = 0; known_implementations[i].name != NULL; i++) {
190 if (strcmp(known_implementations[i].file_path, filepath))
191 continue;
192 return known_implementations[i].is_program;
193 }
194 return FALSE;
195 }
196
show_error(struct AcpiNotifierPage * page,const gchar * filepath)197 static void show_error (struct AcpiNotifierPage *page, const gchar *filepath)
198 {
199 int i;
200 if (!filepath) {
201 gtk_widget_hide(page->warning_box);
202 return;
203 }
204 for (i = 0; known_implementations[i].name != NULL; i++) {
205 if (strcmp(known_implementations[i].file_path, filepath))
206 continue;
207 if (known_implementations[i].help) {
208 gchar *tmp = g_strdup_printf("%s\n%s",
209 _("Control file doesn't exist."),
210 known_implementations[i].help);
211 gtk_label_set_text(GTK_LABEL(page->warning_label), tmp);
212 g_free(tmp);
213 } else {
214 gtk_label_set_text(GTK_LABEL(page->warning_label),
215 _("Control file doesn't exist."));
216 }
217 gtk_widget_show_all(page->warning_box);
218 return;
219 }
220 }
221
type_activated(GtkMenuItem * menuitem,gpointer data)222 static void type_activated(GtkMenuItem *menuitem, gpointer data)
223 {
224 GtkWidget *menu, *item;
225 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *)data;
226 gint selected;
227
228 if (page->file_entry == NULL)
229 return;
230
231 menu = gtk_cmoption_menu_get_menu(
232 GTK_CMOPTION_MENU(page->default_implementations_optmenu));
233 item = gtk_menu_get_active(GTK_MENU(menu));
234 selected = GPOINTER_TO_INT
235 (g_object_get_data(G_OBJECT(item), MENU_VAL_ID));
236
237 if (selected != 0) {
238 gtk_widget_hide(page->hbox_acpi_file);
239 gtk_widget_hide(page->hbox_acpi_values);
240 gtk_entry_set_text(GTK_ENTRY(page->file_entry),
241 known_implementations[selected].file_path);
242 gtk_entry_set_text(GTK_ENTRY(page->on_value_entry),
243 known_implementations[selected].on_param);
244 gtk_entry_set_text(GTK_ENTRY(page->off_value_entry),
245 known_implementations[selected].off_param);
246 if (!check_impl(known_implementations[selected].file_path))
247 show_error(page, known_implementations[selected].file_path);
248 else
249 show_error(page, NULL);
250 } else {
251 gtk_widget_show_all(page->hbox_acpi_file);
252 gtk_widget_show_all(page->hbox_acpi_values);
253 }
254 }
file_entry_changed(GtkWidget * entry,gpointer data)255 static void file_entry_changed (GtkWidget *entry, gpointer data)
256 {
257 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *)data;
258 if (!page->warning_box)
259 return;
260
261 if (!check_impl(gtk_entry_get_text(GTK_ENTRY(entry))))
262 show_error(page, gtk_entry_get_text(GTK_ENTRY(entry)));
263 else
264 show_error(page, NULL);
265 }
266
acpi_prefs_create_widget_func(PrefsPage * _page,GtkWindow * window,gpointer data)267 static void acpi_prefs_create_widget_func(PrefsPage * _page,
268 GtkWindow * window,
269 gpointer data)
270 {
271 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *) _page;
272
273 GtkWidget *vbox;
274 GtkWidget *hbox;
275 GtkWidget *hbox_acpi_file;
276 GtkWidget *hbox_acpi_values;
277 GtkWidget *start_label;
278 GtkWidget *no_mail_label;
279 GtkWidget *no_mail_off_btn;
280 GtkWidget *no_mail_blink_btn;
281 GtkWidget *no_mail_on_btn;
282 GtkWidget *unread_mail_label;
283 GtkWidget *unread_mail_off_btn;
284 GtkWidget *unread_mail_blink_btn;
285 GtkWidget *unread_mail_on_btn;
286 GtkWidget *new_mail_label;
287 GtkWidget *new_mail_off_btn;
288 GtkWidget *new_mail_blink_btn;
289 GtkWidget *new_mail_on_btn;
290 GtkWidget *default_implementations_optmenu;
291 GtkWidget *default_implementations_menu;
292 GtkWidget *on_value_entry;
293 GtkWidget *off_value_entry;
294 GtkWidget *file_entry;
295 GtkWidget *menuitem;
296 GtkWidget *warning_label;
297 GtkWidget *warning_box;
298 GtkWidget *image;
299 GtkWidget *blink_on_err_chkbtn;
300
301 int i;
302 int found = 0;
303
304 vbox = gtk_vbox_new(FALSE, 6);
305 gtk_container_set_border_width (GTK_CONTAINER (vbox), VBOX_BORDER);
306
307 no_mail_label = gtk_label_new(_(" : no new or unread mail"));
308 unread_mail_label = gtk_label_new(_(" : unread mail"));
309 new_mail_label = gtk_label_new(_(" : new mail"));
310
311 no_mail_off_btn = gtk_radio_button_new_with_label(NULL, _("off"));
312 no_mail_blink_btn = gtk_radio_button_new_with_label_from_widget(
313 GTK_RADIO_BUTTON(no_mail_off_btn), _("blinking"));
314 no_mail_on_btn = gtk_radio_button_new_with_label_from_widget(
315 GTK_RADIO_BUTTON(no_mail_off_btn), _("on"));
316
317 unread_mail_off_btn = gtk_radio_button_new_with_label(NULL, _("off"));
318 unread_mail_blink_btn = gtk_radio_button_new_with_label_from_widget(
319 GTK_RADIO_BUTTON(unread_mail_off_btn), _("blinking"));
320 unread_mail_on_btn = gtk_radio_button_new_with_label_from_widget(
321 GTK_RADIO_BUTTON(unread_mail_off_btn), _("on"));
322
323 new_mail_off_btn = gtk_radio_button_new_with_label(NULL, _("off"));
324 new_mail_blink_btn = gtk_radio_button_new_with_label_from_widget(
325 GTK_RADIO_BUTTON(new_mail_off_btn), _("blinking"));
326 new_mail_on_btn = gtk_radio_button_new_with_label_from_widget(
327 GTK_RADIO_BUTTON(new_mail_off_btn), _("on"));
328
329 on_value_entry = gtk_entry_new();
330 off_value_entry = gtk_entry_new();
331 file_entry = gtk_entry_new();
332 gtk_widget_set_size_request(on_value_entry, 40, -1);
333 gtk_widget_set_size_request(off_value_entry, 40, -1);
334
335 default_implementations_optmenu = gtk_cmoption_menu_new ();
336 default_implementations_menu = gtk_menu_new();
337 gtk_cmoption_menu_set_menu (
338 GTK_CMOPTION_MENU(default_implementations_optmenu),
339 default_implementations_menu);
340 for (i = 0; known_implementations[i].name != NULL; i++) {
341 MENUITEM_ADD (default_implementations_menu,
342 menuitem, known_implementations[i].name, i);
343 g_signal_connect(G_OBJECT(menuitem), "activate",
344 G_CALLBACK(type_activated),
345 page);
346 }
347
348 hbox = gtk_hbox_new(FALSE, 6);
349 start_label = gtk_label_new(_("LED "));
350 gtk_box_pack_start(GTK_BOX(hbox), start_label, FALSE, FALSE, 0);
351 gtk_box_pack_start(GTK_BOX(hbox), no_mail_off_btn, FALSE, FALSE, 0);
352 gtk_box_pack_start(GTK_BOX(hbox), no_mail_blink_btn, FALSE, FALSE, 0);
353 gtk_box_pack_start(GTK_BOX(hbox), no_mail_on_btn, FALSE, FALSE, 0);
354 gtk_box_pack_start(GTK_BOX(hbox), no_mail_label, FALSE, FALSE, 0);
355 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
356
357 hbox = gtk_hbox_new(FALSE, 6);
358 start_label = gtk_label_new(_("LED "));
359 gtk_box_pack_start(GTK_BOX(hbox),
360 start_label, FALSE, FALSE, 0);
361 gtk_box_pack_start(GTK_BOX(hbox),
362 unread_mail_off_btn, FALSE, FALSE, 0);
363 gtk_box_pack_start(GTK_BOX(hbox),
364 unread_mail_blink_btn, FALSE, FALSE, 0);
365 gtk_box_pack_start(GTK_BOX(hbox),
366 unread_mail_on_btn, FALSE, FALSE, 0);
367 gtk_box_pack_start(GTK_BOX(hbox),
368 unread_mail_label, FALSE, FALSE, 0);
369 gtk_box_pack_start(GTK_BOX(vbox),
370 hbox, FALSE, FALSE, 0);
371
372 hbox = gtk_hbox_new(FALSE, 6);
373 start_label = gtk_label_new(_("LED "));
374 gtk_box_pack_start(GTK_BOX(hbox),
375 start_label, FALSE, FALSE, 0);
376 gtk_box_pack_start(GTK_BOX(hbox),
377 new_mail_off_btn, FALSE, FALSE, 0);
378 gtk_box_pack_start(GTK_BOX(hbox),
379 new_mail_blink_btn, FALSE, FALSE, 0);
380 gtk_box_pack_start(GTK_BOX(hbox),
381 new_mail_on_btn, FALSE, FALSE, 0);
382 gtk_box_pack_start(GTK_BOX(hbox),
383 new_mail_label, FALSE, FALSE, 0);
384 gtk_box_pack_start(GTK_BOX(vbox),
385 hbox, FALSE, FALSE, 0);
386
387 hbox = gtk_hbox_new(FALSE, 6);
388 start_label = gtk_label_new(_("ACPI type: "));
389 gtk_box_pack_start(GTK_BOX(hbox),
390 start_label, FALSE, FALSE, 0);
391 gtk_box_pack_start(GTK_BOX(hbox),
392 default_implementations_optmenu, FALSE, FALSE, 0);
393 gtk_box_pack_start(GTK_BOX(vbox),
394 hbox, FALSE, FALSE, 0);
395
396 hbox_acpi_file = gtk_hbox_new(FALSE, 6);
397 start_label = gtk_label_new(_("ACPI file: "));
398 gtk_box_pack_start(GTK_BOX(hbox_acpi_file),
399 start_label, FALSE, FALSE, 0);
400 gtk_box_pack_start(GTK_BOX(hbox_acpi_file),
401 file_entry, FALSE, FALSE, 0);
402 gtk_box_pack_start(GTK_BOX(vbox),
403 hbox_acpi_file, FALSE, FALSE, 0);
404 g_signal_connect(G_OBJECT(file_entry), "changed",
405 G_CALLBACK(file_entry_changed), page);
406
407 hbox_acpi_values = gtk_hbox_new(FALSE, 6);
408 start_label = gtk_label_new(_("values - On: "));
409 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
410 start_label, FALSE, FALSE, 0);
411 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
412 on_value_entry, FALSE, FALSE, 0);
413 start_label = gtk_label_new(_(" - Off: "));
414 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
415 start_label, FALSE, FALSE, 0);
416 gtk_box_pack_start(GTK_BOX(hbox_acpi_values),
417 off_value_entry, FALSE, FALSE, 0);
418 gtk_box_pack_start(GTK_BOX(vbox),
419 hbox_acpi_values, FALSE, FALSE, 0);
420
421 warning_box = gtk_hbox_new(FALSE, 6);
422
423 image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING,
424 GTK_ICON_SIZE_SMALL_TOOLBAR);
425 gtk_box_pack_start(GTK_BOX(warning_box), image, FALSE, FALSE, 0);
426 warning_label = gtk_label_new(
427 _("Control file doesn't exist."));
428 gtk_box_pack_start(GTK_BOX(warning_box), warning_label, FALSE, FALSE, 0);
429 gtk_box_pack_start(GTK_BOX(vbox), warning_box, FALSE, FALSE, 0);
430
431 gtk_widget_show_all(vbox);
432 gtk_widget_hide(warning_box);
433
434 blink_on_err_chkbtn = gtk_check_button_new_with_label(
435 _("Blink when user interaction is required"));
436 gtk_box_pack_start(GTK_BOX(vbox), blink_on_err_chkbtn, FALSE, FALSE, 0);
437 gtk_toggle_button_set_active(
438 GTK_TOGGLE_BUTTON(blink_on_err_chkbtn),
439 acpiprefs.blink_on_err);
440 gtk_widget_show(blink_on_err_chkbtn);
441
442 switch (acpiprefs.no_mail_action) {
443 case OFF:
444 gtk_toggle_button_set_active(
445 GTK_TOGGLE_BUTTON(no_mail_off_btn), TRUE);
446 break;
447 case BLINK:
448 gtk_toggle_button_set_active(
449 GTK_TOGGLE_BUTTON(no_mail_blink_btn), TRUE);
450 break;
451 case ON:
452 gtk_toggle_button_set_active(
453 GTK_TOGGLE_BUTTON(no_mail_on_btn), TRUE);
454 break;
455 }
456
457 switch (acpiprefs.unread_mail_action) {
458 case OFF:
459 gtk_toggle_button_set_active(
460 GTK_TOGGLE_BUTTON(unread_mail_off_btn), TRUE);
461 break;
462 case BLINK:
463 gtk_toggle_button_set_active(
464 GTK_TOGGLE_BUTTON(unread_mail_blink_btn), TRUE);
465 break;
466 case ON:
467 gtk_toggle_button_set_active(
468 GTK_TOGGLE_BUTTON(unread_mail_on_btn), TRUE);
469 break;
470 }
471
472 switch (acpiprefs.new_mail_action) {
473 case OFF:
474 gtk_toggle_button_set_active(
475 GTK_TOGGLE_BUTTON(new_mail_off_btn), TRUE);
476 break;
477 case BLINK:
478 gtk_toggle_button_set_active(
479 GTK_TOGGLE_BUTTON(new_mail_blink_btn), TRUE);
480 break;
481 case ON:
482 gtk_toggle_button_set_active(
483 GTK_TOGGLE_BUTTON(new_mail_on_btn), TRUE);
484 break;
485 }
486
487 if (acpiprefs.file_path != NULL) {
488 for (i = 0; known_implementations[i].name != NULL; i++) {
489 if (!strcmp(acpiprefs.file_path,
490 known_implementations[i].file_path)) {
491 gtk_cmoption_menu_set_history(
492 GTK_CMOPTION_MENU(
493 default_implementations_optmenu), i);
494 found = i;
495 }
496 }
497 }
498 if (found == 0) {
499 for (i = 0; known_implementations[i].name != NULL; i++) {
500 if (check_impl(known_implementations[i].file_path)) {
501 gtk_cmoption_menu_set_history(
502 GTK_CMOPTION_MENU(
503 default_implementations_optmenu), i);
504 found = i;
505 }
506 }
507 }
508 page->page.widget = vbox;
509
510 page->no_mail_off_btn = no_mail_off_btn;
511 page->no_mail_blink_btn = no_mail_blink_btn;
512 page->no_mail_on_btn = no_mail_on_btn;
513 page->unread_mail_off_btn = unread_mail_off_btn;
514 page->unread_mail_blink_btn = unread_mail_blink_btn;
515 page->unread_mail_on_btn = unread_mail_on_btn;
516 page->new_mail_off_btn = new_mail_off_btn;
517 page->new_mail_blink_btn = new_mail_blink_btn;
518 page->new_mail_on_btn = new_mail_on_btn;
519 page->default_implementations_optmenu = default_implementations_optmenu;
520 page->on_value_entry = on_value_entry;
521 page->off_value_entry = off_value_entry;
522 page->file_entry = file_entry;
523 page->hbox_acpi_file = hbox_acpi_file;
524 page->hbox_acpi_values = hbox_acpi_values;
525 page->warning_box = warning_box;
526 page->warning_label = warning_label;
527 page->blink_on_err_chkbtn = blink_on_err_chkbtn;
528
529 if (found != 0) {
530 gtk_widget_hide(hbox_acpi_file);
531 gtk_widget_hide(hbox_acpi_values);
532 gtk_entry_set_text(GTK_ENTRY(file_entry),
533 known_implementations[found].file_path);
534 gtk_entry_set_text(GTK_ENTRY(on_value_entry),
535 known_implementations[found].on_param);
536 gtk_entry_set_text(GTK_ENTRY(off_value_entry),
537 known_implementations[found].off_param);
538
539 if (!check_impl(known_implementations[found].file_path))
540 show_error(page, known_implementations[found].file_path);
541 } else {
542 gtk_cmoption_menu_set_history(
543 GTK_CMOPTION_MENU(default_implementations_optmenu), 0);
544 gtk_widget_show_all(hbox_acpi_file);
545 gtk_widget_show_all(hbox_acpi_values);
546 if (acpiprefs.file_path != NULL)
547 gtk_entry_set_text(GTK_ENTRY(file_entry),
548 acpiprefs.file_path);
549 if (acpiprefs.on_param != NULL)
550 gtk_entry_set_text(GTK_ENTRY(on_value_entry),
551 acpiprefs.on_param);
552 if (acpiprefs.off_param != NULL)
553 gtk_entry_set_text(GTK_ENTRY(off_value_entry),
554 acpiprefs.off_param);
555 if (!acpiprefs.file_path || !check_impl(acpiprefs.file_path))
556 show_error(page, acpiprefs.file_path);
557 }
558 }
559
acpi_prefs_destroy_widget_func(PrefsPage * _page)560 static void acpi_prefs_destroy_widget_func(PrefsPage *_page)
561 {
562 }
563
acpi_prefs_save_func(PrefsPage * _page)564 static void acpi_prefs_save_func(PrefsPage * _page)
565 {
566 struct AcpiNotifierPage *page = (struct AcpiNotifierPage *) _page;
567 PrefFile *pfile;
568 gchar *rcpath;
569 GtkWidget *menu;
570 GtkWidget *menuitem;
571 gint selected = 0;
572
573 g_free(acpiprefs.file_path);
574 acpiprefs.file_path = gtk_editable_get_chars(
575 GTK_EDITABLE(page->file_entry), 0, -1);
576 g_free(acpiprefs.on_param);
577 acpiprefs.on_param = gtk_editable_get_chars(
578 GTK_EDITABLE(page->on_value_entry), 0, -1);
579 g_free(acpiprefs.off_param);
580 acpiprefs.off_param = gtk_editable_get_chars(
581 GTK_EDITABLE(page->off_value_entry), 0, -1);
582
583 if (gtk_toggle_button_get_active(
584 GTK_TOGGLE_BUTTON(page->no_mail_off_btn)))
585 acpiprefs.no_mail_action = OFF;
586 else if (gtk_toggle_button_get_active(
587 GTK_TOGGLE_BUTTON(page->no_mail_blink_btn)))
588 acpiprefs.no_mail_action = BLINK;
589 else if (gtk_toggle_button_get_active(
590 GTK_TOGGLE_BUTTON(page->no_mail_on_btn)))
591 acpiprefs.no_mail_action = ON;
592
593 if (gtk_toggle_button_get_active(
594 GTK_TOGGLE_BUTTON(page->unread_mail_off_btn)))
595 acpiprefs.unread_mail_action = OFF;
596 else if (gtk_toggle_button_get_active(
597 GTK_TOGGLE_BUTTON(page->unread_mail_blink_btn)))
598 acpiprefs.unread_mail_action = BLINK;
599 else if (gtk_toggle_button_get_active(
600 GTK_TOGGLE_BUTTON(page->unread_mail_on_btn)))
601 acpiprefs.unread_mail_action = ON;
602
603 if (gtk_toggle_button_get_active(
604 GTK_TOGGLE_BUTTON(page->new_mail_off_btn)))
605 acpiprefs.new_mail_action = OFF;
606 else if (gtk_toggle_button_get_active(
607 GTK_TOGGLE_BUTTON(page->new_mail_blink_btn)))
608 acpiprefs.new_mail_action = BLINK;
609 else if (gtk_toggle_button_get_active(
610 GTK_TOGGLE_BUTTON(page->new_mail_on_btn)))
611 acpiprefs.new_mail_action = ON;
612
613 acpiprefs.blink_on_err = gtk_toggle_button_get_active(
614 GTK_TOGGLE_BUTTON(page->blink_on_err_chkbtn));
615
616 menu = gtk_cmoption_menu_get_menu(
617 GTK_CMOPTION_MENU(page->default_implementations_optmenu));
618 menuitem = gtk_menu_get_active(GTK_MENU(menu));
619 selected = GPOINTER_TO_INT
620 (g_object_get_data(G_OBJECT(menuitem), MENU_VAL_ID));
621
622 if (selected != 0) {
623 g_free(acpiprefs.file_path);
624 acpiprefs.file_path = g_strdup(
625 known_implementations[selected].file_path);
626 g_free(acpiprefs.on_param);
627 acpiprefs.on_param = g_strdup(
628 known_implementations[selected].on_param);
629 g_free(acpiprefs.off_param);
630 acpiprefs.off_param = g_strdup(
631 known_implementations[selected].off_param);
632 }
633
634 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
635 pfile = prefs_write_open(rcpath);
636 g_free(rcpath);
637 if (!pfile || (prefs_set_block_label(pfile, PREFS_BLOCK_NAME) < 0))
638 return;
639
640 if (prefs_write_param(param, pfile->fp) < 0) {
641 g_warning("failed to write " PREFS_BLOCK_NAME
642 " configuration to file\n");
643 prefs_file_close_revert(pfile);
644 return;
645 }
646 if (fprintf(pfile->fp, "\n") < 0) {
647 FILE_OP_ERROR(rcpath, "fprintf");
648 prefs_file_close_revert(pfile);
649 } else
650 prefs_file_close(pfile);
651 }
652
acpi_set(gboolean on)653 static void acpi_set(gboolean on)
654 {
655 FILE *fp = NULL;
656
657 if (!acpiprefs.file_path) {
658 debug_print("acpiprefs.file_path NULL\n");
659 return;
660 }
661 if (!check_impl(acpiprefs.file_path)) {
662 debug_print("acpiprefs.file_path not implemented\n");
663 return;
664 }
665 if (!acpiprefs.on_param || !acpiprefs.off_param) {
666 debug_print("no param\n");
667 return;
668 }
669
670 if (!is_program(acpiprefs.file_path)) {
671 fp = claws_fopen(acpiprefs.file_path, "wb");
672 if (fp == NULL)
673 return;
674
675 if (on) {
676 claws_fwrite(acpiprefs.on_param, 1, strlen(acpiprefs.on_param), fp);
677 } else {
678 claws_fwrite(acpiprefs.off_param, 1, strlen(acpiprefs.off_param), fp);
679 }
680 claws_safe_fclose(fp);
681 } else {
682 gchar *cmd = g_strdup_printf("%s %s",
683 acpiprefs.file_path,
684 on ? acpiprefs.on_param:acpiprefs.off_param);
685 execute_command_line(cmd, TRUE, NULL);
686 g_free(cmd);
687 }
688 }
689
690 static guint should_quit = FALSE;
691 static int last_blink = 0;
692
acpi_blink(gpointer data)693 static gint acpi_blink(gpointer data)
694 {
695 if (!should_quit) {
696 acpi_set(last_blink);
697 last_blink = !last_blink;
698 return TRUE;
699 } else {
700 acpi_set(FALSE);
701 return FALSE;
702 }
703 }
704
705 static int blink_timeout_id = 0;
706 static int alertpanel_blink_timeout_id = 0;
707 static gint my_new = -1, my_unread = -1;
708 static int my_action = -1;
709
acpi_update_hook(gpointer source,gpointer data)710 static gboolean acpi_update_hook(gpointer source, gpointer data)
711 {
712 int action = 0;
713 guint new, unread, unreadmarked, marked, total;
714 guint replied, forwarded, locked, ignored, watched;
715
716 if (alertpanel_blink_timeout_id)
717 return FALSE;
718
719 folder_count_total_msgs(&new, &unread, &unreadmarked, &marked, &total,
720 &replied, &forwarded, &locked, &ignored, &watched);
721
722 if (my_new != new || my_unread != unread) {
723 my_new = new;
724 my_unread = unread;
725 if (my_new > 0) {
726 action = acpiprefs.new_mail_action;
727 } else if (my_unread > 0) {
728 action = acpiprefs.unread_mail_action;
729 } else {
730 action = acpiprefs.no_mail_action;
731 }
732
733 if (action != my_action) {
734 my_action = action;
735
736 if (action != BLINK && blink_timeout_id != 0) {
737 g_source_remove(blink_timeout_id);
738 blink_timeout_id = 0;
739 }
740
741 switch (action) {
742 case ON:
743 acpi_set(TRUE);
744 break;
745 case BLINK:
746 acpi_set(TRUE);
747 last_blink = FALSE;
748 blink_timeout_id = g_timeout_add(1000, acpi_blink, NULL);
749 break;
750 case OFF:
751 acpi_set(FALSE);
752 break;
753 }
754 }
755 }
756
757 return FALSE;
758 }
759
acpi_alertpanel_hook(gpointer source,gpointer data)760 static gboolean acpi_alertpanel_hook(gpointer source, gpointer data)
761 {
762 gboolean *opened = (gboolean *)source;
763
764 if (*opened == TRUE) {
765 if (blink_timeout_id)
766 g_source_remove(blink_timeout_id);
767 blink_timeout_id = 0;
768
769 if (alertpanel_blink_timeout_id)
770 return FALSE;
771
772 acpi_set(TRUE);
773 last_blink = FALSE;
774 alertpanel_blink_timeout_id = g_timeout_add(250, acpi_blink, NULL);
775 } else {
776 if (alertpanel_blink_timeout_id)
777 g_source_remove(alertpanel_blink_timeout_id);
778 alertpanel_blink_timeout_id = 0;
779 my_new = -1;
780 my_unread = -1;
781 my_action = -1;
782 acpi_update_hook(NULL, NULL);
783 }
784 return FALSE;
785 }
786
acpi_prefs_init(void)787 void acpi_prefs_init(void)
788 {
789 static gchar *path[3];
790 gchar *rcpath;
791
792 path[0] = _("Plugins");
793 path[1] = PLUGIN_NAME;
794 path[2] = NULL;
795
796 prefs_set_default(param);
797 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
798 prefs_read_config(param, PREFS_BLOCK_NAME, rcpath, NULL);
799 g_free(rcpath);
800
801 acpi_prefs_page.page.path = path;
802 acpi_prefs_page.page.create_widget = acpi_prefs_create_widget_func;
803 acpi_prefs_page.page.destroy_widget = acpi_prefs_destroy_widget_func;
804 acpi_prefs_page.page.save_page = acpi_prefs_save_func;
805 acpi_prefs_page.page.weight = 40.0;
806
807 prefs_gtk_register_page((PrefsPage *) &acpi_prefs_page);
808 folder_hook_id = hooks_register_hook (FOLDER_ITEM_UPDATE_HOOKLIST,
809 acpi_update_hook, NULL);
810 alertpanel_hook_id = hooks_register_hook (ALERTPANEL_OPENED_HOOKLIST,
811 acpi_alertpanel_hook, NULL);
812 should_quit = FALSE;
813 }
814
acpi_prefs_done(void)815 void acpi_prefs_done(void)
816 {
817 should_quit = TRUE;
818 acpi_set(FALSE);
819 if (claws_is_exiting())
820 return;
821 prefs_gtk_unregister_page((PrefsPage *) &acpi_prefs_page);
822 hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, folder_hook_id);
823 hooks_unregister_hook(ALERTPANEL_OPENED_HOOKLIST, alertpanel_hook_id);
824 }
825
826
acpi_init(void)827 void acpi_init(void)
828 {
829 gint i;
830 for (i = 0; acpi_help[i] != NULL; i++)
831 known_implementations[i].help =
832 *acpi_help[i] ? _(acpi_help[i]) : "";
833 acpi_prefs_init();
834 }
835
acpi_done(void)836 void acpi_done(void)
837 {
838 acpi_prefs_done();
839 }
840
plugin_init(gchar ** error)841 gint plugin_init(gchar **error)
842 {
843 if( !check_plugin_version(MAKE_NUMERIC_VERSION(3,8,1,46),
844 VERSION_NUMERIC, PLUGIN_NAME, error) )
845 return -1;
846
847 acpi_init();
848 return 0;
849 }
850
plugin_done(void)851 gboolean plugin_done(void)
852 {
853 if (blink_timeout_id)
854 g_source_remove(blink_timeout_id);
855 if (alertpanel_blink_timeout_id)
856 g_source_remove(alertpanel_blink_timeout_id);
857
858 acpi_done();
859 return TRUE;
860 }
861
plugin_name(void)862 const gchar *plugin_name(void)
863 {
864 return PLUGIN_NAME;
865 }
866
plugin_desc(void)867 const gchar *plugin_desc(void)
868 {
869 return _("This plugin handles various ACPI mail LEDs.");
870 }
871
plugin_type(void)872 const gchar *plugin_type(void)
873 {
874 return "GTK2";
875 }
876
plugin_licence(void)877 const gchar *plugin_licence(void)
878 {
879 return "GPL3+";
880 }
881
plugin_version(void)882 const gchar *plugin_version(void)
883 {
884 return VERSION;
885 }
886
plugin_provides(void)887 struct PluginFeature *plugin_provides(void)
888 {
889 static struct PluginFeature features[] =
890 { {PLUGIN_NOTIFIER, N_("Laptop LED")},
891 {PLUGIN_NOTHING, NULL}};
892 return features;
893 }
894