~ubuntu-core-dev/update-notifier/ubuntu

« back to all changes in this revision

Viewing changes to src/upgrade-notifier.c

  • Committer: Balint Reczey
  • Date: 2019-09-20 20:02:13 UTC
  • mfrom: (975.1.4 master)
  • Revision ID: balint.reczey@canonical.com-20190920200213-8mx0d8aitaf1xo9c
MergeĀ lp:~rbalint/update-notifier/updates-available-world-readable

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* upgrade-notifier.c
2
 
 * Copyright (C) 2004 Lukas Lipka <lukas@pmad.net>
3
 
 *           (C) 2004 Michael Vogt <mvo@debian.org>
4
 
 *           (C) 2004 Michiel Sikkes <michiel@eyesopened.nl>
5
 
 *
6
 
 * This library is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU Lesser General Public
8
 
 * License as published by the Free Software Foundation; either
9
 
 * version 2 of the License, or (at your option) any later version.
10
 
 *
11
 
 * This library is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 * Lesser General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this library; if not, write to the
18
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
 
 * Boston, MA 02111-1307, USA.
20
 
 */
21
 
 
22
 
#ifdef HAVE_CONFIG_H
23
 
#include "config.h"
24
 
#endif
25
 
 
26
 
#define DBUS_API_SUBJECT_TO_CHANGE 1
27
 
 
28
 
 
29
 
#include <signal.h>
30
 
#include <gnome.h>
31
 
#include <gtk/gtk.h>
32
 
#include <dbus/dbus.h>
33
 
#include <dbus/dbus-glib.h>
34
 
 
35
 
#include "upgrade-notifier.h"
36
 
#include "eggtrayicon.h"
37
 
 
38
 
#define ICON_FILE PACKAGE_DATA_DIR"/pixmaps/upgrade-notifier.png"
39
 
#define UPGRADE_CHECKER PACKAGE_LIB_DIR"/upgrade-notifier/apt-check"
40
 
#define PKG_MANAGER PACKAGE_LIB_DIR"/upgrade-notifier/upgrade-app"
41
 
 
42
 
#define TIMEOUT 1000*60*60
43
 
 
44
 
void
45
 
invoke_update_manager ()
46
 
{
47
 
        //g_print("invoke_update_manager ()\n");
48
 
        gchar *argv[1];
49
 
        gchar *cmd;
50
 
        cmd = g_strdup_printf ("%s", PKG_MANAGER);
51
 
        argv[0] = cmd;
52
 
        g_spawn_async (NULL, argv, NULL, 0/*G_SPAWN_LEAVE_DESCRIPTORS_OPEN*/, NULL, NULL, NULL, NULL);
53
 
 
54
 
        g_free (cmd); 
55
 
}
56
 
 
57
 
gboolean
58
 
button_release_cb (GtkWidget *widget, 
59
 
                   GdkEventButton *event, 
60
 
                   UpgradeNotifier *un)
61
 
{
62
 
        if (event->button == 1 && event->type == GDK_BUTTON_RELEASE) {
63
 
                invoke_update_manager ();
64
 
        }
65
 
}
66
 
 
67
 
void
68
 
trayicon_update_tooltip (UpgradeNotifier *un)
69
 
{
70
 
        //g_print("update_tooltip: %x \n", un);
71
 
        gchar *updates;
72
 
        gchar *explanation;
73
 
 
74
 
        updates = g_strdup_printf(_("There are %i updates available!"), 
75
 
                                  un->num_upgrades);
76
 
 
77
 
        explanation = g_strdup(_("Press this icon to show the updates."));
78
 
 
79
 
        gtk_tooltips_set_tip(GTK_TOOLTIPS(un->tooltip), 
80
 
                             GTK_WIDGET (un->eventbox), 
81
 
                             updates, explanation);
82
 
 
83
 
        g_free (updates);
84
 
        g_free (explanation);
85
 
}
86
 
 
87
 
void 
88
 
trayicon_load (UpgradeNotifier *un)
89
 
{
90
 
        GdkPixbuf *pixbuf;
91
 
 
92
 
        pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (un->icon));
93
 
        
94
 
        if (pixbuf)
95
 
                g_object_unref (G_OBJECT (pixbuf));
96
 
 
97
 
        pixbuf = gdk_pixbuf_new_from_file (ICON_FILE, NULL);
98
 
 
99
 
        gtk_image_set_from_pixbuf (GTK_IMAGE (un->icon), pixbuf);
100
 
}
101
 
 
102
 
gboolean
103
 
trayicon_create (UpgradeNotifier *un)
104
 
{
105
 
        //g_print("trayicon_create()\n");
106
 
        un->tooltip = gtk_tooltips_new ();
107
 
        un->tray_icon = egg_tray_icon_new ("apt upgrade-notifier");
108
 
        un->eventbox = gtk_event_box_new ();
109
 
        un->icon = gtk_image_new ();
110
 
 
111
 
        trayicon_load (un);
112
 
 
113
 
        gtk_container_add (GTK_CONTAINER (un->eventbox), un->icon);
114
 
        gtk_container_add (GTK_CONTAINER (un->tray_icon), un->eventbox);
115
 
 
116
 
        g_signal_connect (G_OBJECT(un->tray_icon),
117
 
                          "button-release-event",
118
 
                          G_CALLBACK (button_release_cb),
119
 
                          un);
120
 
 
121
 
        gtk_widget_show_all (GTK_WIDGET (un->tray_icon));
122
 
 
123
 
        /* Initial tooltip update */
124
 
        trayicon_update_tooltip (un);
125
 
 
126
 
        return TRUE;
127
 
}
128
 
 
129
 
