From: Christopher Aillon <caillon@redhat.com> Date: Thu, 7 Apr 2011 19:34:14 -0700 Subject: [PATCH] Link directly against libnotify Dynamically loading the library isn't ideal since the soname can change silently on us. Additionally, notify-send is shipped as part of libnotify, so we aren't actually bringing in a new dependency. Since we'd need to patch the source and rebuild for new sonames anyway, there's little benefit to dynamically loading libnotify. Plus, this has the benefit of cleaning up the code, as well as ensuring we'll catch any future soname changes sooner. https://bugzilla.redhat.com/show_bug.cgi?id=693362 https://sourceforge.net/tracker/?func=detail&aid=3280223&group_id=239&atid=100239 --- configure.in | 23 +++++++ src/fe-gtk/plugin-tray.c | 144 ++++++++++------------------------------------- 2 files changed, 55 insertions(+), 112 deletions(-) diff -p -U8 xchat-2.8.8/configure.in.libnotifyso4 xchat-2.8.8/configure.in --- xchat-2.8.8/configure.in.libnotifyso4 2010-05-29 23:01:16.000000000 -0700 +++ xchat-2.8.8/configure.in 2011-04-07 19:27:00.448137113 -0700 @@ -34,16 +34,17 @@ AH_VERBATIM([PREFIX],[#undef PREFIX]) AH_VERBATIM([XCHATLIBDIR],[#undef XCHATLIBDIR]) AH_VERBATIM([XCHATSHAREDIR],[#undef XCHATSHAREDIR]) AH_VERBATIM([SOCKS],[#undef SOCKS]) AH_VERBATIM([USE_MSPROXY],[#undef USE_MSPROXY]) dnl AH_VERBATIM([USE_GNOME],[#undef USE_GNOME]) AH_VERBATIM([USE_SHM],[#undef USE_SHM]) AH_VERBATIM([USE_GTKSPELL],[#undef USE_GTKSPELL]) AH_VERBATIM([USE_LIBSEXY],[#undef USE_LIBSEXY]) +AH_VERBATIM([USE_LIBNOTIFY],[#undef USE_LIBNOTIFY]) AH_VERBATIM([USE_IPV6],[#undef USE_IPV6]) AH_VERBATIM([USE_MMX],[#undef USE_MMX]) AH_VERBATIM([USE_OPENSSL],[#undef USE_OPENSSL]) AH_VERBATIM([USE_PLUGIN],[#undef USE_PLUGIN]) AH_VERBATIM([USE_XFT],[#undef USE_XFT]) AH_VERBATIM([USE_XLIB],[#undef USE_XLIB]) AH_VERBATIM([USE_SIGACTION],[#undef USE_SIGACTION]) AH_VERBATIM([USING_FREEBSD],[#undef USING_FREEBSD]) @@ -126,16 +127,20 @@ AC_ARG_ENABLE(tcl, AC_ARG_ENABLE(plugin, [ --disable-plugin disable plugin support], plugin=$enableval, plugin=yes) AC_ARG_ENABLE(dbus, [ --disable-dbus disable DBUS support], dbus=$enableval, dbus=yes) +AC_ARG_ENABLE(libnotify, +[ --disable-libnotify disable libnotify support], + libnotify=$enableval, libnotify=yes) + AC_ARG_ENABLE(mmx, [ --disable-mmx disable MMX assembly routines], mmx=$enableval, mmx=yes) AC_ARG_ENABLE(shm, [ --enable-shm enable use of XShm for fast tinting (default: no)], shm=$enableval, shm=no) @@ -482,16 +487,32 @@ if test "x$dbus" = "xyes" ; then DBUS_SERVICES_DIR="$DATADIR/dbus-1/services" AC_SUBST(DBUS_SERVICES_DIR) AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for DBUS is]) fi fi dnl ********************************************************************* +dnl ** LIBNOTIFY ******************************************************** +dnl ********************************************************************* + +if test "x$libnotify" = "xyes" ; then + PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= 0.4, [], [ + AC_MSG_RESULT(no) + libnotify=no + ]) + if test "$libnotify" != "no" ; then + GUI_LIBS="$GUI_LIBS $LIBNOTIFY_LIBS" + GUI_CFLAGS="$GUI_CFLAGS $LIBNOTIFY_CFLAGS" + AC_DEFINE(USE_LIBNOTIFY) + fi +fi + +dnl ********************************************************************* dnl ** SPELL ************************************************************ dnl ********************************************************************* if test "$spell" = "gtkspell" ; then PKG_CHECK_MODULES(GTKSPELL, gtkspell-2.0 >= 2.0.2, [], [ AC_MSG_RESULT(no) spell=no ]) @@ -519,16 +540,17 @@ if test "$spell" = "static" ; then fi dnl ********************************************************************* dnl ** CONDITIONALS ***************************************************** dnl ********************************************************************* AM_CONDITIONAL(USE_OPENSSL, test "x$openssl" = "xyes") AM_CONDITIONAL(USE_LIBSEXY, test "x$spell" = "xstatic") +AM_CONDITIONAL(USE_LIBNOTIFY, test "x$libnotify" = "xyes") AM_CONDITIONAL(DO_TEXT, test "x$textfe" = "xyes") AM_CONDITIONAL(DO_GTK, test "x$gtkfe" = "xyes") AM_CONDITIONAL(DO_PERL, test "x$perl" = "xyes") AM_CONDITIONAL(DO_PYTHON, test "x$python" = "xyes") AM_CONDITIONAL(DO_TCL, test "x$tcl" = "xyes") AM_CONDITIONAL(DO_PLUGIN, test "x$plugin" = "xyes") AM_CONDITIONAL(USE_DBUS, test "x$dbus" = "xyes") AM_CONDITIONAL(DO_GCONF, test "x$GCONFTOOL" != "xno") @@ -807,16 +829,17 @@ echo mmx tinting ......... : $mmx\ spell echo XShm tinting ........ : $shm\ plugin interface ...... : $plugin if test "$xft" = no; then echo text backend ........ : pango\ nls/gettext ........... : $USE_NLS else echo text backend ........ : xft\ nls/gettext ........... : $USE_NLS fi echo openssl support ..... : $openssl\ ipv6 support .......... : $ipv6 echo dbus support ........ : $dbus\ msproxy ntlm \(ISA\) .... : $have_ntlm +echo libnotify support ... : $libnotify echo echo The binary will be installed in $prefix/bin echo if test "$gtkfe" = no; then echo Warning: The GTK \(GUI\) frontend will not be built. echo fi diff -p -U8 xchat-2.8.8/src/fe-gtk/plugin-tray.c.libnotifyso4 xchat-2.8.8/src/fe-gtk/plugin-tray.c --- xchat-2.8.8/src/fe-gtk/plugin-tray.c.libnotifyso4 2011-04-07 17:57:27.524307905 -0700 +++ xchat-2.8.8/src/fe-gtk/plugin-tray.c 2011-04-07 19:18:33.429475719 -0700 @@ -10,17 +10,27 @@ #include "../common/fe.h" #include "../common/util.h" #include "fe-gtk.h" #include "pixmaps.h" #include "maingui.h" #include "menu.h" #include <gtk/gtk.h> -#define LIBNOTIFY +#ifdef USE_LIBNOTIFY +#include <libnotify/notify.h> +#ifndef NOTIFY_CHECK_VERSION +#define NOTIFY_CHECK_VERSION(x,y,z) 0 +#endif +#if NOTIFY_CHECK_VERSION(0,7,0) +#define XC_NOTIFY_NEW(a,b,c,d) notify_notification_new(a,b,c) +#else +#define XC_NOTIFY_NEW(a,b,c,d) notify_notification_new(a,b,c,d) +#endif +#endif typedef enum /* current icon status */ { TS_NONE, TS_MESSAGE, TS_HIGHLIGHT, TS_FILEOFFER, TS_CUSTOM /* plugin */ @@ -112,90 +122,16 @@ tray_count_networks (void) void fe_tray_set_tooltip (const char *text) { if (sticon) gtk_status_icon_set_tooltip (sticon, text); } -#ifdef LIBNOTIFY - -/* dynamic access to libnotify.so */ - -static void *nn_mod = NULL; -/* prototypes */ -static gboolean (*nn_init) (char *); -static void (*nn_uninit) (void); -/* recent versions of libnotify don't take the fourth GtkWidget argument, but passing an - * extra NULL argument will be fine */ -static void *(*nn_new) (const gchar *summary, const gchar *message, const gchar *icon, gpointer dummy); -static gboolean (*nn_show) (void *noti, GError **error); -static void (*nn_set_timeout) (void *noti, gint timeout); - -static void -libnotify_cleanup (void) -{ - if (nn_mod) - { - nn_uninit (); - g_module_close (nn_mod); - nn_mod = NULL; - } -} - -static gboolean -libnotify_notify_new (const char *title, const char *text, GtkStatusIcon *icon) -{ - void *noti; - - if (!nn_mod) - { - nn_mod = g_module_open ("libnotify", G_MODULE_BIND_LAZY); - if (!nn_mod) - { - nn_mod = g_module_open ("libnotify.so.1", G_MODULE_BIND_LAZY); - if (!nn_mod) - return FALSE; - } - - if (!g_module_symbol (nn_mod, "notify_init", (gpointer)&nn_init)) - goto bad; - if (!g_module_symbol (nn_mod, "notify_uninit", (gpointer)&nn_uninit)) - goto bad; - if (!g_module_symbol (nn_mod, "notify_notification_new", (gpointer)&nn_new)) - goto bad; - if (!g_module_symbol (nn_mod, "notify_notification_show", (gpointer)&nn_show)) - goto bad; - if (!g_module_symbol (nn_mod, "notify_notification_set_timeout", (gpointer)&nn_set_timeout)) - goto bad; - if (!nn_init (PACKAGE_NAME)) - goto bad; - } - - text = strip_color (text, -1, STRIP_ALL|STRIP_ESCMARKUP); - title = strip_color (title, -1, STRIP_ALL); - noti = nn_new (title, text, XCHATSHAREDIR"/pixmaps/xchat.png", NULL); - g_free ((char *)title); - g_free ((char *)text); - - nn_set_timeout (noti, prefs.input_balloon_time*1000); - nn_show (noti, NULL); - g_object_unref (G_OBJECT (noti)); - - return TRUE; - -bad: - g_module_close (nn_mod); - nn_mod = NULL; - return FALSE; -} - -#endif - void fe_tray_set_balloon (const char *title, const char *text) { #ifndef WIN32 const char *argv[8]; const char *path; char time[16]; WinStatus ws; @@ -208,52 +144,36 @@ fe_tray_set_balloon (const char *title, /* bit 1 of flags means "no balloons unless hidden/iconified" */ if (ws != WS_HIDDEN && (prefs.gui_tray_flags & 2)) return; /* FIXME: this should close the current balloon */ if (!text) return; -#ifdef LIBNOTIFY - /* try it via libnotify.so */ - if (libnotify_notify_new (title, text, sticon)) - return; /* success */ -#endif +#ifdef USE_LIBNOTIFY + NotifyNotification *notification; + char *notify_text, *notify_title; - /* try it the crude way */ - path = g_find_program_in_path ("notify-send"); - if (path) - { - sprintf(time, "%d000",prefs.input_balloon_time); - argv[0] = path; - argv[1] = "-i"; - argv[2] = "gtk-dialog-info"; - if (access (XCHATSHAREDIR"/pixmaps/xchat.png", R_OK) == 0) - argv[2] = XCHATSHAREDIR"/pixmaps/xchat.png"; - argv[3] = "-t"; - argv[4] = time; - argv[5] = title; - text = strip_color (text, -1, STRIP_ALL|STRIP_ESCMARKUP); - argv[6] = text; - argv[7] = NULL; - xchat_execv (argv); - g_free ((char *)path); - g_free ((char *)text); - } - else - { - /* show this error only once */ - static unsigned char said_it = FALSE; - if (!said_it) - { - said_it = TRUE; - fe_message (_("Cannot find 'notify-send' to open balloon alerts.\nPlease install libnotify."), FE_MSG_ERROR); - } - } + if (!notify_is_initted()) + notify_init(PACKAGE_NAME); + + notify_text = strip_color (text, -1, STRIP_ALL|STRIP_ESCMARKUP); + notify_title = strip_color (title, -1, STRIP_ALL); + + notification = XC_NOTIFY_NEW (notify_title, notify_text, XCHATSHAREDIR"/pixmaps/xchat.png", NULL); + + g_free ((char *)notify_title); + g_free ((char *)notify_text); + + notify_notification_set_timeout (notification, prefs.input_balloon_time*1000); + notify_notification_show (notification, NULL); + + g_object_unref (notification); +#endif #endif } static void tray_set_balloonf (const char *text, const char *format, ...) { va_list args; char *buf; @@ -840,13 +760,13 @@ tray_plugin_init (xchat_plugin *plugin_h return 1; /* return 1 for success */ } int tray_plugin_deinit (xchat_plugin *plugin_handle) { #ifdef WIN32 tray_cleanup (); -#elif defined(LIBNOTIFY) - libnotify_cleanup (); +#elif defined(USE_LIBNOTIFY) + notify_uninit (); #endif return 1; }