/* tray.c * Copyright (C) 2004 Lukas Lipka * (C) 2004 Michael Vogt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #include "eggtrayicon.h" #define ICON_FILE PACKAGE_DATA_DIR"/pixmaps/update-notifier.png" #define UPGRADE_CHECKER PACKAGE_LIB_DIR"/update-notifier/apt-check" #define PACKAGE_MANAGER "/usr/sbin/synaptic" const char * gksu_message = _("Please enter your password to start the package manager"); // tick is each (1/1000)sec #define TIMEOUT 1000*60*60 EggTrayIcon *tray_icon = NULL; GtkWidget *icon = NULL; GtkWidget *box = NULL; GtkTooltips *tt = NULL; GtkWidget *menu = NULL; GladeXML *xml; guint timer_id; GString *all_upgrades = NULL; int num_upgrades = 0; #if 0 static void start_package_manager() { gchar *cmd; cmd = g_strdup_printf("gksu -u root -m \"%s\" " " \"%s ; killall -HUP upgrade-notifier \" &", gksu_message, PACKAGE_MANAGER); system(cmd); g_free(cmd); } #endif static void create_menu () { GtkWidget *menuitem; menu = gtk_menu_new (); menuitem = gtk_menu_item_new_with_label (_("Start package manager")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (start_package_manager), 0); menuitem = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); menuitem = gtk_menu_item_new_with_label (_("Exit")); g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (gtk_main_quit), 0); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_widget_show_all (menu); } static void tray_icon_load () { GdkPixbuf *pixbuf; pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (icon)); if (pixbuf) g_object_unref (G_OBJECT (pixbuf)); pixbuf = gdk_pixbuf_new_from_file (ICON_FILE, NULL); gtk_image_set_from_pixbuf (GTK_IMAGE (icon), pixbuf); #if 0 gtk_image_set_from_stock(GTK_IMAGE(icon), "gtk-dialog-warning", GTK_ICON_SIZE_SMALL_TOOLBAR); #endif // hide by default gtk_widget_hide(icon); } static void clicked (GtkWidget *widget, GdkEventButton *event, gpointer data) { GtkWidget *view, *dia; GtkTextBuffer *buffer; if(event->button == 1 && event->type==GDK_2BUTTON_PRESS) { //xml = glade_xml_new("upgrade-dialog.glade",NULL, NULL); dia = glade_xml_get_widget(xml, "dialog_upgrades"); view = glade_xml_get_widget(xml, "textview_upgrades"); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); gtk_text_buffer_set_text (buffer, all_upgrades->str, -1); if(gtk_dialog_run(dia) == GTK_RESPONSE_OK) start_package_manager(); gtk_widget_hide (dia); } if(event->button == 3) gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time); } void tray_create () { tt = gtk_tooltips_new(); create_menu (); xml = glade_xml_new(PACKAGE_LIB_DIR"/update-notifier/upgrade-dialog.glade",NULL, NULL); tray_icon = egg_tray_icon_new ("apt update-notifier"); box = gtk_event_box_new (); icon = gtk_image_new (); gtk_container_add (GTK_CONTAINER (box), icon); gtk_container_add (GTK_CONTAINER (tray_icon), box); gtk_widget_show_all (GTK_WIDGET (tray_icon)); g_signal_connect (G_OBJECT (box), "button-press-event", G_CALLBACK (clicked), NULL); tray_icon_load (); } void tray_destroy () { GdkPixbuf *pixbuf; pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (icon)); if (pixbuf) g_object_unref (G_OBJECT (pixbuf)); gtk_widget_destroy (icon); gtk_widget_destroy (GTK_WIDGET (tray_icon)); } void timer(gpointer data) { gchar **strarray; num_upgrades = 0; if(all_upgrades != NULL) g_string_free(all_upgrades, TRUE); all_upgrades = g_string_new(""); FILE *f = popen(UPGRADE_CHECKER,"r"); char s[401]; gboolean upgrade_available = FALSE; while( fgets(s, 400, f) != NULL) { strarray = g_strsplit(s," ", 0); g_string_append(all_upgrades, strarray[1]); g_string_append(all_upgrades, "\n"); g_strfreev(strarray); num_upgrades++; } fclose(f); if(num_upgrades > 0) { gchar *s; s = g_strdup_printf(ngettext("%i system upgrade available", "%i system upgrades available", num_upgrades), num_upgrades); gtk_tooltips_set_tip(tt, GTK_WIDGET(box), s, NULL); g_free(s); gtk_widget_show(icon); } else { gtk_widget_hide(icon); } } void sighup_handler(int j, siginfo_t *i, void *d) { //g_print("sighub_handler\n"); // reread timer timer(NULL); } int main (int argc, char *argv[]) { GnomeClient *client; gnome_program_init ("update-notifier", "0.3", LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_NONE); client = gnome_master_client (); gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY); // make sure we die if the session dies gtk_signal_connect (GTK_OBJECT (client), "die", GTK_SIGNAL_FUNC (gtk_main_quit), NULL); struct sigaction new_act; memset( &new_act, 0, sizeof( new_act ) ); new_act.sa_handler = sighup_handler; sigaction( SIGHUP, &new_act, NULL); // create icons and menu tray_create (); // fire timer up once, then set timeout timer(NULL); timer_id = gtk_timeout_add(TIMEOUT, (GtkFunction)timer, NULL); // run, the eventloop now takes care gtk_main (); tray_destroy (); return 0; }