src/mn-evolution-client.gob (3662B) - raw
1 /*
2 * Mail Notification
3 * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 %headertop{
21 #include <dbus/dbus-glib.h>
22 %}
23
24 %{
25 #include "mn-shell.h"
26 #include "mn-evolution.h"
27 #include "mn-util.h"
28 %}
29
30 /*
31 * A memory management bug in DBusGProxy
32 * (https://bugs.freedesktop.org/show_bug.cgi?id=14030) prevents us
33 * from unreferencing the proxy, so provide an eternal singleton
34 * proxy.
35 */
36 class MN:Evolution:Client from G:Object
37 {
38 public DBusGProxy *proxy;
39 property POINTER proxy (link, export, type = DBusGProxy *);
40
41 private gboolean name_owner_signal_connected;
42
43 init (self)
44 {
45 self_connect(self);
46 }
47
48 private void
49 connect_name_owner_signal (self)
50 {
51 if (selfp->name_owner_signal_connected)
52 return;
53
54 dbus_g_proxy_connect_signal(mn_shell->session_bus_proxy,
55 "NameOwnerChanged",
56 G_CALLBACK(self_name_owner_changed_h),
57 self,
58 NULL);
59
60 selfp->name_owner_signal_connected = TRUE;
61 }
62
63 private void
64 disconnect_name_owner_signal (self)
65 {
66 if (! selfp->name_owner_signal_connected)
67 return;
68
69 dbus_g_proxy_disconnect_signal(mn_shell->session_bus_proxy,
70 "NameOwnerChanged",
71 G_CALLBACK(self_name_owner_changed_h),
72 self);
73
74 selfp->name_owner_signal_connected = FALSE;
75 }
76
77 private void
78 connect (self)
79 {
80 DBusGProxy *proxy;
81
82 g_return_if_fail(self->proxy == NULL);
83
84 proxy = dbus_g_proxy_new_for_name_owner(mn_shell->session_bus,
85 MN_EVOLUTION_SERVER_SERVICE,
86 MN_EVOLUTION_SERVER_PATH,
87 MN_EVOLUTION_SERVER_INTERFACE,
88 NULL);
89 if (proxy)
90 {
91 self_disconnect_name_owner_signal(self);
92
93 dbus_g_proxy_add_signal(proxy,
94 MN_EVOLUTION_SERVER_SIGNAL_FOLDER_CHANGED,
95 G_TYPE_STRING, /* uri */
96 G_TYPE_INVALID);
97 dbus_g_proxy_add_signal(proxy,
98 MN_EVOLUTION_SERVER_SIGNAL_MESSAGE_READING,
99 G_TYPE_STRING, /* uri */
100 G_TYPE_INVALID);
101
102 g_signal_connect(proxy, "destroy", G_CALLBACK(self_proxy_destroy_h), self);
103
104 self_set_proxy(self, proxy);
105 }
106 else
107 self_connect_name_owner_signal(self);
108 }
109
110 private void
111 name_owner_changed_h (DBusGProxy *proxy,
112 const char *service_name,
113 const char *old_owner,
114 const char *new_owner,
115 gpointer user_data)
116 {
117 Self *self = user_data;
118
119 /* this is a main loop callback */
120 GDK_THREADS_ENTER();
121
122 if (! strcmp(service_name, MN_EVOLUTION_SERVER_SERVICE) && *new_owner)
123 self_connect(self);
124
125 GDK_THREADS_LEAVE();
126 }
127
128 private void
129 proxy_destroy_h (DBusGProxy *proxy, gpointer user_data)
130 {
131 Self *self = user_data;
132
133 /* this is a main loop callback */
134 GDK_THREADS_ENTER();
135
136 self_set_proxy(self, NULL);
137 self_connect_name_owner_signal(self);
138
139 GDK_THREADS_LEAVE();
140 }
141
142 public MNEvolutionClient *
143 get (void)
144 {
145 static Self *self = NULL;
146
147 /* does not need to be thread-safe */
148 if (! self)
149 self = GET_NEW;
150
151 return self;
152 }
153 }