⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playlist.c

📁 xmms-1.2.10.tar.gz学习使用的就下吧
💻 C
📖 第 1 页 / 共 3 页
字号:
		a_filename = strrchr(a->filename, '/') + 1;	else		a_filename = a->filename;	if (strrchr(b->filename,'/'))		b_filename = strrchr(b->filename, '/') + 1;	else		b_filename = b->filename;	return strcasecmp(a_filename, b_filename);}void playlist_sort_by_filename(void){	PL_LOCK();	playlist = g_list_sort(playlist, (GCompareFunc) playlist_sort_by_filename_cmpfunc);	PL_UNLOCK();}static int playlist_sort_str_by_path_cmpfunc(gconstpointer pa, gconstpointer pb){	const char *a = pa, *b = pb;	char *posa, *posb;	posa = strrchr(a, '/');	posb = strrchr(b, '/');	/*	 * Sort directories before files	 */	if (posa && posb && (posa - a != posb - b))	{		int len, ret;		if (posa - a > posb - b)		{			len = posb - b;			ret = -1;		}		else		{			len = posa - a;			ret = 1;		}		if (!strncasecmp(a, b, len))			return ret;	}	return strcasecmp(a, b);}static int playlist_sort_by_path_cmpfunc(PlaylistEntry * a, PlaylistEntry * b){	return playlist_sort_str_by_path_cmpfunc(a->filename, b->filename);}void playlist_sort_by_path(void){	PL_LOCK();	playlist = g_list_sort(playlist, (GCompareFunc) playlist_sort_by_path_cmpfunc);	PL_UNLOCK();}static int playlist_sort_by_date_cmpfunc(PlaylistEntry * a, PlaylistEntry * b){	struct stat buf;	time_t modtime;		if (!lstat(a->filename, &buf))	{		modtime = buf.st_mtime;		if (!lstat(b->filename, &buf))		{			if (buf.st_mtime == modtime)				return 0;			else				return (buf.st_mtime-modtime) > 0 ? -1 : 1;		}		else			return -1;	}	else if(!lstat(b->filename, &buf))		return 1;	else		return playlist_sort_by_filename_cmpfunc(a,b);}void playlist_sort_by_date(void){	PL_LOCK();	playlist = g_list_sort(playlist, (GCompareFunc) playlist_sort_by_date_cmpfunc);	PL_UNLOCK();}static GList* playlist_sort_selected(GList *list, GCompareFunc cmpfunc){	GList *list1, *list2;	GList *temp_list = NULL;	GList *index_list = NULL;	/*	 * We take all the selected entries out of the playlist,	 * sorts them, and then put them back in again.	 */	list1 = g_list_last(list);	while (list1)	{		list2 = g_list_previous(list1);		if (((PlaylistEntry *) list1->data)->selected)		{			gpointer idx;			idx = GINT_TO_POINTER(g_list_position(list, list1));			index_list = g_list_prepend(index_list, idx);			list = g_list_remove_link(list, list1);			temp_list = g_list_concat(list1, temp_list);		}		list1 = list2;	}	temp_list = g_list_sort(temp_list, cmpfunc);	list1 = temp_list;	list2 = index_list;	while (list2)	{		if (!list1)		{			g_log(NULL, G_LOG_LEVEL_CRITICAL,			      "%s: Error during list sorting. "			      "Possibly dropped some playlist-entries.",			      PACKAGE);			break;		}		list = g_list_insert(list, list1->data, GPOINTER_TO_INT(list2->data));		list2 = g_list_next(list2);		list1 = g_list_next(list1);	}	g_list_free(index_list);	g_list_free(temp_list);	return list;}void playlist_sort_selected_by_title(void){	PL_LOCK();		playlist = playlist_sort_selected(playlist, (GCompareFunc) playlist_sort_by_title_cmpfunc);	PL_UNLOCK();}void playlist_sort_selected_by_filename(void){	PL_LOCK();	playlist = playlist_sort_selected(playlist, (GCompareFunc) playlist_sort_by_filename_cmpfunc);	PL_UNLOCK();}void playlist_sort_selected_by_path(void){	PL_LOCK();	playlist = playlist_sort_selected(playlist, (GCompareFunc) playlist_sort_by_path_cmpfunc);	PL_UNLOCK();}void playlist_sort_selected_by_date(void){	PL_LOCK();	playlist = playlist_sort_selected(playlist, (GCompareFunc) playlist_sort_by_date_cmpfunc);	PL_UNLOCK();}void playlist_reverse(void){	PL_LOCK();	playlist = g_list_reverse(playlist);	PL_UNLOCK();}static GList *playlist_shuffle_list(GList *list){	/* Caller should hold playlist mutex */	/*	 * Note that this doesn't make a copy of the original list.	 * The pointer to the original list is not valid after this	 * fuction is run.	 */	int len = g_list_length(list);	int i, j;	GList *node, **ptrs;	if (!len)		return NULL;	ptrs = g_new(GList *, len);	for (node = list, i = 0; i < len; node = g_list_next(node), i++)		ptrs[i] = node;	j = random() % len;	list = ptrs[j];	ptrs[j]->next = NULL;	ptrs[j] = ptrs[0];	for (i = 1; i < len; i++)	{		j = random() % (len - i);		list->prev = ptrs[i + j];		ptrs[i + j]->next = list;		list = ptrs[i + j];		ptrs[i + j] = ptrs[i];	}	list->prev = NULL;	g_free(ptrs);	return list;}void playlist_random(void){	PL_LOCK();	playlist = playlist_shuffle_list(playlist);	PL_UNLOCK();}GList * playlist_get_selected(void){	GList *node, *list = NULL;	int i = 0;	PL_LOCK();	for (node = get_playlist(); node != 0; node = g_list_next(node), i++)	{		PlaylistEntry *entry = node->data;		if (entry->selected)			list = g_list_prepend(list, GINT_TO_POINTER(i));	}	PL_UNLOCK();	return g_list_reverse(list);}int playlist_get_num_selected(void){	GList *node;	int num = 0;	PL_LOCK();	for (node = get_playlist(); node != 0; node = g_list_next(node))	{		PlaylistEntry *entry = node->data;		if (entry->selected)			num++;	}	PL_UNLOCK();	return num;}	static void playlist_generate_shuffle_list(void){	PL_LOCK();	__playlist_generate_shuffle_list();	PL_UNLOCK();}static void __playlist_generate_shuffle_list(void){	/* Caller should hold playlist mutex */	GList *node;	int numsongs;	if (shuffle_list)	{		g_list_free(shuffle_list);		shuffle_list = NULL;	}	if (!cfg.shuffle || !playlist)		return;		shuffle_list = playlist_shuffle_list(g_list_copy(playlist));	numsongs = g_list_length(shuffle_list);	if (playlist_position)	{		int i = g_list_index(shuffle_list, playlist_position);		node = g_list_nth(shuffle_list, i);		shuffle_list = g_list_remove_link(shuffle_list, node);		shuffle_list = g_list_prepend(shuffle_list, node->data);	}}void playlist_fileinfo(int pos){	char *path = NULL;	GList *node;		PL_LOCK();	if ((node = g_list_nth(get_playlist(), pos)) != NULL)	{		PlaylistEntry *entry = node->data;		path = g_strdup(entry->filename);	}	PL_UNLOCK();	if (path)	{		input_file_info_box(path);		g_free(path);	}}void playlist_fileinfo_current(void){	char *path = NULL;	PL_LOCK();		if (get_playlist() && playlist_position)		path = g_strdup(playlist_position->filename);	PL_UNLOCK();	if (path)	{		input_file_info_box(path);		g_free(path);	}}static gboolean playlist_get_info_entry(PlaylistEntry *entry){	/*	 * Caller need to hold playlist mutex.	 * Note that this function temporarily drops the playlist mutex.	 * If it returns false, the entry might no longer be valid.	 */	char *temp_filename, *temp_title;	int temp_length;	temp_filename = g_strdup(entry->filename);	temp_title = NULL;	temp_length = -1;	/* We don't want to lock the playlist while reading info */	PL_UNLOCK();	input_get_song_info(temp_filename, &temp_title, &temp_length);	PL_LOCK();	g_free(temp_filename);	if (!temp_title && temp_length == -1)		return FALSE;	/* Make sure entry is still around */	if (g_list_index(get_playlist(), entry) == -1)		return FALSE;	/* entry is still around */	entry->title = temp_title;	entry->length = temp_length;	return TRUE;}static void *playlist_get_info_func(void *arg){	GList *node;	gboolean update_playlistwin = FALSE, update_mainwin = FALSE;	PlaylistEntry *entry;	while (playlist_get_info_going)	{		if (cfg.get_info_on_load && playlist_get_info_scan_active)		{			PL_LOCK();			for (node = get_playlist(); node; node = g_list_next(node))			{				entry = node->data;				if (entry->title || entry->length != -1)					continue;				if (!playlist_get_info_entry(entry))				{					if (g_list_index(get_playlist(), entry) == -1)						/* Entry disapeared while we						   looked it up.  Restart. */						node = get_playlist();				}				else if (entry->title || entry->length != -1)				{					update_playlistwin = TRUE;					if (entry == playlist_position)						update_mainwin = TRUE;					break;				}			}			PL_UNLOCK();			if (!node)				playlist_get_info_scan_active = FALSE;		}		else if (!cfg.get_info_on_load && cfg.get_info_on_demand &&			 cfg.playlist_visible && !cfg.playlist_shaded)		{			gboolean found = FALSE;			PL_LOCK();			if (!get_playlist())			{				PL_UNLOCK();				xmms_usleep(1000000);				continue;			}						for (node = g_list_nth(get_playlist(), playlistwin_get_toprow());			     node && playlistwin_item_visible(g_list_position(get_playlist(), node));			     node = g_list_next(node))			{				entry = node->data;				if (entry->title || entry->length != -1)					continue;				if (!playlist_get_info_entry(entry))				{					if (g_list_index(get_playlist(), entry) == -1)						/* Entry disapeared while we						   looked it up.  Restart. */						node = g_list_nth(get_playlist(), playlistwin_get_toprow());				}				else if (entry->title || entry->length != -1)				{					update_playlistwin = TRUE;					if (entry == playlist_position)						update_mainwin = TRUE;					found = TRUE;					break;				}			}			PL_UNLOCK();			if (!found)			{				xmms_usleep(500000);				continue;			}		}		else			xmms_usleep(500000);		if (update_playlistwin)		{			playlistwin_update_list();			update_playlistwin = FALSE;		}		if (update_mainwin)		{			mainwin_set_info_text();			update_mainwin = FALSE;		}	}	pthread_exit(NULL);}void playlist_start_get_info_thread(void){	playlist_get_info_going = TRUE;	pthread_create(&playlist_get_info_thread, NULL,		       playlist_get_info_func, NULL);}void playlist_stop_get_info_thread(void){	playlist_get_info_going = FALSE;	pthread_join(playlist_get_info_thread, NULL);}void playlist_start_get_info_scan(void){	playlist_get_info_scan_active = TRUE;}void playlist_remove_dead_files(void){	/* FIXME? Does virtual directories work well? */	GList *node, *next_node, *curr_pos = NULL, *temp = NULL;	PlaylistEntry *entry;	gboolean list_changed = FALSE;		PL_LOCK();	node = playlist;	while (node)	{		/* A dead file is a file that is not readable. */		next_node = g_list_next(node);		entry = node->data;		if (entry && entry->filename &&		    !strstr(entry->filename, "://") && /* Don't kill URL's */		    ((temp = input_scan_dir(entry->filename)) == NULL) &&		    access(entry->filename, R_OK))		{			list_changed = TRUE;			if (playlist_position)				curr_pos = g_list_find(playlist, playlist_position);			if (node == curr_pos)			{				if (get_input_playing())				{					/* Don't remove the currently					   playing song */					node = next_node;					continue;				}				if (g_list_next(curr_pos))					playlist_position = curr_pos->next->data;				else if (g_list_previous(curr_pos))					playlist_position = curr_pos->prev->data;				else if (node != playlist)					playlist_position = playlist->data;				else					playlist_position = NULL;			}			playlist = g_list_remove_link(playlist, node);			g_free(entry->title);			g_free(entry->filename);			g_free(node->data);			g_list_free_1(node);		}		else if (temp)		{			g_list_free(temp);			temp = NULL;		}		node = next_node;	}	PL_UNLOCK();	if (list_changed)	{		playlist_generate_shuffle_list();		playlistwin_update_list();	}}void playlist_get_total_time(gulong *total_time, gulong *selection_time, gboolean *total_more, gboolean *selection_more){	GList *list;	PlaylistEntry *entry;		*total_time = 0;	*selection_time = 0;	*total_more = FALSE;	*selection_more = FALSE;		PL_LOCK();	list = get_playlist();	while (list)	{		entry = list->data;		if (entry->length != -1)			*total_time += entry->length / 1000;		else			*total_more = TRUE;		if (entry->selected)		{			if (entry->length != -1)				*selection_time += entry->length / 1000;			else				*selection_more = TRUE;		}		list = g_list_next(list);	}	PL_UNLOCK();}void playlist_select_all(gboolean set){	GList *list;		PL_LOCK();	list = get_playlist();	while (list)	{		PlaylistEntry *entry = list->data;		entry->selected = set;		list = list->next;	}	PL_UNLOCK();}void playlist_select_invert_all(void){	GList *list;		PL_LOCK();	list = get_playlist();	while (list)	{		PlaylistEntry *entry = list->data;		entry->selected = !entry->selected;		list = list->next;	}	PL_UNLOCK();}gboolean playlist_select_invert(int num){	GList *list;	gboolean retv = FALSE;	PL_LOCK();	if ((list = g_list_nth(get_playlist(), num)) != NULL)	{		PlaylistEntry *entry = list->data;		entry->selected = !entry->selected;		retv = TRUE;	}	PL_UNLOCK();	return retv;}	void playlist_select_range(int min, int max, gboolean sel){	GList *list;	int i;	if (min > max)	{		int tmp = min;		min = max;		max = tmp;	}	PL_LOCK();	list = g_list_nth(get_playlist(), min);	for (i = min; i <= max && list; i++)	{		PlaylistEntry *entry = list->data;		entry->selected = sel;		list = list->next;	}	PL_UNLOCK();}gboolean playlist_read_info_selection(void){	GList *node;	gboolean retval = FALSE;	PL_LOCK();	for (node = get_playlist(); node; node = node->next)	{		PlaylistEntry *entry = node->data;		if (entry->selected)		{			retval = TRUE;			if (entry->title)				g_free(entry->title);			entry->title = NULL;			entry->length = -1;			if (!playlist_get_info_entry(entry))			{				if (g_list_index(get_playlist(), entry) == -1)					/* Entry disapeared while we					   looked it up.  Restart. */					node = get_playlist();			}		}	}	PL_UNLOCK();	playlistwin_update_list();	return retval;}void playlist_read_info(int pos){	GList *node;	PL_LOCK();	if ((node = g_list_nth(get_playlist(), pos)) != NULL)	{		PlaylistEntry *entry = node->data;		if (entry->title)			g_free(entry->title);		entry->title = NULL;		entry->length = -1;		playlist_get_info_entry(entry);	}	PL_UNLOCK();	playlistwin_update_list();}void playlist_set_shuffle(gboolean shuffle){	PL_LOCK();	cfg.shuffle = shuffle;	__playlist_generate_shuffle_list();	PL_UNLOCK();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -