~ubuntu-branches/ubuntu/jaunty/imms/jaunty

« back to all changes in this revision

Viewing changes to clients/xmms/plugin.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Veber
  • Date: 2005-04-13 23:43:11 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050413234311-kzr68z9l7z5mv551
Tags: 2.0.3-2
Build depend on xmms-dev (>= 1.2.10+cvs20050209)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      The XMMS plugin portion of IMMS
 
3
 */
 
4
 
 
5
#include <string>
 
6
#include <iostream>
 
7
#include <time.h>
 
8
 
 
9
#ifdef BMP
 
10
# include <bmp/plugin.h>
 
11
# include <bmp/beepctrl.h> 
 
12
#else
 
13
# include <xmms/plugin.h>
 
14
# include <xmms/xmmsctrl.h> 
 
15
#endif
 
16
 
 
17
 
 
18
#include "immsconf.h"
 
19
#include "cplugin.h"
 
20
#include "clientstub.h"
 
21
 
 
22
using std::string;
 
23
using std::cerr;
 
24
using std::endl;
 
25
 
 
26
#define POLL_DELAY          5
 
27
 
 
28
// Local vars
 
29
unsigned int time_left = 1000, sloppy_skips = 0;
 
30
int last_plpos = -2, cur_plpos, pl_length = -1;
 
31
int good_length = 0, song_length = 0, delay = 0, xidle_val = 0;
 
32
string cur_path = "", last_path = "";
 
33
 
 
34
// Extern from interface.c
 
35
extern GeneralPlugin imms_gp;
 
36
int &session = imms_gp.xmms_session;
 
37
 
 
38
static enum
 
39
{
 
40
    IDLE        = 0,
 
41
    BUSY        = 1,
 
42
    FIND_NEXT   = 2
 
43
} state;
 
44
 
 
45
// Wrapper that frees memory
 
46
string imms_get_playlist_item(int at)
 
47
{
 
48
    if (at > pl_length - 1)
 
49
        return "";
 
50
    char *tmp = 0;
 
51
    while (!tmp)
 
52
       tmp = xmms_remote_get_playlist_file(session, at);
 
53
    string result = tmp;
 
54
    free(tmp);
 
55
    return result;
 
56
}
 
57
 
 
58
struct FilterOps;
 
59
typedef IMMSClient<FilterOps> XMMSClient;
 
60
XMMSClient *imms = 0;
 
61
 
 
62
struct FilterOps
 
63
{
 
64
    static void set_next(int next)
 
65
    {
 
66
        cur_plpos = next;
 
67
 
 
68
        cur_path = imms_get_playlist_item(cur_plpos);
 
69
        xmms_remote_set_playlist_pos(session, cur_plpos);
 
70
 
 
71
        // notify imms of the next song
 
72
        if (imms)
 
73
            imms->start_song(cur_plpos, cur_path);
 
74
 
 
75
        last_path = cur_path;
 
76
        good_length = 0;
 
77
 
 
78
        xmms_remote_play(session);
 
79
    }
 
80
    static void reset_selection() {}
 
81
    static string get_item(int index)
 
82
    {
 
83
        return imms_get_playlist_item(index);
 
84
    }
 
85
    static int get_length()
 
86
    {
 
87
        return (int)xmms_remote_get_playlist_length(session);
 
88
    }
 
89
};
 
90
 
 
91
void imms_init()
 
92
{
 
93
    if (!imms)
 
94
        imms = new XMMSClient();
 
95
 
 
96
    state = IDLE;
 
97
}
 
98
 
 
99
void imms_setup(int use_xidle)
 
100
{
 
101
    xidle_val = use_xidle;
 
102
    if (imms)
 
103
        imms->setup(use_xidle);
 
104
}
 
105
 
 
106
void imms_cleanup(void)
 
107
{
 
108
    delete imms;
 
109
    imms = 0;
 
110
}
 
111
 
 
112
void do_more_checks()
 
