Project

General

Profile

notifyactionsupport.patch

Jean-Alexandre Anglès d'Auriac, April 14, 2013 00:19

View differences:

src/notify/event.c
21 21
#include <audacious/drct.h>
22 22
#include <audacious/i18n.h>
23 23
#include <audacious/playlist.h>
24
#include <audacious/misc.h>
24 25
#include <libaudcore/hook.h>
25 26
#include <libaudgui/libaudgui-gtk.h>
26 27

  
28
#include "config.h"
27 29
#include "event.h"
28 30
#include "osd.h"
29 31

  
32

  
30 33
static char * last_title = NULL, * last_message = NULL; /* pooled */
31 34

  
32 35
static void clear (void)
......
37 40
    last_message = NULL;
38 41
}
39 42

  
40
static void reshow (void)
43
static void update_button (void * unused, void * useless)
41 44
{
42
    if (! last_title || ! last_message)
43
        return;
44

  
45
    GdkPixbuf * pb = audgui_pixbuf_request_current ();
46
    if (pb)
47
        audgui_pixbuf_scale_within (& pb, 96);
48

  
49
    osd_show (last_title, last_message, "audio-x-generic", pb);
50

  
51
    if (pb)
52
        g_object_unref (pb);
45
    osd_refresh ();
53 46
}
54 47

  
55
static void update (void * unused, void * explicit)
48

  
49
static void update (void * unused, void * forcedisplay)
56 50
{
57 51
    if (! aud_drct_get_playing () || ! aud_drct_get_ready ())
58 52
    {
59
        if (GPOINTER_TO_INT (explicit))
60
            osd_show (_("Stopped"), _("Audacious is not playing."), NULL, NULL);
61

  
62 53
        return;
63 54
    }
64 55

  
......
85 76
    str_unref (album);
86 77

  
87 78
    /* pointer comparison works for pooled strings */
88
    if (! GPOINTER_TO_INT (explicit) && title == last_title && message == last_message)
79
    if (title == last_title && message == last_message && !GPOINTER_TO_INT (forcedisplay))
89 80
    {
90 81
        str_unref (title);
91 82
        str_unref (message);
......
97 88
    str_unref (last_message);
98 89
    last_message = message;
99 90

  
100
    reshow ();
91
    GdkPixbuf *pixbuf = audgui_pixbuf_request_current();
92

  
93
    if (pixbuf)
94
        audgui_pixbuf_scale_within (& pixbuf, 96);
95

  
96
    osd_show (title, message, pixbuf);
97

  
98
    if (pixbuf)
99
        g_object_unref (pixbuf);
100
}
101

  
102
static void update_explicit (void * unused, void * useless)
103
{
104
    if (! aud_drct_get_playing () || ! aud_drct_get_ready ())
105
        osd_show (_("Stopped"), _("Audacious is not playing."), NULL);
106
    else
107
        update(unused, GINT_TO_POINTER (TRUE));
108
    return;
101 109
}
102 110

  
103
void event_init (void)
111
void event_init ()
104 112
{
105
    update (NULL, GINT_TO_POINTER (FALSE));
106
    hook_associate ("aosd toggle", (HookFunction) update, GINT_TO_POINTER (TRUE));
107
    hook_associate ("playback ready", (HookFunction) update, GINT_TO_POINTER (FALSE));
108
    hook_associate ("playlist update", (HookFunction) update, GINT_TO_POINTER (FALSE));
109
    hook_associate ("current art ready", (HookFunction) reshow, NULL);
113
    hook_associate ("aosd toggle", (HookFunction) update_explicit, NULL);
114
    hook_associate ("playback ready", (HookFunction) update, NULL);
115
    hook_associate ("playlist update", (HookFunction) update, NULL);
116
    hook_associate ("current art ready", (HookFunction) update, GINT_TO_POINTER (TRUE));
117
    hook_associate ("playback pause", (HookFunction) update_button, NULL);
118
    hook_associate ("playback unpause", (HookFunction) update_button, NULL);
119
    hook_associate ("playback begin", (HookFunction) update_button, NULL);
120
    hook_associate ("playback stop", (HookFunction) update_button, NULL);
110 121
    hook_associate ("playback begin", (HookFunction) clear, NULL);
111 122
    hook_associate ("playback stop", (HookFunction) clear, NULL);
112 123
}
113 124

  
114 125
void event_uninit (void)
115 126
{
116
    hook_dissociate ("aosd toggle", (HookFunction) update);
127
    hook_dissociate ("aosd toggle", (HookFunction) update_explicit);
117 128
    hook_dissociate ("playback ready", (HookFunction) update);
118 129
    hook_dissociate ("playlist update", (HookFunction) update);
119
    hook_dissociate ("current art ready", (HookFunction) reshow);
130
    hook_dissociate ("current art ready", (HookFunction) update);
131
    hook_dissociate ("playback pause", (HookFunction) update_button);
132
    hook_dissociate ("playback unpause", (HookFunction) update_button);
133
    hook_dissociate ("playback begin", (HookFunction) update_button);
134
    hook_dissociate ("playback stop", (HookFunction) update_button);
120 135
    hook_dissociate ("playback begin", (HookFunction) clear);
121 136
    hook_dissociate ("playback stop", (HookFunction) clear);
122 137
    clear ();
src/notify/event.h
17 17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 18
 */
19 19

  
20
void event_init (void);
20
void event_init ();
21 21
void event_uninit (void);
src/notify/notify.c
23 23
#include <audacious/i18n.h>
24 24
#include <audacious/plugin.h>
25 25
#include <audacious/debug.h>
26
#include <audacious/preferences.h>
27
#include <audacious/misc.h>
26 28

  
29
#include "config.h"
27 30
#include "event.h"
28 31
#include "osd.h"
29 32

  
......
46 49
    "You should have received a copy of the GNU General Public License "
47 50
    "along with this program.  If not, see <http://www.gnu.org/licenses/>.");
48 51

  
52
static const char * const notify_defaults[] = {
53
 "actions", "TRUE",
54
 NULL};
55

  
56

  
57
static const PreferencesWidget notify_widgets[] = {
58
 {WIDGET_CHK_BTN, N_("Activate controls inside of the notification"),
59
 .cfg_type = VALUE_BOOLEAN, .csect = "notify", .cname = "actions"},
60
};
61

  
62
static const PluginPreferences notify_prefs = {
63
 .widgets = notify_widgets,
64
 .n_widgets = G_N_ELEMENTS (notify_widgets)
65
};
66

  
67

  
68

  
49 69
AUD_GENERAL_PLUGIN
50 70
(
51 71
    .name = N_("Desktop Notifications"),
52 72
    .domain = PACKAGE,
53 73
    .about_text = plugin_about,
54 74
    .init = plugin_init,
75
    .prefs = & notify_prefs,
55 76
    .cleanup = plugin_cleanup
56 77
)
57 78

  
......
59 80

  
60 81
gboolean plugin_init (void)
61 82
{
62
    AUDDBG("started!\n");
63
    if(!osd_init()) {
64
        AUDDBG("osd_init failed!\n");
65
        return FALSE;
66
    }
83
    aud_config_set_defaults ("notify", notify_defaults);
84
    osd_init();
67 85
    event_init();
68

  
69 86
    plugin_active = 1;
87
    AUDDBG("Osd plugin initted\n");
70 88
    return TRUE;
71 89
}
72 90

  
73 91

  
74 92
void plugin_cleanup() {
75 93
    if(plugin_active) {
76
        AUDDBG("started!\n");
77 94
        event_uninit();
78 95
        osd_uninit();
79 96
        plugin_active = 0;
80
        AUDDBG("done!\n");
97
        AUDDBG("Osd plugin uninitted\n");
81 98
    }
82 99
}
src/notify/osd.c
17 17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 18
 */
19 19

  
20
#include <libaudcore/core.h>
21
#include <libaudcore/hook.h>
22
#include <audacious/debug.h>
23
#include <audacious/i18n.h>
24
#include <audacious/drct.h>
25
#include <audacious/misc.h>
26
#include <libnotify/notify.h>
20 27
#include "osd.h"
21 28

  
22
static NotifyNotification * notification = NULL;
29
static NotifyNotification *notification = NULL;
30
static gboolean actions_available = FALSE;
31
static gboolean resident_notification = FALSE;
23 32

  
24
bool_t osd_init()
25
{
26
    return notify_init ("Audacious");
33
void osd_init() {
34
    if (notify_is_initted())
35
    {
36
        AUDDBG("Notify is already initted, that shouldn't happen\n");
37
        return;
38
    }
39
    if (notify_init("Audacious"))
40
    {
41
        notification = notify_notification_new("Notification", NULL, NULL);
42

  
43
        notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
44
        notify_notification_set_hint (notification, "desktop-entry", g_variant_new_string ("audacious"));
45
        notify_notification_set_category (notification, "x-gnome.music");
46

  
47
        GList *server_caps;
48
        server_caps = notify_get_server_caps ();
49

  
50
        if (g_list_find_custom (server_caps, "actions", (GCompareFunc)g_strcmp0) && aud_get_bool ("notify", "actions"))
51
        {
52
            actions_available = TRUE;
53
            if (g_list_find_custom (server_caps, "action-icons", (GCompareFunc)g_strcmp0))
54
                notify_notification_set_hint (notification, "action-icons", g_variant_new_boolean (TRUE));
55
            if (g_list_find_custom (server_caps, "persistence", (GCompareFunc)g_strcmp0) )
56
            {
57
                AUDDBG("Notification server supports persistence\n");
58
                resident_notification = TRUE;
59
                notify_notification_set_hint (notification, "resident", g_variant_new_boolean (TRUE));
60
            }
61
        }
62
        else
63
        {
64
            AUDDBG("Notification server doesn't supports persistence\n");
65
        }
66
        g_list_free_full(server_caps, g_free);
67
    }
68
    return;
27 69
}
28 70

  
29 71
void osd_uninit (void)
30 72
{
31 73
    if (notification)
32 74
    {
75
        GError *error = NULL;
76
        if (notify_notification_close (notification, &error) == FALSE)
77
            AUDDBG("%s!\n", error->message);
78
        if(error)
79
            g_error_free(error);
33 80
        g_object_unref (notification);
34 81
        notification = NULL;
35 82
    }
36 83

  
37 84
    notify_uninit();
85
    AUDDBG("Notify uninitted\n");
38 86
}
39 87

  
40
static void osd_closed_handler (void)
88

  
89
void goprevious (NotifyNotification *notification,
90
            const char *action,
91
            gpointer user_data)
41 92
{
42
    if (notification)
43
    {
44
        g_object_unref (notification);
45
        notification = NULL;
46
    }
93
    aud_drct_pl_prev();
47 94
}
48 95

  
49
void osd_show (const char * title, const char * _message, const char * icon,
50
 GdkPixbuf * pixbuf)
96
void gonext (NotifyNotification *notification,
97
        const char *action,
98
        gpointer user_data)
51 99
{
52
    char * message = g_markup_escape_text (_message, -1);
100
    aud_drct_pl_next();
101
}
53 102

  
54
    if (pixbuf)
55
        icon = NULL;
103
void show_audacious (NotifyNotification *notification,
104
        const char *action,
105
        gpointer user_data)
106
{
107
    aud_interface_show(TRUE);
108
}
56 109

  
57
    if (notification)
58
        notify_notification_update (notification, title, message, icon);
110
void playpause (NotifyNotification *notification,
111
           const char *action,
112
           gpointer user_data)
113
{
114
    if(aud_drct_get_playing())
115
    {aud_drct_pause();}
59 116
    else
117
    {aud_drct_play();}
118
}
119

  
120
void osd_update_button(void){
121
    if(actions_available){
122
        gboolean paused = TRUE;
123
        if (aud_drct_get_playing()) {paused = aud_drct_get_paused();}
124

  
125
        notify_notification_clear_actions (notification);
126

  
127
        notify_notification_add_action (notification,
128
                    "media-skip-backward",
129
                    N_("Previous"),
130
                    NOTIFY_ACTION_CALLBACK(goprevious),
131
                    NULL,
132
                    NULL);
133

  
134
        notify_notification_add_action (notification,
135
                    paused ? "media-playback-start" : "media-playback-pause",
136
                    paused ? N_("Play") : N_("Pause"),
137
                    NOTIFY_ACTION_CALLBACK(playpause),
138
                    NULL,
139
                    NULL);
140

  
141
        notify_notification_add_action (notification,
142
                    "media-skip-forward",
143
                    N_("Next"),
144
                    NOTIFY_ACTION_CALLBACK(gonext),
145
                    NULL,
146
                    NULL);
147

  
148
        notify_notification_add_action (notification,
149
                    "default",
150
                    N_("Show Audacious"),
151
                    NOTIFY_ACTION_CALLBACK(show_audacious),
152
                    NULL,
153
                    NULL);
154
    }
155
}
156

  
157
void osd_refresh(void){
158
    osd_update_button();
159
    if(resident_notification)
60 160
    {
61
        notification = notify_notification_new (title, message, icon);
62
        g_signal_connect (notification, "closed", (GCallback) osd_closed_handler, NULL);
161
        GError *error = NULL;
162
        if(!notify_notification_show(notification, &error))
163
            AUDDBG("Error “%s” when trying to send notification\n", error->message);
164
        if(error)
165
            g_error_free(error);
63 166
    }
167
}
168

  
169
void osd_show (const gchar * title, const gchar * _message, GdkPixbuf *cover)
170
{
171
    gchar * message = g_markup_escape_text (_message, -1);
172
    GError *error = NULL;
173

  
174
    if(cover)
175
        notify_notification_set_image_from_pixbuf(notification, cover);
176

  
177
    osd_update_button();
64 178

  
65
    if (pixbuf)
66
        notify_notification_set_icon_from_pixbuf (notification, pixbuf);
179
    if(!notify_notification_update(notification, title, message, "audacious"))
180
         AUDDBG("Could not update osd!\n");
67 181

  
68
    notify_notification_show (notification, NULL);
182
    if(!notify_notification_show(notification, &error))
183
        AUDDBG("Error “%s” when trying to send notification\n", error->message);
184
    if(error)
185
        g_error_free(error);
69 186

  
70 187
    g_free (message);
71 188
}
src/notify/osd.h
17 17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 18
 */
19 19

  
20
#include <libaudcore/core.h>
21
#include <libnotify/notify.h>
22

  
23
bool_t osd_init (void);
24
void osd_uninit (void);
25
void osd_show (const char * title, const char * message, const char * icon, GdkPixbuf * pixbuf);
20
void osd_init();
21
void osd_uninit();
22
void osd_show(const gchar *title, const gchar *message, GdkPixbuf *pixbuf);
23
void osd_refresh(void);