File: pl.c

package info (click to toggle)
cmus 2.7.1%2Bgit20160225-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,848 kB
  • sloc: ansic: 35,866; sh: 1,548; makefile: 260; python: 159
file content (145 lines) | stat: -rw-r--r-- 3,418 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Copyright 2008-2013 Various Authors
 * Copyright 2006 Timo Hirvonen
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include "pl.h"
#include "editable.h"
#include "options.h"
#include "xmalloc.h"

struct editable pl_editable;
struct simple_track *pl_cur_track = NULL;
struct rb_root pl_shuffle_root;

static void pl_free_track(struct list_head *item)
{
	struct simple_track *track = to_simple_track(item);
	struct shuffle_track *shuffle_track = (struct shuffle_track *) track;

	if (track == pl_cur_track)
		pl_cur_track = NULL;

	rb_erase(&shuffle_track->tree_node, &pl_shuffle_root);
	track_info_unref(track->info);
	free(track);
}

void pl_init(void)
{
	editable_init(&pl_editable, pl_free_track);
}

static int dummy_filter(const struct simple_track *track)
{
	return 1;
}

static struct track_info *set_track(struct simple_track *track)
{
	struct track_info *ti = NULL;

	if (track) {
		pl_cur_track = track;
		ti = track->info;
		track_info_ref(ti);
		if (follow)
			pl_sel_current();
		pl_editable.win->changed = 1;
	}
	return ti;
}

struct track_info *pl_goto_next(void)
{
	struct simple_track *track;

	if (list_empty(&pl_editable.head))
		return NULL;

	if (shuffle) {
		track = (struct simple_track *)shuffle_list_get_next(&pl_shuffle_root,
				(struct shuffle_track *)pl_cur_track, dummy_filter);
	} else {
		track = simple_list_get_next(&pl_editable.head, pl_cur_track, dummy_filter);
	}
	return set_track(track);
}

struct track_info *pl_goto_prev(void)
{
	struct simple_track *track;

	if (list_empty(&pl_editable.head))
		return NULL;

	if (shuffle) {
		track = (struct simple_track *)shuffle_list_get_prev(&pl_shuffle_root,
				(struct shuffle_track *)pl_cur_track, dummy_filter);
	} else {
		track = simple_list_get_prev(&pl_editable.head, pl_cur_track, dummy_filter);
	}
	return set_track(track);
}

struct track_info *pl_activate_selected(void)
{
	struct iter sel;

	if (list_empty(&pl_editable.head))
		return NULL;

	window_get_sel(pl_editable.win, &sel);
	return set_track(iter_to_simple_track(&sel));
}

void pl_sel_current(void)
{
	if (pl_cur_track) {
		struct iter iter;

		editable_track_to_iter(&pl_editable, pl_cur_track, &iter);
		window_set_sel(pl_editable.win, &iter);
	}
}

void pl_add_track(struct track_info *ti)
{
	struct shuffle_track *track = xnew(struct shuffle_track, 1);

	track_info_ref(ti);
	simple_track_init((struct simple_track *)track, ti);
	shuffle_list_add(track, &pl_shuffle_root);
	editable_add(&pl_editable, (struct simple_track *)track);
}

void pl_reshuffle(void)
{
	shuffle_list_reshuffle(&pl_shuffle_root);
}

int pl_for_each(int (*cb)(void *data, struct track_info *ti), void *data)
{
	struct simple_track *track;
	int rc = 0;

	list_for_each_entry(track, &pl_editable.head, node) {
		rc = cb(data, track->info);
		if (rc)
			break;
	}
	return rc;
}