void
130
 
update_check (UpgradeNotifier *un)
131
 
{
132
 
        //g_print("upgrade_check(): %x \n", un);
133
 
        FILE *f = popen(UPGRADE_CHECKER, "r");
134
 
        char s[400];
135
 
 
136
 
        un->num_upgrades = 0;
137
 
 
138
 
        /* Check the number of upgrades trough the helper script */
139
 
        while (fgets (s, 400, f) != NULL) {
140
 
                un->num_upgrades++;
141
 
        }
142
 
 
143
 
        pclose (f);
144
 
 
145
 
        if (un->num_upgrades == 0) {
146
 
                /* We don't have any updates. */
147
 
                if (un->is_displayed) {
148
 
                        /* We're still displayed, shoot ourselves */
149
 
                        gtk_widget_destroy (GTK_WIDGET (un->tray_icon));
150
 
                        un->is_displayed = FALSE;
151
 
                }
152
 
        } else {
153
 
                /* There are updates */
154
 
                if (un->is_displayed) {
155
 
                        /* We're already displayed, update tooltip */
156
 
                        trayicon_update_tooltip (un);
157
 
                } else {
158
 
                        /* We're not already displayed, display ourselves */
159
 
                        if (trayicon_create (un))
160
 
                                un->is_displayed = TRUE;
161
 
                }
162
 
        }
163
 
        //g_print("upgrades: %i\n", un->num_upgrades);
164
 
}
165
 
 
166
 
static DBusHandlerResult
167
 
signal_filter(DBusConnection *connection, DBusMessage *message, void *data)
168
 
{
169
 
#if 0 // DEBUG stuff to better understand about dbus
170
 
        g_print("path: %s\n", dbus_message_get_path(message));
171
 
        g_print("interface: %s\n", dbus_message_get_interface(message));
172
 
        g_print("type: %i\n", dbus_message_get_type(message));
173
 
        g_print("dest: %s\n", dbus_message_get_destination(message));   
174
 
        g_print("member: %s\n", dbus_message_get_member(message));      
175
 
#endif
176
 
        //g_print("signal_filter: %x\n");
177
 
 
178
 
        if(dbus_message_is_signal(message, "app.apt.dbus", "changed") 
179
 
           || dbus_message_is_signal(message, "app.apt.dbus", "updated")) {
180
 
           DBusError error;
181
 
           gboolean finished=FALSE;
182
 
           dbus_error_init(&error);
183
 
           if(dbus_message_get_args(message, &error, 
184
 
                                    DBUS_TYPE_BOOLEAN, &finished, 
185
 
                                    DBUS_TYPE_INVALID)) {
186
 
              if(finished) {
187
 
                 //g_print("dbus message triggered update_check\n");
188
 
                 update_check(data);
189
 
              }
190
 
           }
191
 
              
192
 
        }
193
 
 
194
 
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
195
 
}
196
 
 
197
 
int 
198
 
main (int argc, char *argv[])
199
 
{
200
 
        GnomeClient *client;
201
 
        UpgradeNotifier *un;
202
 
        GMainLoop *loop;
203
 
        DBusConnection *bus;
204
 
        DBusError error;
205
 
 
206
 
        gnome_program_init (PACKAGE, PACKAGE_VERSION, 
207
 
                            LIBGNOMEUI_MODULE,
208
 
                            argc, argv, 
209
 
                            GNOME_PARAM_NONE);
210
 
 
211
 
        client = gnome_master_client ();
212
 
 
213
 
        /* Make sure we die when the session dies */
214
 
        g_signal_connect (G_OBJECT (client), "die",
215
 
                          G_CALLBACK (gtk_main_quit), NULL);
216
 
        
217
 
        gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY);
218
 
 
219
 
        /* Create the UpgradeNotifier object */
220
 
        un = g_new0 (UpgradeNotifier, 1);
221
 
 
222
 
        /* setup a dbus channel */
223
 
        loop = g_main_loop_new(NULL, FALSE);
224
 
        dbus_error_init(&error);
225
 
        bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
226
 
        if(!bus) {
227
 
           g_error("Failed to connect to D-BUS: %s",error.message);
228
 
           return 1;
229
 
        }
230
 
        dbus_connection_setup_with_g_main(bus, NULL);
231
 
        dbus_bus_add_match(bus, "type='signal',interface='app.apt.dbus'", 
232
 
                           &error);
233
 
        dbus_connection_add_filter(bus, signal_filter, un, NULL);
234
 
 
235
 
        /* Check for updates for the first time */
236
 
        update_check (un);
237
 
 
238
 
        /* Set a time-out for the update check */
239
 
        g_timeout_add (TIMEOUT, (GSourceFunc)update_check, un);
240
 
 
241
 
        /* Start the main gtk loop */
242
 
        gtk_main ();
243
 
 
244
 
        return 0;
245
 
}