summary refs log tree commit diff stats
path: root/plugins/mpcinfo/oggInfo.c
blob: 83c2beb53904ad504fda86567ae080f4e132b49f (plain) (blame)
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
/*
 *  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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

static int getOggInt(char *buff, int beg, int bytes){
//if (DEBUG==1) putlog("getOggInt");
	int ret=0;
	int i;
	for (i=0;i<bytes;i++){
		if (buff[i+beg]>=0) ret+=buff[i+beg]*iPow(256,i);else ret+=(256+buff[i+beg])*iPow(256,i);
		//printf("[%i]=%i\n",i,buff[i+beg]);
	}
	return ret;
}

static char *upperStr(char *text){
//if (DEBUG==1) putlog("converting text to uc");
    //printf("upperStr(%s)\n",text);
	int i;
	char *ret=(char*) malloc(sizeof(char)*(strlen(text)+1));
	ret[strlen(text)]=0;
	for (i=0;i<strlen(text);i++) ret[i]=toupper(text[i]);
	//printf("Result: %s\n",ret);
	return ret;
}

struct tagInfo getOggHeader(char *file){
//if (DEBUG==1) putlog("reading ogg header");
	char header[4096];
	int i, c;
	int h1pos, h3pos, maxBr, nomBr, minBr, pos, count, tagLen;
	char *sub;
	char *name;
	char *val;
	char *HEADLOC1, *HEADLOC3, *HEADLOC5;
	FILE *f;
	struct tagInfo info;

	info.artist=NULL;
	f = fopen(file,"rb");
	if (f==NULL){
       xchat_print(ph,"file not found while trying to read ogg header");
       //if (DEBUG==1) putlog("file not found while trying to read ogg header");
       return info;
    }

	for (i=0;i<4095;i++) {c=fgetc(f);header[i]=(char)c;}
	fclose(f);
	HEADLOC1="_vorbis";
	HEADLOC1[0]=1;
	HEADLOC3="_vorbis";
	HEADLOC3[0]=3;
	HEADLOC5="_vorbis";
	HEADLOC5[0]=5;
	h1pos=inStr(header,4096,HEADLOC1);
	h3pos=inStr(header,4096,HEADLOC3);
	//int h5pos=inStr(header,4096,HEADLOC5); //not needed
	
	//printf("loc1: %i\n",h1pos);printf("loc3: %i\n",h3pos);printf("loc5: %i\n",h5pos);
	maxBr=getOggInt(header,h1pos+7+9,4);
	nomBr=getOggInt(header,h1pos+7+13,4);
	minBr=getOggInt(header,h1pos+7+17,4);
	info.freq=getOggInt(header,h1pos+7+5,4);
	info.mode=header[h1pos+7+4];
	info.bitrate=nomBr;
	if (((maxBr==nomBr)&&(nomBr=minBr))||((minBr==0)&&(maxBr==0))||((minBr=-1)&&(maxBr=-1)) )info.cbr=1;else info.cbr=0;
	printf("bitrates: %i|%i|%i\n",maxBr,nomBr,minBr);
	printf("freq: %i\n",info.freq);
	pos=h3pos+7;
	pos+=getOggInt(header,pos,4)+4;
	count=getOggInt(header,pos,4);
	//printf("tags: %i\n",count);
	pos+=4;

	info.artist=NULL;info.title=NULL;info.album=NULL;info.comment=NULL;info.genre=NULL;
	for (i=0;i<count;i++){
		tagLen=getOggInt(header,pos,4);
		//printf("taglength: %i\n",tagLen);
		sub=substring(header,pos+4,tagLen);
		name=upperStr(substring(sub,0,inStr(sub,tagLen,"=")));
		val=substring(sub,inStr(sub,tagLen,"=")+1,tagLen-inStr(sub,tagLen,"=")-1);
		//printf("Tag: %s\n",sub);
		//printf("Name: %s\n",name);
		//printf("value: %s\n",val);
		if (strcmp(name,"ARTIST")==0) info.artist=val;
		if (strcmp(name,"TITLE")==0) info.title=val;
		if (strcmp(name,"ALBUM")==0) info.album=val;
		if (strcmp(name,"GENRE")==0) info.genre=val;
		if (strcmp(name,"COMMENT")==0) info.comment=val;
		pos+=4+tagLen;
	}
	if (info.artist==NULL) info.artist="";
	if (info.album==NULL) info.album ="";
	if (info.title==NULL) info.title="";
	if (info.genre==NULL) info.genre="";
	if (info.comment==NULL) info.comment="";
	
	printf("Artist: %s\nTitle: %s\nAlbum: %s\n",info.artist,info.title, info.album);
	printf("Genre: %s\nComment: %s\nMode: %i\nCBR: %i\n",info.genre,info.comment,info.mode,info.cbr);
	//if (DEBUG==1) putlog("ogg header readed");
	return info;
}

/*
void printOggInfo(char *file){
	printf("Scanning Ogg-File for Informations: %s\n",file);
	printf("size:\t%10d byte\n",getSize(file));
	struct tagInfo info = getOggHeader(file);
}
*/
n">gtk_tree_selection_get_selected(selection, 0, &iter); gchar* theme_name; gtk_tree_model_get(model, &iter, 0, &theme_name, -1); // std::cout << theme_name << "\n"; return gchar_to_string(theme_name); } std::string get_selected_font() { // GtkWidget* fontentry = lookup_widget(g_main_window, "main_fontentry"); // return gtk_entry_get_text(GTK_ENTRY(fontentry)); bool default_font = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(g_main_window, "main_use_default_font_radio"))); if (default_font) return ""; GtkWidget* fontbutton = lookup_widget(g_main_window, "main_font_selector_button"); return gtk_font_button_get_font_name(GTK_FONT_BUTTON(fontbutton)); } // ------------------------------------------------------ static void themelist_selection_changed_cb(GtkTreeSelection* selection, gpointer data) { if (gtk_tree_selection_get_selected (selection, 0, 0)) apply_theme(get_selected_theme(), get_current_font()); } // ------------------------------------------------------ static void populate_with_themes(GtkWidget* w) { std::string search_path = gchar_to_string(gtk_rc_get_theme_dir()); //std::string search_path = gchar_to_string(g_build_filename("lib", "gtk-2.0", "2.10.0", "engines", NULL)); if (search_path.size() && search_path[search_path.size() -1] != G_DIR_SEPARATOR) search_path += G_DIR_SEPARATOR_S; GDir* gdir = g_dir_open(search_path.c_str(), 0, NULL); if (gdir == NULL) return; char* name; GList* glist = 0; while ( (name = const_cast<char*>(g_dir_read_name(gdir))) != NULL ) { std::string filename = name; // if (g_ascii_strup(fname.c_str(), -1) == "Default") // continue; std::string fullname = search_path + filename; std::string rc = fullname; rc += G_DIR_SEPARATOR_S; rc += "gtk-2.0"; rc += G_DIR_SEPARATOR_S; rc += "gtkrc"; bool is_dir = 0; if (g_file_test(fullname.c_str(), G_FILE_TEST_IS_DIR)) is_dir = 1; if (is_dir && g_file_test(rc.c_str(), G_FILE_TEST_IS_REGULAR)) { glist = g_list_insert_sorted(glist, g_strdup(filename.c_str()), (GCompareFunc)strcmp); } } g_dir_close(gdir); // ---------------- tree GtkTreeView* treeview = GTK_TREE_VIEW(w); GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store)); GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes ( "Theme", gtk_cell_renderer_text_new(), "text", 0, NULL); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); GtkTreeIter iter; int i =0, curr=0; while (char* theme = (char*)g_list_nth_data(glist, i)) { gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, 0, theme, -1); if (strcmp(theme, get_current_theme().c_str()) == 0) { curr = i; } ++i; } GtkTreeSelection* selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); // set the default theme // THIS IS IMPORTANT!!! gtk_widget_grab_focus(w); std::stringstream str; str << curr; GtkTreePath* selpath = gtk_tree_path_new_from_string (str.str().c_str()); if (selpath) { gtk_tree_selection_select_path(selection, selpath); gtk_tree_view_scroll_to_cell(treeview, selpath, NULL, true, 0.5, 0.0); gtk_tree_path_free(selpath); } g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (themelist_selection_changed_cb), NULL); g_object_unref (G_OBJECT (store)); // ---------------- font // GtkWidget* fontentry = lookup_widget(g_main_window, "main_fontentry"); // gtk_entry_set_text(GTK_ENTRY(fontentry), get_current_font().c_str()); GtkWidget* fontbutton = lookup_widget(g_main_window, "main_font_selector_button"); gtk_font_button_set_font_name(GTK_FONT_BUTTON(fontbutton), get_current_font().c_str()); } // ------------------------------------------------------ #ifdef _WIN32 static void redirect_to_file (const gchar* log_domain, GLogLevelFlags log_level, const gchar* message, gpointer user_data) { /* only write logs if running in portable mode, otherwise we would get a permission error in program files */ if ((_access( "portable-mode", 0 )) != -1) { std::fstream f; f.open("gtk2-prefs.log", std::ios::app); f << message << "\n"; f.close(); } } #endif // ------------------------------------------------------ int main(int argc, char *argv[]) { // work around pango weirdness #ifdef _WIN32 // no longer needed as of pango 1.2.5, but won't do any harm // putenv("PANGO_WIN32_NO_UNISCRIBE=1"); #endif std::string user = g_get_user_name(); std::string tmp = g_get_tmp_dir(); std::string tmp_file = tmp + G_DIR_SEPARATOR_S + "gtk_prefs_tmprc_" + user; s_tmp_file = tmp_file; gtk_rc_add_default_file(tmp_file.c_str()); gtk_init (&argc, &argv); // redirect gtk warnings to file when in win32 #if defined _WIN32 && !defined DEBUG g_log_set_handler ("GLib", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); g_log_set_handler ("GModule", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); g_log_set_handler ("GLib-GObject", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); g_log_set_handler ("GThread", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); g_log_set_handler ("Gtk", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); g_log_set_handler ("Gdk", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); g_log_set_handler ("GdkPixbuf", GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION), redirect_to_file, NULL); #endif add_pixmap_directory("."); g_main_window = create_main_window(); populate_with_themes(lookup_widget(g_main_window, "main_themelist")); std::string about_text = std::string("GTK+ Preference Tool") + "\n\ \n\ by Alex Shaduri <ashaduri@gmail.com>\n\ \n\ The authors make NO WARRANTY or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. This software is provided \"AS IS\", and you, its user, assume the entire risk as to its quality and accuracy.\n\ \n\ This is free software, and you are welcome to redistribute it under terms of GNU General Public License v2."; gtk_label_set_text(GTK_LABEL(lookup_widget(g_main_window, "about_label")), about_text.c_str()); GtkTreeView* treeview = GTK_TREE_VIEW(lookup_widget(g_main_window, "preview_treeview")); GtkTreeStore *store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT); gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store)); GtkTreeViewColumn* column1 = gtk_tree_view_column_new_with_attributes ("Text", gtk_cell_renderer_text_new(), "text", 0, NULL); gtk_tree_view_column_set_sizing(column1, GTK_TREE_VIEW_COLUMN_GROW_ONLY); gtk_tree_view_column_set_resizable(column1, true); gtk_tree_view_column_set_reorderable (column1, true); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column1); GtkTreeViewColumn* column2 = gtk_tree_view_column_new_with_attributes ("Number", gtk_cell_renderer_text_new(), "text", 1, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column2); GtkTreeIter iter1, iter2; gtk_tree_store_append (store, &iter1, NULL); gtk_tree_store_set (store, &iter1, 0, "Parent 2", 1, 66, -1); gtk_tree_store_append (store, &iter1, NULL); gtk_tree_store_set (store, &iter1, 0, "Parent 1", 1, 65, -1); gtk_tree_store_append (store, &iter2, &iter1); gtk_tree_store_set (store, &iter2, 0, "Child 1", 1, 67, -1); gtk_tree_view_column_set_sort_column_id(column1, 0); gtk_tree_view_column_set_sort_order (column1, GTK_SORT_ASCENDING); gtk_tree_view_column_set_sort_indicator(column1, true); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), 0, GTK_SORT_ASCENDING); g_object_unref (G_OBJECT (store)); get_orig_theme() = get_current_theme(); get_orig_font() = get_current_font(); gtk_widget_show (g_main_window); gtk_main(); return EXIT_SUCCESS; } // ------------------------------- void set_theme(const std::string& theme_name, const std::string& font) { // set widgets accordingly // tree GtkTreeView* treeview = GTK_TREE_VIEW(lookup_widget(g_main_window, "main_themelist")); GtkTreeModel* model = gtk_tree_view_get_model(treeview); GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview); GtkTreeIter iter; gtk_tree_model_get_iter_first(model, &iter); while(gtk_tree_model_iter_next(model, &iter)) { gchar* text; gtk_tree_model_get (model, &iter, 0, &text, -1); std::string theme = gchar_to_string(text); if (theme_name == theme) { gtk_tree_selection_select_iter(selection, &iter); break; } } // font // GtkWidget* fontentry = lookup_widget(g_main_window, "main_fontentry"); // gtk_entry_set_text(GTK_ENTRY(fontentry), font.c_str()); if (font != "") { GtkWidget* fontbutton = lookup_widget(g_main_window, "main_font_selector_button"); gtk_font_button_set_font_name(GTK_FONT_BUTTON(fontbutton), get_current_font().c_str()); } apply_theme(get_selected_theme(), get_selected_font()); } void apply_theme(const std::string& theme_name, const std::string& font) { std::stringstream strstr; strstr << "gtk-theme-name = \"" << theme_name << "\"\n"; if (font != "") strstr << "style \"user-font\"\n{\nfont_name=\"" << font << "\"\n}\nwidget_class \"*\" style \"user-font\""; // std::cout << strstr.str() << "\n\n\n"; std::fstream f; f.open(s_tmp_file.c_str(), std::ios::out); f << strstr.str(); f.close(); GtkSettings* settings = gtk_settings_get_default(); gtk_rc_reparse_all_for_settings (settings, true); // gtk_rc_parse_string(strstr.str().c_str()); // gtk_rc_parse("/root/.gtk-tmp"); // gtk_rc_reset_styles(settings); unlink(s_tmp_file.c_str()); while (gtk_events_pending()) gtk_main_iteration(); } #ifdef _WIN32 #ifdef HAVE_DIRECT_H #include <direct.h> #define mkdir(a) _mkdir(a) #else #define mkdir(a, b) mkdir(a) #endif #endif bool save_current_theme() { std::string conf_file = ""; if ((_access( "portable-mode", 0 )) != -1) { char* themes_dir_c = gtk_rc_get_theme_dir(); char* conf_file_c = g_build_filename("etc", "gtk-2.0", "gtkrc", NULL); conf_file = (conf_file_c ? conf_file_c : ""); // file doesn't exist, try to get it from gtk. if (!g_file_test(conf_file.c_str(), G_FILE_TEST_EXISTS)) { gchar** rc_files = gtk_rc_get_default_files(); if (rc_files[0] != 0) { conf_file = rc_files[0]; } } g_free(themes_dir_c); g_free(conf_file_c); // mkdir a directory, only one level deep char* etc = g_path_get_dirname(conf_file.c_str()); if (!g_file_test(etc, G_FILE_TEST_IS_DIR)) { mkdir(etc, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } g_free(etc); } else { conf_file = get_home_dir(); if (conf_file[conf_file.length()-1] != G_DIR_SEPARATOR) conf_file += G_DIR_SEPARATOR_S; conf_file += ".gtkrc-2.0"; } // ask GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget* dialog = gtk_dialog_new_with_buttons ("Query", GTK_WINDOW(window), GtkDialogFlags(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL), GTK_STOCK_NO, GTK_RESPONSE_REJECT, GTK_STOCK_YES, GTK_RESPONSE_ACCEPT, NULL); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); GtkWidget* hbox = gtk_hbox_new(1, 1); gtk_container_set_border_width(GTK_CONTAINER(hbox), 10); gtk_container_add (GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox); gtk_container_add (GTK_CONTAINER(hbox), gtk_label_new((std::string("\n\nThe file \"") + conf_file + "\" will be overwritten.\nAre you sure?\n\n").c_str())); gtk_widget_show_all (dialog); bool ret = 0; gint result = gtk_dialog_run (GTK_DIALOG (dialog)); switch (result) { case GTK_RESPONSE_ACCEPT: ret = 1; break; } gtk_widget_destroy(dialog); gtk_widget_destroy(window); if (!ret) // the user pressed "No". return false; std::string font = get_selected_font(); std::fstream f; f.open(conf_file.c_str(), std::ios::out); f << "# Auto-written by gtk2_prefs. Do not edit.\n\n"; f << "gtk-theme-name = \"" << get_selected_theme() << "\"\n"; if (font != "") f << "style \"user-font\"\n{\n\tfont_name=\"" << font << "\"\n}\nwidget_class \"*\" style \"user-font\""; f.close(); return true; } void program_shutdown() { gtk_main_quit(); }