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

📄 playlist.c

📁 avi player 使用Linux下 GDK,GTK
💻 C
字号:
/***  Sinek (Media Player)**  Copyright (c) 2001-2002 Gurer Ozen****  This code is free software; you can redistribute it and/or**  modify it under the terms of the GNU General Public License.****  playlist*/#include "common.h"enum{	COL_MRL,	COL_ITEM,	N_COLS};static gint nr_items;static GtkWidget *list_view;static GtkListStore *list_store;static GtkTreeSelection *list_select;static GtkTreeRowReference *cur_item;typedef struct pl_item_struct{	char *mrl;	int time;	int format;} pl_item;static void pl_remove(pl_item *item);void pl_sort_by_name(void);void pl_sort_shuffle(void);void pl_sort_reverse(void);static void cb_load(GtkWidget *w, gpointer data);static void cb_save(GtkWidget *w, int to_default);static void cb_play(GtkWidget *w, gpointer data);static void cb_add(GtkWidget *w, gpointer data);static void cb_remove(GtkWidget *w, gpointer data);void pl_load(char *fname);#define BUTTON(title,sigfunc,data) \	but = gtk_button_new_with_label(title); \	gtk_widget_show(but); \	gtk_box_pack_start(GTK_BOX(hb), but, TRUE, TRUE, 4); \	g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(sigfunc), (gpointer)data)static void cb_menu(GtkWidget *widget, guint action){	if(sinek.signal_fake) return;	execute_cmd((cmd_type)action);}static void find_m3u(gpointer data, gpointer user_data){	char *t;		t = strrchr((char *) data, '.');	if(t && strcasecmp(t, ".m3u") == 0)	{		char **fname = (char **) user_data;		if(*fname)			g_free(*fname);		*fname = g_strdup((char *) data);	}}int pl_init(void){	gchar *fname = NULL;	sinek.repeat_all = media->conf->register_bool(media->conf, "sinek.repeat_all", -1, NULL, NULL, NULL, NULL);	wm_build(pl_build);	g_list_foreach(sinek.start_mrls, find_m3u, &fname);	if(!fname && !sinek.start_mrls)		fname = g_strconcat(g_get_home_dir(), "/.xine/playlist.xml", NULL);	if(fname)	{		pl_load(fname);		g_list_foreach(sinek.start_mrls, (GFunc) g_free, NULL);		g_list_free(sinek.start_mrls);		sinek.start_mrls = NULL;		g_free(fname);	}	return 1;}gboolean play_item(GtkTreeIter *iter, pl_item *item, gboolean can_remove){	GtkTreePath *path;	if(video_play(item->mrl))	{		path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), iter);		if(cur_item) gtk_tree_row_reference_free(cur_item);		cur_item = gtk_tree_row_reference_new(GTK_TREE_MODEL(list_store), path);		gtk_tree_path_free(path);		return TRUE;	}	else if(can_remove)	{		gtk_list_store_remove(list_store, iter);		pl_remove(item);	}	return FALSE;}void pl_prev(void){	GtkTreePath *path;	GtkTreeIter iter;	pl_item *item;	if(!cur_item) return;	path = gtk_tree_row_reference_get_path(cur_item);	if(!path) return;	gtk_tree_path_prev(path);	if(gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path))	{		gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COL_ITEM, &item, -1);		play_item(&iter, item, TRUE);	}	gtk_tree_path_free(path);}void pl_next(void){	GtkTreePath *path = NULL;	GtkTreeIter iter;	pl_item *item;	if(cur_item) path = gtk_tree_row_reference_get_path(cur_item);	if(path)		gtk_tree_path_next(path);	else		path = gtk_tree_path_new_root();	while(nr_items)	{		if(FALSE == gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path))		{			if(sinek.repeat_all == 0) break;			if(path) gtk_tree_path_free(path);			path = gtk_tree_path_new_root();			continue;		}		gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COL_ITEM, &item, -1);		if(play_item(&iter, item, TRUE)) break;	}	gtk_tree_path_free(path);}char *pl_get_mrl(int row){	pl_item *item = NULL;	GtkTreeIter iter;	if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, row))		gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COL_ITEM, &item, -1);	if(item) return(item->mrl);	return NULL;}void pl_append(char *mrl){	pl_item *item;	GtkTreeIter iter;	if(!mrl || mrl[0] == 0) return;	item = malloc(sizeof(pl_item));	if(!item) return;	item->mrl = strdup(mrl);	gtk_list_store_append(list_store, &iter);	gtk_list_store_set(list_store, &iter, COL_ITEM, (gpointer)item, -1);	nr_items++;}static void pl_remove(pl_item *item){	free(item->mrl);	free(item);	nr_items--;}void pl_remove_all(void){	GtkTreeIter iter;	gboolean go;	pl_item *item;	go = gtk_tree_model_get_iter_root(GTK_TREE_MODEL(list_store), &iter);	while(go)	{		gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COL_ITEM, &item, -1);		pl_remove(item);		go = gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter);	}	gtk_list_store_clear(list_store);	nr_items = 0;}void pl_load_m3u(char *fname){	gchar buf[2048], *t, *path;	FILE *f;	f = fopen(fname, "r");	if(f)	{		while(fgets(buf, 2040, f))		{			strtok(buf, "\r\n");			if(buf[0] != '#')			{				while((t = strchr(buf, '\\')) != NULL)					*t = '/';				if(buf[0] != '/' && !strstr(buf, "://"))				{					path = g_strdup(fname);					t = strrchr(path, '/');					if(t)					{						*t = '\0';						t = g_strdup_printf("%s/%s", path, buf);						pl_append(t);						free(t);					}					else					{						pl_append(buf);					}				}				else				{					pl_append(buf);				}			}		}		fclose(f);	}}void pl_load(char *filename){	iks *x, *y;	char *mrl;	x = iks_load(filename);	if(!x || iks_strcmp(iks_name(x), "spl") != 0) return;	for(y = iks_child(x); y; y = iks_next(y))	{		if(iks_type(y) == IKS_TAG && iks_strcmp(iks_name(y), "media") == 0)		{			mrl = iks_cdata(iks_child(iks_find(y, "mrl")));			if(mrl) pl_append(mrl);		}	}	iks_delete(x);}void pl_save(char *filename){	iks *x, *y;	pl_item *item;	GtkTreeIter iter;	gboolean go;	x = iks_new("spl");	iks_insert_cdata(x, "\n", 1);	if(sinek.repeat_all)	{		iks_insert(x, "repeat");		iks_insert_cdata(x, "\n", 1);	}	go = gtk_tree_model_get_iter_root(GTK_TREE_MODEL(list_store), &iter);	while(go)	{		gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COL_ITEM, &item, -1);		y = iks_insert(x, "media");		iks_insert_cdata(y, "\n\t", 2);		iks_insert_cdata(iks_insert(y, "mrl"), item->mrl, -1);		iks_insert_cdata(y, "\n", 1);		iks_insert_cdata(x, "\n", 1);		go = gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter);	}	iks_save(filename, x);	iks_delete(x);}			static void cb_load(GtkWidget *w, gpointer data){	select_file(pl_load, _("Load playlist..."));}static void cb_save(GtkWidget *w, int to_default){	gchar *fname;	if(to_default)	{		fname = g_strconcat(g_get_home_dir(), "/.xine/playlist.xml", NULL);		pl_save(fname);		g_free(fname);	}	else		select_file(pl_save, _("Save playlist as..."));}static void cb_play_file(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gboolean *go){	pl_item *item;	if(*go)	{		gtk_tree_model_get(model, iter, COL_ITEM, &item, -1);		if(play_item(iter, item, FALSE)) *go = FALSE;	}}static void cb_play(GtkWidget *w, gpointer data){	gboolean go = TRUE;	gtk_tree_selection_selected_foreach(list_select, (GtkTreeSelectionForeachFunc)cb_play_file, &go);	if(go)	{		pl_item *item;		GtkTreeIter iter;		if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, 0))		{			gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COL_ITEM, &item, -1);			play_item(&iter, item, FALSE);		}	}}static gint cb_click(GtkWidget *w, GdkEventButton *ev, gpointer data){	if(ev->type == GDK_2BUTTON_PRESS)	{		gboolean go = TRUE;		gtk_tree_selection_selected_foreach(list_select, (GtkTreeSelectionForeachFunc)cb_play_file, &go);	}	return FALSE;}static void cb_add(GtkWidget *w, gpointer data){	file_request(TRUE);}static void cb_remove_file(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, int *nr){	pl_item *item;	gtk_tree_model_get(model, iter, COL_ITEM, &item, -1);	gtk_list_store_set(list_store, iter, COL_ITEM, NULL, -1);	pl_remove(item);	(*nr)++;}static void cb_remove(GtkWidget *w, gpointer data){	GtkTreeIter iter;	gboolean go;	pl_item *item;	int nr = 0;	gtk_tree_selection_selected_foreach(list_select, (GtkTreeSelectionForeachFunc)cb_remove_file, &nr);	if(nr == 0) return;	go = gtk_tree_model_get_iter_root(GTK_TREE_MODEL(list_store), &iter);	while(go && nr)	{		gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, COL_ITEM, &item, -1);		if(item)		{			go = gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter);		}		else		{			gtk_list_store_remove(list_store, &iter);			nr--;		}	}}static gint sort_func(pl_item **a, pl_item **b, gboolean reverse){	pl_item *item1 = *a;	pl_item *item2 = *b;	if(reverse)		return strcmp(g_basename(item2->mrl), g_basename(item1->mrl));	else		return strcmp(g_basename(item1->mrl), g_basename(item2->mrl));}void pl_sort_by_name(void){	sort_list(list_store, COL_ITEM, (GCompareDataFunc)sort_func, (gpointer)FALSE);}void pl_sort_reverse(void){	sort_list(list_store, COL_ITEM, (GCompareDataFunc)sort_func, (gpointer)TRUE);}void pl_sort_shuffle(void){	int *deal, *newdeal;	int len = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL);	int i, j;	GtkTreeIter iter1, iter2;	pl_item *a, *b;	if(len < 2) return;	deal = g_malloc0(sizeof(int) * len);	newdeal = g_malloc0(sizeof(int) * len);	for(i = 0; i < len; i++)		deal[i] = i;	for(i = 0; i < len; i++)	{		j = (((double)len - i) * rand()) / RAND_MAX;		newdeal[i] = deal[j];		if(j != (len - i - 1)) deal[j] = deal[len - i - 1];	}	for(i = 0; i < len; i++)	{		j = newdeal[i];		if(newdeal[j] != -1 && i != j)		{			gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter1, NULL, i);			gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter1, COL_ITEM, &a, -1);			gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter2, NULL, j);			gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter2, COL_ITEM, &b, -1);			gtk_list_store_set(list_store, &iter1, COL_ITEM, b, -1);			gtk_list_store_set(list_store, &iter2, COL_ITEM, a, -1);
		}		newdeal[i] = -1;	}	g_free(newdeal);	g_free(deal);}static void cb_render_mrl(GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data){	pl_item *item;	gtk_tree_model_get(model, iter, COL_ITEM, &item, -1);	g_object_set(cell, "text", g_basename(item->mrl), NULL);}int pl_build(GtkWidget **win){	GtkItemFactoryEntry menus[] =	{		{ _("/File"), NULL, NULL, 0, "<Branch>" },		{ _("/File/Open..."), NULL, cb_load, 0, "<StockItem>", GTK_STOCK_OPEN },		{ _("/File/Save as..."), NULL, cb_save, 0, "<StockItem>", GTK_STOCK_SAVE_AS },		{ _("/File/Save as Default"), NULL, cb_save, 1, NULL },		{ _("/Edit"), NULL, NULL, 0, "<Branch>" },		{ _("/Edit/Add..."), NULL, cb_add, 0, "<StockItem>", GTK_STOCK_ADD },		{ _("/Edit/Remove"), NULL, cb_remove, 0, "<StockItem>", GTK_STOCK_REMOVE },		{ _("/Edit/Clear"), NULL, pl_remove_all, 0, "<StockItem>", GTK_STOCK_CLEAR },		{ _("/Sort"), NULL, NULL, 0, "<Branch>" },		{ _("/Sort/By Name"), NULL, pl_sort_by_name, 0, NULL },		{ _("/Sort/Reverse"), NULL, pl_sort_reverse, 0, NULL },		{ _("/Sort/Shuffle"), NULL, pl_sort_shuffle, 0, NULL },		{ _("/Modes"), NULL, NULL, 0, "<Branch>" },		{ _("/Modes/Repeat"), NULL, cb_menu, CMD_TOGGLE_REPEAT_ALL, "<CheckItem>" }	};	GtkItemFactory *fabrika;	gint n = sizeof(menus) / sizeof(menus[0]);	GtkWidget *w, *vb, *menu, *sw, *hb, *but;	GtkCellRenderer *cell;	GtkTreeViewColumn *col;	w = gtk_window_new(GTK_WINDOW_TOPLEVEL);	gtk_window_set_title(GTK_WINDOW(w), _("Sinek Playlist"));	gtk_window_set_wmclass(GTK_WINDOW(w), "playlist", "sinek");	gtk_window_set_default_size(GTK_WINDOW(w), 450, 200);	vb = gtk_vbox_new(FALSE, 0);	gtk_widget_show(vb);	gtk_container_add(GTK_CONTAINER(w), vb);	gtk_container_set_border_width(GTK_CONTAINER(vb), 4);	/* menu */	fabrika = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", NULL);	gtk_item_factory_create_items(fabrika, n, menus, NULL);	menu = gtk_item_factory_get_widget(fabrika, "<main>");	sinek.repeat_all_chk = gtk_item_factory_get_widget(fabrika, _("/Modes/Repeat"));	sinek.signal_fake = 1;	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(sinek.repeat_all_chk), sinek.repeat_all);	sinek.signal_fake = 0;	gtk_widget_show(menu);	gtk_box_pack_start(GTK_BOX(vb), menu, FALSE, FALSE, 0);	/* playlist */	sw = gtk_scrolled_window_new(NULL, NULL);	gtk_widget_show(sw);	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);	gtk_box_pack_start(GTK_BOX(vb), sw, TRUE, TRUE, 3);	list_store = gtk_list_store_new(N_COLS, G_TYPE_STRING, G_TYPE_POINTER);	list_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));	list_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));	gtk_tree_selection_set_mode(list_select, GTK_SELECTION_MULTIPLE);	cell = gtk_cell_renderer_text_new();	col = gtk_tree_view_column_new_with_attributes(_("Media"), cell, NULL);	gtk_tree_view_column_set_cell_data_func(col, cell, cb_render_mrl, NULL, NULL);	gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), col);	gtk_widget_show(list_view);	gtk_container_add(GTK_CONTAINER(sw), list_view);	gtk_tree_view_set_reorderable(GTK_TREE_VIEW(list_view), TRUE);	g_signal_connect(G_OBJECT(list_view), "button_press_event", G_CALLBACK(cb_click), NULL);	/* buttons */	hb = gtk_hbox_new(TRUE, 0);	gtk_widget_show(hb);	gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, TRUE, 4);	gtk_container_set_border_width(GTK_CONTAINER(hb), 5);	BUTTON(_("Play"), cb_play, 0);	BUTTON(_("Add..."), cb_add, 0);	BUTTON(_("Remove"), cb_remove, 0);	*win = w;	return WM_NORMAL;}

⌨️ 快捷键说明

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