1 /* Notification plugin for Claws Mail
2  * Copyright (C) 2005-2007 Holger Berndt
3  *
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; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifdef HAVE_CONFIG_H
19 #  include "config.h"
20 #  include "claws-features.h"
21 #endif
22 
23 #include <glib.h>
24 #include <glib/gi18n.h>
25 
26 #ifdef NOTIFICATION_LCDPROC
27 
28 #include "notification_lcdproc.h"
29 #include "notification_prefs.h"
30 #include "notification_core.h"
31 
32 #include "common/socket.h"
33 
34 #include <string.h>
35 #include <sys/socket.h>
36 
37 #define NOTIFICATION_LCDPROC_BUFFER_SIZE 8192
38 
39 void notification_sock_puts(SockInfo*, gchar*);
40 void notification_lcdproc_send(gchar*);
41 
42 static SockInfo *sock = NULL;
43 
notification_lcdproc_connect(void)44 void notification_lcdproc_connect(void)
45 {
46   gint len, count;
47   gchar buf[NOTIFICATION_LCDPROC_BUFFER_SIZE];
48 
49   if(!notify_config.lcdproc_enabled)
50     return;
51 
52   if(sock)
53     notification_lcdproc_disconnect();
54 
55   sock = sock_connect(notify_config.lcdproc_hostname,
56 		      notify_config.lcdproc_port);
57   /*
58    * Quietly return when a connection fails; next attempt
59    * will be made when some folder info has been changed.
60    */
61   if(sock == NULL || sock->state == CONN_FAILED) {
62     debug_print("Could not connect to LCDd\n");
63     if(sock && sock->state == CONN_FAILED) {
64       sock_close(sock, TRUE);
65       sock = NULL;
66     }
67     return;
68   }
69   else
70     debug_print("Connected to LCDd\n");
71 
72   sock_set_nonblocking_mode(sock, TRUE);
73 
74   /* Friendly people say "hello" first */
75   notification_sock_puts(sock, "hello");
76 
77   /* FIXME: Ouch. Is this really the way to go? */
78   count = 50;
79   len = 0;
80   while((len <= 0) && (count-- >= 0)) {
81     g_usleep(125000);
82     len = sock_read(sock, buf, NOTIFICATION_LCDPROC_BUFFER_SIZE);
83   }
84 
85 /*
86  * This might not be a LCDProc server.
87  * FIXME: check LCD size, LCDd version etc
88  */
89 
90   if (len <= 0) {
91     debug_print("Notification plugin: Can't communicate with "
92 		"LCDd server! Are you sure that "
93 		"there is a LCDd server running on %s:%d?\n",
94 		notify_config.lcdproc_hostname, notify_config.lcdproc_port);
95     notification_lcdproc_disconnect();
96     return;
97   }
98 
99   notification_lcdproc_send("client_set -name \"{Claws-Mail}\"");
100 
101   notification_lcdproc_send("screen_add msg_counts");
102   notification_lcdproc_send("screen_set msg_counts -name {Claws-Mail Message Count}");
103 
104   notification_lcdproc_send("widget_add msg_counts title title");
105   notification_lcdproc_send("widget_set msg_counts title {Claws-Mail}");
106   notification_lcdproc_send("widget_add msg_counts line1 string");
107   notification_lcdproc_send("widget_add msg_counts line2 string");
108   notification_lcdproc_send("widget_add msg_counts line3 string");
109 
110   notification_update_msg_counts(NULL);
111 }
112 
notification_lcdproc_disconnect(void)113 void notification_lcdproc_disconnect(void)
114 {
115   if(sock) {
116 #ifndef G_OS_WIN32
117     shutdown(sock->sock, SHUT_RDWR);
118 #endif
119     sock_close(sock, TRUE);
120     sock = NULL;
121   }
122 }
123 
notification_update_lcdproc(void)124 void notification_update_lcdproc(void)
125 {
126   NotificationMsgCount count;
127   gchar *buf;
128 
129   if(!notify_config.lcdproc_enabled || !sock)
130     return;
131 
132   if(!sock || sock->state == CONN_FAILED) {
133     notification_lcdproc_connect();
134     return;
135   }
136 
137   notification_core_get_msg_count(NULL, &count);
138 
139   if((count.new_msgs + count.unread_msgs) > 0) {
140     buf =
141       g_strdup_printf("widget_set msg_counts line1 1 2 {%s: %d}",_("New"),
142 		      count.new_msgs);
143     notification_lcdproc_send(buf);
144     buf =
145       g_strdup_printf("widget_set msg_counts line2 1 3 {%s: %d}",_("Unread"),
146 		      count.unread_msgs);
147     notification_lcdproc_send(buf);
148     buf =
149       g_strdup_printf("widget_set msg_counts line3 1 4 {%s: %d}",_("Total"),
150 		      count.total_msgs);
151     notification_lcdproc_send(buf);
152   }
153   else {
154     buf = g_strdup_printf("widget_set msg_counts line1 1 2 {%s}",
155 			  _("No new messages"));
156     notification_lcdproc_send(buf);
157     buf = g_strdup_printf("widget_set msg_counts line2 1 3 {}");
158     notification_lcdproc_send(buf);
159     buf = g_strdup_printf("widget_set msg_counts line3 1 4 {}");
160     notification_lcdproc_send(buf);
161   }
162 
163   g_free(buf);
164 }
165 
notification_sock_puts(SockInfo * socket,gchar * string)166 void notification_sock_puts(SockInfo *socket, gchar *string)
167 {
168   sock_write(socket, string, strlen(string));
169   sock_write(socket, "\n", 1);
170 }
171 
notification_lcdproc_send(gchar * string)172 void notification_lcdproc_send(gchar *string)
173 {
174   notification_sock_puts(sock, string);
175   /* TODO: Check return message from LCDd */
176 }
177 
178 #endif /* NOTIFICATION_LCDPROC */
179