113
{
 
114
    delay = 0;
 
115
 
 
116
    // make sure shuffle is disabled
 
117
    if (imms && xmms_remote_is_shuffle(session))
 
118
        xmms_remote_toggle_shuffle(session);
 
119
 
 
120
    // update playlist length
 
121
    int new_pl_length = xmms_remote_get_playlist_length(session);
 
122
    if (new_pl_length != pl_length)
 
123
    {
 
124
        pl_length = new_pl_length;
 
125
        imms->playlist_changed(pl_length);
 
126
    }
 
127
 
 
128
    // check if xmms is reporting the song length correctly
 
129
    song_length = xmms_remote_get_playlist_time(session, cur_plpos);
 
130
    if (song_length > 1000)
 
131
        good_length++;
 
132
}
 
133
 
 
134
void do_checks()
 
135
{
 
136
    if (imms->check_connection() || last_plpos == -2)
 
137
    {
 
138
        imms->setup(xidle_val);
 
139
        imms->playlist_changed(pl_length
 
140
                = xmms_remote_get_playlist_length(session));
 
141
        last_plpos = xmms_remote_get_playlist_pos(session);
 
142
        if (xmms_remote_is_playing(session))
 
143
        {
 
144
            cur_plpos = last_plpos;
 
145
            last_path = cur_path = imms_get_playlist_item(cur_plpos);
 
146
            imms->start_song(cur_plpos, cur_path);
 
147
        }
 
148
    }
 
149
 
 
150
    if (!xmms_remote_is_playing(session))
 
151
        return;
 
152
 
 
153
    // run these checks less frequently so as not to waste cpu time
 
154
    if (++delay > POLL_DELAY || pl_length < 0 || good_length < 3)
 
155
        do_more_checks();
 
156
 
 
157
    // do not preemptively end the song if imms is disabled 
 
158
    // to allow the built in shuffle/sequential to take effect
 
159
    bool ending = good_length > 2 && time_left == 0;
 
160
    cur_plpos = xmms_remote_get_playlist_pos(session);
 
161
 
 
162
    if (ending || cur_plpos != last_plpos)
 
163
    {
 
164
        cur_path = imms_get_playlist_item(cur_plpos);
 
165
 
 
166
        if (ending || last_path != cur_path)
 
167
        {
 
168
            xmms_remote_stop(session);
 
169
            state = FIND_NEXT;
 
170
            return;
 
171
        }
 
172
 
 
173
        last_plpos = cur_plpos;
 
174
    }
 
175
 
 
176
    // check the time to catch the end of the song
 
177
    int cur_time = xmms_remote_get_output_time(session);
 
178
    if (cur_time > 1000 || good_length < 3)
 
179
        time_left = (song_length - cur_time) / 500;
 
180
}
 
181
 
 
182
void do_find_next()
 
183
{
 
184
    if (time_left < 20)
 
185
        time_left = 0;
 
186
 
 
187
    cur_plpos = xmms_remote_get_playlist_pos(session);
 
188
    bool forced = (cur_plpos != last_plpos) && 
 
189
        ((last_plpos + 1) % pl_length) != cur_plpos;
 
190
    bool bad = good_length < 3 || song_length <= 30*1000;
 
191
 
 
192
    // notify imms that the previous song has ended
 
193
    if (last_path != "")
 
194
        imms->end_song(!time_left, forced, bad);
 
195
 
 
196
    if (!forced && pl_length > 2)
 
197
        imms->select_next();
 
198
    else
 
199
    {
 
200
        last_plpos = cur_plpos = xmms_remote_get_playlist_pos(session);
 
201
        last_path = cur_path = imms_get_playlist_item(cur_plpos);
 
202
        xmms_remote_play(session);
 
203
        imms->start_song(cur_plpos, cur_path);
 
204
    }
 
205
}
 
206
 
 
207
void imms_poll()
 
208
{
 
209
    switch (state)
 
210
    {
 
211
    case BUSY:
 
212
        return;
 
213
 
 
214
    case IDLE:
 
215
        state = BUSY;
 
216
        do_checks();
 
217
        if (state == BUSY)
 
218
            state = IDLE;
 
219
        return;
 
220
 
 
221
    case FIND_NEXT:
 
222
        state = BUSY;
 
223
        do_find_next();
 
224
        state = IDLE;
 
225
        return;
 
226
    }
 
227
}