diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/inc.c | 158 | ||||
-rw-r--r-- | src/inc.h | 3 | ||||
-rw-r--r-- | src/notificationwindow.c | 276 | ||||
-rw-r--r-- | src/notificationwindow.h | 35 |
6 files changed, 439 insertions, 42 deletions
@@ -1,3 +1,9 @@ +2013-02-08 + + * src/inc.[ch] + src/notificationwindow.[ch]: implemented new message notification + popup window. + 2013-02-01 * nsis/*.{nsh,nsi}: translate Start Menu shortcuts. diff --git a/src/Makefile.am b/src/Makefile.am index cc0feb3c..1c613e63 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -93,7 +93,8 @@ sylpheed_SOURCES = \ update_check.c update_check.h \ quote_fmt_lex.l quote_fmt_lex.h \ quote_fmt_parse.y quote_fmt.h \ - sylpheed-marshal.c sylpheed-marshal.h + sylpheed-marshal.c sylpheed-marshal.h \ + notificationwindow.c notificationwindow.h BUILT_SOURCES = \ quote_fmt_lex.c \ @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2012 Hiroyuki Yamamoto + * Copyright (C) 1999-2013 Hiroyuki Yamamoto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,6 +58,7 @@ #include "progressdialog.h" #include "alertpanel.h" #include "trayicon.h" +#include "notificationwindow.h" #include "filter.h" #include "folder.h" #include "procheader.h" @@ -70,6 +71,18 @@ typedef struct _IncAccountNewMsgCount gint new_messages; } IncAccountNewMsgCount; +typedef struct _IncMsgSummary +{ + gchar *subject; + gchar *from; +} IncMsgSummary; + +struct _IncResult +{ + GSList *count_list; + GSList *msg_summaries; +}; + static GList *inc_dialog_list = NULL; @@ -84,15 +97,18 @@ static GdkPixbuf *ok_pixbuf; static void inc_finished (MainWindow *mainwin, - GSList *msg_counts); + IncResult *result); static GSList *inc_add_message_count (GSList *list, PrefsAccount *account, gint new_messages); +static void inc_result_free (IncResult *result, + gboolean free_self); static gint inc_remote_account_mail (MainWindow *mainwin, PrefsAccount *account); static gint inc_account_mail_real (MainWindow *mainwin, - PrefsAccount *account); + PrefsAccount *account, + IncResult *result); static IncProgressDialog *inc_progress_dialog_create (gboolean autocheck); @@ -101,8 +117,7 @@ static void inc_progress_dialog_destroy (IncProgressDialog *inc_dialog); static IncSession *inc_session_new (PrefsAccount *account); static void inc_session_destroy (IncSession *session); -static gint inc_start (IncProgressDialog *inc_dialog, - GSList **count_list); +static gint inc_start (IncProgressDialog *inc_dialog); static IncState inc_pop3_session_do (IncSession *session); static void inc_progress_dialog_update (IncProgressDialog *inc_dialog, @@ -161,14 +176,14 @@ static gint inc_autocheck_func (gpointer data); /** * inc_finished: * @mainwin: Main window. - * @msg_counts: GSList of Number of received messages for each account. + * @result: Information of incorporation result. * @new_messages: Number of received messages. * * Update the folder view and the summary view after receiving * messages. If @new_messages is 0, this function avoids unneeded * updating. **/ -static void inc_finished(MainWindow *mainwin, GSList *msg_counts) +static void inc_finished(MainWindow *mainwin, IncResult *result) { FolderItem *item; gint new_messages = 0; @@ -176,10 +191,12 @@ static void inc_finished(MainWindow *mainwin, GSList *msg_counts) IncAccountNewMsgCount *count; GSList *cur; - for (cur = msg_counts; cur != NULL; cur = cur->next) { - count = cur->data; - if (count->new_messages > 0) - new_messages += count->new_messages; + if (result) { + for (cur = result->count_list; cur != NULL; cur = cur->next) { + count = cur->data; + if (count->new_messages > 0) + new_messages += count->new_messages; + } } debug_print("inc_finished: %d new message(s)\n", new_messages); @@ -190,14 +207,15 @@ static void inc_finished(MainWindow *mainwin, GSList *msg_counts) } if (new_messages > 0 && !block_notify) { + gchar buf[1024]; GString *str; gint c = 0; str = g_string_new(""); g_string_printf(str, _("Sylpheed: %d new messages"), new_messages); - if (msg_counts) { - for (cur = msg_counts; cur != NULL; cur = cur->next) { + if (result) { + for (cur = result->count_list; cur != NULL; cur = cur->next) { count = cur->data; if (count->new_messages > 0) { if (c == 0) @@ -214,6 +232,24 @@ static void inc_finished(MainWindow *mainwin, GSList *msg_counts) debug_print("inc_finished: %s\n", str->str); trayicon_set_tooltip(str->str); trayicon_set_notify(TRUE); + + g_snprintf(buf, sizeof(buf), _("Sylpheed: %d new messages"), new_messages); + g_string_truncate(str, 0); + if (result) { + for (cur = result->msg_summaries; cur != NULL; cur = cur->next) { + IncMsgSummary *summary = cur->data; + gchar *markup; + + if (str->len > 0) + g_string_append_c(str, '\n'); + markup = g_markup_printf_escaped("<b>%s</b> %s", summary->subject, summary->from); + g_string_append(str, markup); + g_free(markup); + } + } + + notification_window_create(buf, str->str, 5); + g_string_free(str, TRUE); } @@ -271,10 +307,28 @@ static GSList *inc_add_message_count(GSList *list, PrefsAccount *account, return g_slist_append(list, count); } +static void inc_result_free(IncResult *result, gboolean free_self) +{ + GSList *cur; + + slist_free_strings(result->count_list); + g_slist_free(result->count_list); + for (cur = result->msg_summaries; cur != NULL; cur = cur->next) { + IncMsgSummary *sum = cur->data; + g_free(sum->subject); + g_free(sum->from); + g_free(sum); + } + g_slist_free(result->msg_summaries); + + if (free_self) + g_free(result); +} + void inc_mail(MainWindow *mainwin) { + IncResult result = {NULL, NULL}; gint new_msgs = 0; - GSList *list = NULL; if (inc_lock_count) return; if (inc_is_active()) return; @@ -301,23 +355,21 @@ void inc_mail(MainWindow *mainwin) if (prefs_common.inc_local) { new_msgs = inc_spool(); - list = inc_add_message_count(list, NULL, new_msgs); + result.count_list = inc_add_message_count(result.count_list, NULL, new_msgs); } } else { if (prefs_common.inc_local) { new_msgs = inc_spool(); if (new_msgs < 0) new_msgs = 0; - list = inc_add_message_count(list, NULL, new_msgs); + result.count_list = inc_add_message_count(result.count_list, NULL, new_msgs); } - new_msgs = inc_account_mail_real(mainwin, cur_account); - list = inc_add_message_count(list, cur_account, new_msgs); + new_msgs = inc_account_mail_real(mainwin, cur_account, &result); } - inc_finished(mainwin, list); - slist_free_strings(list); - g_slist_free(list); + inc_finished(mainwin, &result); + inc_result_free(&result, FALSE); inc_is_running = FALSE; @@ -455,7 +507,8 @@ static gint inc_remote_account_mail(MainWindow *mainwin, PrefsAccount *account) return new_msgs; } -static gint inc_account_mail_real(MainWindow *mainwin, PrefsAccount *account) +static gint inc_account_mail_real(MainWindow *mainwin, PrefsAccount *account, + IncResult *result) { IncProgressDialog *inc_dialog; IncSession *session; @@ -471,18 +524,19 @@ static gint inc_account_mail_real(MainWindow *mainwin, PrefsAccount *account) inc_dialog = inc_progress_dialog_create(FALSE); inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session); inc_dialog->mainwin = mainwin; + inc_dialog->result = result; inc_progress_dialog_set_list(inc_dialog); main_window_set_toolbar_sensitive(mainwin); main_window_set_menu_sensitive(mainwin); - return inc_start(inc_dialog, NULL); + return inc_start(inc_dialog); } gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account) { + IncResult result = {NULL, NULL}; gint new_msgs; - GSList *list; if (inc_lock_count) return 0; if (inc_is_active()) return 0; @@ -498,12 +552,10 @@ gint inc_account_mail(MainWindow *mainwin, PrefsAccount *account) syl_plugin_signal_emit("inc-mail-start", account); - new_msgs = inc_account_mail_real(mainwin, account); + new_msgs = inc_account_mail_real(mainwin, account, &result); - list = inc_add_message_count(NULL, account, new_msgs); - inc_finished(mainwin, list); - slist_free_strings(list); - g_slist_free(list); + inc_finished(mainwin, &result); + inc_result_free(&result, FALSE); inc_is_running = FALSE; @@ -517,7 +569,7 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck) { GList *list, *queue_list = NULL; IncProgressDialog *inc_dialog; - GSList *count_list = NULL; + IncResult result = {NULL, NULL}; gint new_msgs = 0; if (inc_lock_count) return; @@ -538,7 +590,7 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck) new_msgs = inc_spool(); if (new_msgs < 0) new_msgs = 0; - count_list = inc_add_message_count(count_list, NULL, new_msgs); + result.count_list = inc_add_message_count(result.count_list, NULL, new_msgs); } /* check IMAP4 / News folders */ @@ -547,7 +599,7 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck) if ((account->protocol == A_IMAP4 || account->protocol == A_NNTP) && account->recv_at_getall) { new_msgs = inc_remote_account_mail(mainwin, account); - count_list = inc_add_message_count(count_list, account, new_msgs); + result.count_list = inc_add_message_count(result.count_list, account, new_msgs); } } @@ -567,17 +619,17 @@ void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck) inc_dialog = inc_progress_dialog_create(autocheck); inc_dialog->queue_list = queue_list; inc_dialog->mainwin = mainwin; + inc_dialog->result = &result; inc_progress_dialog_set_list(inc_dialog); main_window_set_toolbar_sensitive(mainwin); main_window_set_menu_sensitive(mainwin); - inc_start(inc_dialog, &count_list); + inc_start(inc_dialog); } - inc_finished(mainwin, count_list); - slist_free_strings(count_list); - g_slist_free(count_list); + inc_finished(mainwin, &result); + inc_result_free(&result, FALSE); inc_is_running = FALSE; @@ -612,13 +664,14 @@ gint inc_pop_before_smtp(PrefsAccount *account) _("Authenticating with POP3")); inc_dialog->queue_list = g_list_append(inc_dialog->queue_list, session); inc_dialog->mainwin = mainwin; + inc_dialog->result = NULL; inc_progress_dialog_set_list(inc_dialog); inc_dialog->show_dialog = TRUE; main_window_set_toolbar_sensitive(mainwin); main_window_set_menu_sensitive(mainwin); - inc_start(inc_dialog, NULL); + inc_start(inc_dialog); inc_is_running = FALSE; @@ -776,7 +829,7 @@ static void inc_update_folder_foreach(GHashTable *table) folderview_update_item_foreach(table, TRUE); } -static gint inc_start(IncProgressDialog *inc_dialog, GSList **count_list) +static gint inc_start(IncProgressDialog *inc_dialog) { IncSession *session; GList *qlist; @@ -903,8 +956,8 @@ static gint inc_start(IncProgressDialog *inc_dialog, GSList **count_list) break; } - if (count_list) - *count_list = inc_add_message_count(*count_list, pop3_session->ac_prefs, session->new_msgs); + if (inc_dialog->result) + inc_dialog->result->count_list = inc_add_message_count(inc_dialog->result->count_list, pop3_session->ac_prefs, session->new_msgs); new_msgs += session->new_msgs; if (!prefs_common.scan_all_after_inc) { @@ -1394,6 +1447,17 @@ static gint inc_recv_message(Session *session, const gchar *msg, gpointer data) return 0; } +/** + * inc_drop_message: + * @session: Current Pop3Session. + * @file: Received message file. + * + * Callback function to drop received message into local mailbox. + * + * Return value: DROP_OK if succeeded. DROP_ERROR if error occurred. + * DROP_DONT_RECEIVE if the message should be skipped. + * DROP_DELETE if the message should be deleted. + **/ static gint inc_drop_message(Pop3Session *session, const gchar *file) { FolderItem *inbox; @@ -1404,11 +1468,14 @@ static gint inc_drop_message(Pop3Session *session, const gchar *file) gint val; gboolean is_junk = FALSE; gboolean is_counted = FALSE; + IncProgressDialog *inc_dialog; g_return_val_if_fail(inc_session != NULL, DROP_ERROR); gdk_threads_enter(); + inc_dialog = (IncProgressDialog *)inc_session->data; + if (session->ac_prefs->inbox) { inbox = folder_find_item_from_identifier (session->ac_prefs->inbox); @@ -1521,8 +1588,17 @@ static gint inc_drop_message(Pop3Session *session, const gchar *file) else { val = DROP_OK; if (!is_junk && is_counted && - fltinfo->actions[FLT_ACTION_MARK_READ] == FALSE) + fltinfo->actions[FLT_ACTION_MARK_READ] == FALSE) { inc_session->new_msgs++; + + if (inc_dialog->result && msginfo->subject && g_slist_length(inc_dialog->result->msg_summaries) < 5) { + IncMsgSummary *summary; + summary = g_new(IncMsgSummary, 1); + summary->subject = g_strdup(msginfo->subject); + summary->from = g_strdup(msginfo->fromname); + inc_dialog->result->msg_summaries = g_slist_append(inc_dialog->result->msg_summaries, summary); + } + } } procmsg_msginfo_free(msginfo); @@ -32,6 +32,7 @@ #include "session.h" #include "pop.h" +typedef struct _IncResult IncResult; typedef struct _IncProgressDialog IncProgressDialog; typedef struct _IncSession IncSession; @@ -64,6 +65,8 @@ struct _IncProgressDialog GList *queue_list; /* list of IncSession */ gint cur_row; + + IncResult *result; }; struct _IncSession diff --git a/src/notificationwindow.c b/src/notificationwindow.c new file mode 100644 index 00000000..7c8b0258 --- /dev/null +++ b/src/notificationwindow.c @@ -0,0 +1,276 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2013 Hiroyuki Yamamoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#ifdef G_OS_WIN32 +# include <windows.h> +#endif + +#include "notificationwindow.h" +#include "mainwindow.h" +#include "utils.h" + +#define NOTIFICATIONWINDOW_NOTIFY_PERIOD 10000 +#define NOTIFICATIONWINDOW_WIDTH 280 +#define NOTIFICATIONWINDOW_HEIGHT 96 +#define FADE_REFRESH_RATE 50 +#define FADE_SPEED 5 + +struct _NotificationWindow +{ + GtkWidget *window; + + GtkWidget *msglabel; + GtkWidget *sublabel; + + guint notify_tag; + + gint x; + gint y; + gint width; + gint height; + gint fade_length; + gint fade_count; + guint timeout; +}; + +static NotificationWindow notify_window; + +static void notification_window_destroy(void); + +static gboolean notify_timeout_cb(gpointer data); + +static gboolean nwin_button_pressed (GtkWidget *widget, + GdkEventButton *event, + gpointer data); +static gboolean nwin_entered (GtkWidget *widget, + GdkEventCrossing *event, + gpointer data); +static gboolean nwin_motion_notify (GtkWidget *widget, + GdkEventMotion *event, + gpointer data); + +static void nwin_destroy_cb (GtkWidget *widget, + gpointer data); + + +static void get_work_area(GdkRectangle *rect) +{ +#ifdef G_OS_WIN32 + RECT rc; + + SystemParametersInfoW(SPI_GETWORKAREA, 0, &rc, 0); + rect->x = rc.left; + rect->y = rc.top; + rect->width = rc.right - rc.left; + rect->height = rc.bottom - rc.top; +#else + rect->x = 0; + rect->y = 0; + rect->width = gdk_screen_width(); + rect->height = gdk_screen_height(); +#endif +} + +gint notification_window_create(const gchar *message, const gchar *submessage, + guint timeout) +{ + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *msglabel; + GtkWidget *sublabel; + GdkRectangle rect; + gint x, y; + GtkRequisition requisition; + + if (notify_window.window) { + notification_window_destroy(); + } + + window = gtk_window_new(GTK_WINDOW_POPUP); + gtk_window_set_title(GTK_WINDOW(window), _("Notification")); + gtk_window_set_wmclass(GTK_WINDOW(window), "notification", "Sylpheed"); + gtk_container_set_border_width(GTK_CONTAINER(window), 4); + gtk_widget_set_events(window, GDK_EXPOSURE_MASK|GDK_BUTTON_MOTION_MASK|GDK_POINTER_MOTION_MASK|GDK_POINTER_MOTION_HINT_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_ENTER_NOTIFY_MASK|GDK_LEAVE_NOTIFY_MASK); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(window), TRUE); + gtk_window_set_gravity(GTK_WINDOW(window), GDK_GRAVITY_SOUTH_EAST); + gtk_widget_set_size_request(window, NOTIFICATIONWINDOW_WIDTH, -1); + gtk_widget_realize(window); + gdk_window_set_type_hint(window->window, GDK_WINDOW_TYPE_HINT_NOTIFICATION); + + /* move window bottom-right */ + get_work_area(&rect); + x = rect.x + rect.width - NOTIFICATIONWINDOW_WIDTH - 2; + if (x < 0) x = 0; + y = rect.y + rect.height - NOTIFICATIONWINDOW_HEIGHT - 2; + if (y < 0) y = 0; + gtk_window_move(GTK_WINDOW(window), x, y); + + g_signal_connect(G_OBJECT(window), "destroy", + G_CALLBACK(nwin_destroy_cb), NULL); + g_signal_connect(G_OBJECT(window), "button_press_event", + G_CALLBACK(nwin_button_pressed), NULL); + g_signal_connect(G_OBJECT(window), "enter_notify_event", + G_CALLBACK(nwin_entered), NULL); + g_signal_connect(G_OBJECT(window), "motion_notify_event", + G_CALLBACK(nwin_motion_notify), NULL); + + vbox = gtk_vbox_new(FALSE, 4); + gtk_container_add(GTK_CONTAINER(window), vbox); + + msglabel = gtk_label_new(message); + gtk_box_pack_start(GTK_BOX(vbox), msglabel, FALSE, FALSE, 4); + + sublabel = gtk_label_new(""); + gtk_label_set_ellipsize(GTK_LABEL(sublabel), PANGO_ELLIPSIZE_END); + gtk_label_set_markup(GTK_LABEL(sublabel), submessage); + gtk_box_pack_start(GTK_BOX(vbox), sublabel, FALSE, FALSE, 4); + + gtk_widget_show_all(window); + + /* adjust window size and position */ + gtk_widget_get_child_requisition(window, &requisition); + notify_window.width = NOTIFICATIONWINDOW_WIDTH; + notify_window.height = MAX(requisition.height, NOTIFICATIONWINDOW_HEIGHT); + gtk_widget_set_size_request(window, NOTIFICATIONWINDOW_WIDTH, notify_window.height); + y = rect.y + rect.height - notify_window.height - 2; + if (y < 0) y = 0; + gtk_window_move(GTK_WINDOW(window), x, y); + + notify_window.notify_tag = g_timeout_add(timeout * 1000, + notify_timeout_cb, NULL); + + debug_print("notification window created\n"); + + notify_window.window = window; + notify_window.msglabel = msglabel; + notify_window.sublabel = sublabel; + notify_window.x = x; + notify_window.y = y; + notify_window.fade_length = 0; + notify_window.fade_count = 0; + notify_window.timeout = timeout; + + return 0; +} + +void notification_window_set_message(const gchar *message, + const gchar *submessage) +{ + gtk_label_set_text(GTK_LABEL(notify_window.msglabel), message); + gtk_label_set_markup(GTK_LABEL(notify_window.sublabel), submessage); +} + +void notification_window_close(void) +{ + notification_window_destroy(); +} + +static void notification_window_destroy(void) +{ + if (notify_window.window) { + if (notify_window.notify_tag > 0) { + g_source_remove(notify_window.notify_tag); + notify_window.notify_tag = 0; + } + + gtk_widget_destroy(notify_window.window); + + notify_window.window = NULL; + notify_window.msglabel = NULL; + notify_window.sublabel = NULL; + + debug_print("notification window removed\n"); + } +} + +static gboolean notify_fadeout_timeout_cb(gpointer data) +{ + gdk_threads_enter(); + notify_window.fade_length -= FADE_SPEED; + notify_window.fade_count++; + + gtk_window_move(GTK_WINDOW(notify_window.window), + notify_window.x, notify_window.y + notify_window.fade_count * FADE_SPEED); + + if (notify_window.fade_length <= 0) { + notification_window_destroy(); + gdk_threads_leave(); + return FALSE; + } + gdk_threads_leave(); + return TRUE; +} + +static gboolean notify_timeout_cb(gpointer data) +{ + gdk_threads_enter(); + notify_window.fade_length = gdk_screen_height() - notify_window.y; + notify_window.notify_tag = g_timeout_add(FADE_REFRESH_RATE, + notify_fadeout_timeout_cb, + NULL); + gdk_threads_leave(); + + return FALSE; +} + +static gboolean nwin_button_pressed(GtkWidget *widget, GdkEventButton *event, + gpointer data) +{ + if (!event) + return FALSE; + + notification_window_destroy(); + main_window_popup(main_window_get()); + + return TRUE; +} + +static gboolean nwin_entered(GtkWidget *widget, GdkEventCrossing *event, + gpointer data) +{ + return FALSE; +} + +static gboolean nwin_motion_notify(GtkWidget *widget, GdkEventMotion *event, + gpointer data) +{ + if (notify_window.notify_tag > 0) { + g_source_remove(notify_window.notify_tag); + notify_window.notify_tag = 0; + } + notify_window.fade_count = 0; + gtk_window_move(GTK_WINDOW(notify_window.window), + notify_window.x, notify_window.y); + notify_window.notify_tag = g_timeout_add(notify_window.timeout * 1000, + notify_timeout_cb, NULL); + + return FALSE; +} + +static void nwin_destroy_cb(GtkWidget *widget, gpointer data) +{ +} diff --git a/src/notificationwindow.h b/src/notificationwindow.h new file mode 100644 index 00000000..d724af27 --- /dev/null +++ b/src/notificationwindow.h @@ -0,0 +1,35 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 1999-2013 Hiroyuki Yamamoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __NOTIFICATIONWINDOW_H__ +#define __NOTIFICATIONWINDOW_H__ + +#include <glib.h> +#include <gtk/gtk.h> + +typedef struct _NotificationWindow NotificationWindow; + +gint notification_window_create (const gchar *message, + const gchar *submessage, + guint timeout); +void notification_window_set_message (const gchar *message, + const gchar *submessage); +void notification_window_close (void); + +#endif /* __NOTIFICATIONWINDOW_H__ */ |