summary refs log tree commit diff stats
path: root/plugins/mpcinfo
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mpcinfo')
-rw-r--r--plugins/mpcinfo/functions.c167
-rw-r--r--plugins/mpcinfo/makefile.mak18
-rw-r--r--plugins/mpcinfo/mp3Info.c361
-rw-r--r--plugins/mpcinfo/mpcInfo.c149
-rw-r--r--plugins/mpcinfo/oggInfo.c122
-rw-r--r--plugins/mpcinfo/theme.c136
6 files changed, 953 insertions, 0 deletions
diff --git a/plugins/mpcinfo/functions.c b/plugins/mpcinfo/functions.c
new file mode 100644
index 00000000..ed0632d4
--- /dev/null
+++ b/plugins/mpcinfo/functions.c
@@ -0,0 +1,167 @@
+/*
+ *  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.
+ */
+
+/*
+typedef int (*MYPROC)(HWND,HWND,char*,char*,BOOL,BOOL); 
+
+int dllProc(char *name, char *data){
+    HINSTANCE hinstLib; 
+    hinstLib = LoadLibrary("mpcinfo");
+    //MYPROC proc;
+    int res;
+    if (hinstLib != NULL){
+       //proc = ;
+       if ((MYPROC) GetProcAddress(hinstLib, name)!=NULL){
+          res=(MYPROC)(NULL,NULL,data,NULL,TRUE,TRUE);
+       }
+       else{fprintf(stderr,"can't get proc: %s\n",name);res=-2;}
+    }
+    else{fprintf(stderr,"can't access dll\n");return -1;}
+    FreeLibrary(hinstLib);
+    return res;
+}
+*/
+
+/*
+int dllProc(char *name, char *data)
+{
+	static HMODULE lib = NULL;
+	if (!lib)
+	{
+		lib = LoadLibraryA ("mpcinfo");
+		if (!lib)
+		{
+			return FALSE;
+		}
+		FreeLibrary (lib);
+	}
+
+	return TRUE;
+}
+*/
+
+char *split(char *text, char seperator){
+     //if (DEBUG==1) putlog("splitting");
+     int i;int pos=-1;
+     for (i=0;i<strlen(text);i++){
+         if (text[i]==seperator){pos=i;i=strlen(text)+1;}
+     }
+     if (pos==-1) return text;
+     text[pos]=0;
+     return &(text[pos+1]);
+}
+
+int endsWith(char *text, char *suffix){
+    char *tmp=strstr(text,suffix);
+    if (tmp==NULL) return 0;
+    if (strlen(tmp)==strlen(suffix)) return 1;
+    return 0;
+}
+
+int inStr(char *s1, int sl1, char *s2){
+    //if (DEBUG==1) putlog("checking instr");
+	int i;int j;
+	for(i=0;i<sl1-strlen(s2);i++){
+		for (j=0;j<strlen(s2);j++){
+			if (s1[i+j]!=s2[j]) j=strlen(s2)+2;
+		}
+		if (j==strlen(s2)) return i;
+	}
+	return -1;
+}
+
+static char *subString(char *text, int first, int length, int spcKill){
+//if (DEBUG==1) putlog("creating substring");
+	char *ret=(char*) calloc (length+1,sizeof(char)); //malloc(sizeof(char)*(length+1));
+	int i;
+	ret[length]=0;
+	for (i=0;i<length;i++){
+		ret[i]=text[i+first];
+		//if (ret[i]==0) ret[i]='0';
+	}
+	if (spcKill==1){
+	   for (i=length-1;i>=0;i--){
+           if (ret[i]==32) ret[i]=0;
+           else i=-1;
+       }
+    }
+    //if (DEBUG==1) putlog("substring created");
+	return ret;
+}
+
+static char *substring(char *text, int first, int length){return subString(text,first,length,0);}
+
+
+char *readLine(FILE *f){
+     //if (DEBUG==1) putlog("reading line from file");
+     char *buffer=(char*)calloc(1024,sizeof(char)); //malloc(sizeof(char)*1024);
+     int pos=0;
+     int cc=0;
+     while((cc!=EOF)&&(pos<1024)&&(cc!=10)){
+          cc=fgetc(f);
+          if ((cc!=10)&&(cc!=13)){
+             if (cc==EOF) buffer[pos]=0;
+             else buffer[pos]=(char)cc;pos++;
+          }
+     }
+     if (buffer[pos]==EOF) xchat_printf(ph,"EOF: %i\n",pos);
+     return buffer;
+}
+
+char *toUpper(char *text){
+     //if (DEBUG==1) putlog("converting text to upper case");
+     char *ret=(char*) calloc(strlen(text)+1,sizeof(char));
+     int i;
+     for (i=0;i<strlen(text);i++) ret[i]=toupper(text[i]);
+     ret[strlen(text)]=0;
+     //if (DEBUG==1) putlog("uc done");
+     return ret;
+}
+
+static char *str3cat(char *s1, char *s2, char *s3){
+       //if (DEBUG==1) putlog("cating 3 strings");
+       char *ret=(char*)calloc(strlen(s1)+strlen(s2)+strlen(s3)+1,sizeof(char));
+       strcpy(ret,s1);strcat(ret,s2);strcat(ret,s3);
+       ret[strlen(s1)+strlen(s2)+strlen(s3)]=0;
+       //if (DEBUG==1) putlog("strings cated");
+       return ret;
+}
+
+char *replace(char *text, char *from, char *to){
+     //if (DEBUG==1) putlog("replacing");
+     char *ret=(char*)calloc( strlen(text)+(strlen(to)-strlen(from)),sizeof(char));
+     char *left;
+     char *right;
+     int pos=inStr(text,strlen(text),from);
+     if (pos!=-1){
+           left=substring(text,0,pos);
+           right=substring(text,pos+strlen(from),strlen(text)-(pos+strlen(from)));          
+           ret=str3cat(left,to,right);
+           return replace(ret,from,to);
+     }
+     //if (DEBUG==1) putlog("replaced");
+     return text;
+}
+
+char *intReplaceF(char *text, char *from, int to, char *form){
+     //if (DEBUG==1) putlog("replaceF");
+     char *buffer=(char*) calloc(16,sizeof(char));
+     sprintf(buffer,form,to);
+     //if (DEBUG==1) putlog("replaceF done");
+     return replace(text,from,buffer);
+}
+
+char *intReplace(char *text, char *from, int to){return intReplaceF(text,from,to,"%i");}
diff --git a/plugins/mpcinfo/makefile.mak b/plugins/mpcinfo/makefile.mak
new file mode 100644
index 00000000..4a8a2763
--- /dev/null
+++ b/plugins/mpcinfo/makefile.mak
@@ -0,0 +1,18 @@
+include "..\..\src\makeinc.mak"

+

+all: mpcinfo.obj mpcinfo.def

+	link $(LDFLAGS) $(LIBS) /dll /out:xcmpcinfo.dll /def:mpcinfo.def mpcinfo.obj

+

+mpcinfo.def:

+	echo EXPORTS > mpcinfo.def

+	echo xchat_plugin_init >> mpcinfo.def

+	echo xchat_plugin_deinit >> mpcinfo.def

+

+mpcinfo.obj: mpcinfo.c makefile.mak

+	cl $(CFLAGS) $(GLIB) /I.. mpcinfo.c

+

+clean:

+	del *.obj

+	del *.dll

+	del *.exp

+	del *.lib

diff --git a/plugins/mpcinfo/mp3Info.c b/plugins/mpcinfo/mp3Info.c
new file mode 100644
index 00000000..f75ba9c4
--- /dev/null
+++ b/plugins/mpcinfo/mp3Info.c
@@ -0,0 +1,361 @@
+/*
+ *  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.
+ */
+
+//#include <stdio.h>
+#include <sys/stat.h>
+//#include "functions.c"
+
+struct tagInfo{
+	int mode;
+	int cbr;
+	int bitrate;
+	unsigned int freq;
+	char *artist;
+	char *title;
+	char *album;
+	char *comment;
+	char *genre;
+	//int genre;
+	//int track;
+};
+
+static int RATES[2][3][15]={
+				{//mpeg2
+                    {-1,8,16,24,32,64,80,56,64,128,160,112,128,256,320},//layer3 (V2)    
+					{-1,32,48,56,64,80,96,112,128,160,192,224,256,320,384},//layer2 (V2)
+					{-1,32,64,96,128,160,192,224,256,288,320,352,384,416,448},//layer1 (V2)
+                },
+                {//mpeg1
+					{-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320},//layer3 (V1)
+					{-1,32,48,56,64,80,96,112,128,160,192,224,256,320,384},//layer2 (V1)
+                    {-1,32,64,96,128,160,192,224,256,288,320,352,384,416,448},//layer1 (V1)
+        }};
+static int FREQS[2][4]={{22050,24000,16000,-1},{44100,48000,32000,-1}};
+//static double FRATES[]={38.5,32.5,27.8,0.0};
+
+static char GENRES[][50]={"Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge","Hip-Hop","Jazz","Metal",
+"New Age","Oldies","Other","Pop","R&B","Rap","Reggae","Rock","Techno","Industrial",
+"Alternative","Ska","Death Metal","Pranks","Soundtrack","Euro-Techno","Ambient","Trip-Hop","Vocal","Jazz+Funk",
+"Fusion","Trance","Classical","Instrumental","Acid","House","Game","Sound Clip","Gospel","Noise",
+"AlternRock","Bass","Soul","Punk","Space","Meditative","Instrumental Pop","Instrumental Rock","Ethnic","Gothic",
+"Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance","Dream","Southern Rock","Comedy","Cult","Gangsta",
+"Top 40","Christian Rap","Pop/Funk","Jungle","Native American","Cabaret","New Wave","Psychadelic","Rave","Showtunes",
+"Trailer","Lo-Fi","Tribal","Acid Punk","Acid Jazz","Polka","Retro","Musical","Rock & Roll","Hard Rock",
+
+//################## END OF OFFICIAL ID3 TAGS, WINAMP TAGS BELOW ########################################
+
+"Folk","Folk/Rock","National Folk","Swing","Fast Fusion","Bebob","Latin","Revival","Celtic","Bluegrass",
+"Avantgarde","Gothic Rock","Progressive Rock","Psychedelic Rock","Symphonic Rock","Slow Rock","Big Band","Chorus","Easy Listening","Acoustic",
+"Humour","Speech","Chanson","Opera","Chamber Music","Sonata","Symphony","Booty Bass","Primus","Porn Groove",
+"Satire","Slow Jam","Club","Tango","Samba","Folklore","Ballad","Poweer Ballad","Rhytmic Soul","Freestyle",
+"Duet","Punk Rock","Drum Solo","A Capela","Euro-House","Dance Hall",
+
+//################## FOUND AT http://en.wikipedia.org/wiki/ID3 ###########################################
+
+"Goa","Drum & Bass","Club-House","Hardcore",
+"Terror","Indie","BritPop","Negerpunk","Polsk Punk","Beat","Christian Gangsta Rap","Heavy Metal","Black Metal","Crossover",
+"Contemporary Christian","Christian Rock","Merengue","Salsa","Thrash Metal","Anime","JPop","Synthpop"
+
+};
+
+static char MODES [][13]={"Stereo","Joint-Stereo","Dual-Channel","Mono"};
+
+int iPow(int x, int y){return (int)(pow((double)x,(double) y));}
+
+int str2int(char *text){
+    //if (DEBUG==1) putlog("converting string to int");
+    int i;
+    int ret=0;
+    for (i=1;i<=strlen(text);i++){
+        if ((text[strlen(text)-i]>57)||(text[strlen(text)-i]<48)){
+           xchat_printf(ph,"invalid char in string: %i",text[strlen(text)-i]);
+           return 255;
+        }
+        ret+=((int)text[strlen(text)-i]-48)*iPow(10,i-1);
+    }
+    //xchat_printf(ph, "str2int(%s)=%i",text,ret);
+    //if (DEBUG==1) putlog("int converted");
+    return ret;
+}
+/*
+static int getSize(char *file){
+    //if (DEBUG==1) putlog("reading filesize");
+	struct stat info;
+	if (stat(file,&info)!=0) return -1;
+	return info.st_size;
+}*/
+/*
+int inStr(char *s1, int sl1, char *s2){
+    //if (DEBUG==1) putlog("checking instr");
+	int i;int j;
+	for(i=0;i<sl1-strlen(s2);i++){
+		for (j=0;j<strlen(s2);j++){
+			if (s1[i+j]!=s2[j]) j=strlen(s2)+2;
+		}
+		if (j==strlen(s2)) return i;
+	}
+	return -1;
+}
+
+static char *subString(char *text, int first, int length, int spcKill){
+//if (DEBUG==1) putlog("creating substring");
+	char *ret=(char*) calloc (length+1,sizeof(char)); //malloc(sizeof(char)*(length+1));
+	ret[length]=0;int i;
+	for (i=0;i<length;i++){
+		ret[i]=text[i+first];
+		//if (ret[i]==0) ret[i]='0';
+	}
+	if (spcKill==1){
+	   for (i=length-1;i>=0;i--){
+           if (ret[i]==32) ret[i]=0;
+           else i=-1;
+       }
+    }
+    //if (DEBUG==1) putlog("substring created");
+	return ret;
+}
+
+static char *substring(char *text, int first, int length){return subString(text,first,length,0);} //1
+*/
+
+static char *tagExtract(char *tag, int tagLen, char* info){
+//if (DEBUG==1) putlog("extracting tag");
+	int pos, len, i;
+	pos=inStr(tag,tagLen,info);
+//xchat_printf(ph,"pos=%i",pos);
+	if (pos==-1) return "";//NULL;
+	//printf("position of %s = %i\n",info,pos);
+	len=0;
+	//for (i=pos;i<pos+10;i++)printf("tag[%i]=%i \n",i,tag[i]);
+	for (i=0;i<4;i++) {
+		len+=tag[pos+strlen(info)+i]*iPow(255,3-i);
+	}
+	//printf("Tag-Length: %i\n",len);
+	if (strcmp("COMM",info)!=0) return substring(tag,pos+7+strlen(info),len-1);//11
+	return substring(tag,pos+7+strlen(info),len-1);//11
+	//char *ct=substring(tag,pos+7+strlen(info),len-1);//11
+	//return substring(ct,strlen(ct)+1,len-1-strlen(ct)); //<-- do not understand, what i did here :(
+	
+}
+
+struct tagInfo readID3V1(char *file){
+//if (DEBUG==1) putlog("reading ID3V1");
+	FILE *f;
+	struct tagInfo ret;
+	int res, i, c, val;
+	char *tag;
+	char *id;
+	char *tmp;
+	tag = (char*) malloc(sizeof(char)*129);
+	ret.artist=NULL;
+	f=fopen(file,"rb");
+	if (f==NULL){
+       xchat_print(ph,"file not found while trying to read id3v1");
+       //if (DEBUG==1) putlog("file not found while trying to read id3v1");
+       return ret;
+    }
+	//int offset=getSize(file)-128;
+	res=fseek(f,-128,SEEK_END);
+	if (res!=0) {printf("seek failed\n");fclose(f);return ret;}
+	//long int pos=ftell(f);
+	//printf("position= %li\n",pos);
+	for (i=0;i<128;i++) {
+		c=fgetc(f);
+		if (c==EOF) {xchat_printf(ph,"read ID3V1 failed\n");fclose(f);return ret;}
+		tag[i]=(char)c;
+	}
+	fclose(f);
+	//printf("tag readed: \n");
+	id=substring(tag,0,3);
+	//printf("header: %s\n",id);
+	if (strcmp(id,"TAG")!=0){xchat_printf(ph,"no id3 v1 found\n");return ret;}
+	ret.title=subString(tag,3,30,1);
+	ret.artist=subString(tag,33,30,1);
+	ret.album=subString(tag,63,30,1);
+	ret.comment=subString(tag,97,30,1);
+	tmp=substring(tag,127,1);
+	//ret.genre=substring(tag,127,1);
+	
+	val=(int)tmp[0];
+	if (val<0)val+=256;
+	//xchat_printf(ph, "tmp[0]=%i (%i)",val,tmp[0]);
+	if ((val<148)&&(val>=0)) 
+       ret.genre=GENRES[val];//#############changed
+	else {
+         ret.genre="unknown";
+         //xchat_printf(ph, "tmp[0]=%i (%i)",val,tmp[0]);
+    }
+	//xchat_printf(ph, "tmp: \"%s\" -> %i",tmp,tmp[0]);
+	//xchat_printf(ph,"genre \"%s\"",ret.genre);
+	//if (DEBUG==1) putlog("id3v1 extracted");
+	return ret;
+}
+
+char *extractID3Genre(char *tag){
+     //if (DEBUG==1) putlog("extracting id3 genre");
+     if (tag[strlen(tag)-1]==')'){
+        tag[strlen(tag)-1]=0;
+        tag=&tag[1];
+        return GENRES[str2int(tag)];
+        //return tag;
+     }
+     else{
+          int i;
+          //xchat_print(ph, "Using 2 criteria");
+          for (i=0;i<strlen(tag);i++){
+              if (tag[i]==')'){ tag=&tag[i]+1;return tag;}
+          //return tag;
+          }
+     }
+     return "[152] failed";
+}
+
+struct tagInfo readID3V2(char *file){
+//if (DEBUG==1) putlog("reading id3v2");
+	FILE *f;
+	int i, c, len;
+	char header[10];
+	char *tag;
+	struct tagInfo ret;
+
+	f = fopen(file,"rb");
+	//xchat_printf(ph,"file :%s",file);
+	if (f==NULL)
+	{
+       xchat_print(ph,"file not found whilt trying to read ID3V2");
+       //if (DEBUG==1)putlog("file not found while trying to read ID3V2");
+       return ret;
+    }
+
+	ret.artist=NULL;
+	for (i=0;i<10;i++){
+        c=fgetc(f);
+        if (c==EOF){
+           //putlog("found eof while reading id3v2");
+           return ret;
+        }
+        header[i]=(char)c;
+    }
+	if (strstr(header,"ID3")==header){
+		//xchat_printf(ph,"found id3v2\n");
+		len=0;
+		for (i=6;i<10;i++) len+=(int)header[i]*iPow(256,9-i);
+		
+		//char *tag=(char*)malloc(sizeof(char)*len);
+		tag=(char*) calloc(len,sizeof(char)); //malloc(sizeof(char)*len);
+		for (i=0;i<len;i++){c=fgetc(f);tag[i]=(char)c;}
+//xchat_printf(ph,"tag length: %i\n",len);
+//xchat_printf(ph,"tag: %s\n",tag);
+		fclose(f);
+		ret.comment=tagExtract(tag,len,"COMM");
+//xchat_printf(ph,"Comment: %s\n",ret.comment);
+		ret.genre=tagExtract(tag,len,"TCON");
+		//if (strcmp(ret.genre,"(127)")==0) ret.genre="unknown";
+//xchat_printf(ph, "ret.genre = %s",ret.genre);
+		if ((ret.genre!=NULL)&&(ret.genre[0]=='(')) ret.genre=extractID3Genre(ret.genre);
+//xchat_printf(ph,"genre: %s\n",ret.genre);
+		ret.title=tagExtract(tag,len,"TIT2");
+//xchat_printf(ph,"Title: %s\n",ret.title);
+		ret.album=tagExtract(tag,len,"TALB");
+//xchat_printf(ph,"Album: %s\n",ret.album);
+		ret.artist=tagExtract(tag,len,"TPE1");
+//xchat_printf(ph,"Artist: %s\n",ret.artist);
+	}
+	else{fclose(f);printf("no id3v2 tag found\n"); return ret;}
+	//printf("id2v2 done\n");
+	//if (DEBUG==1) putlog("id3v2 readed");
+	return ret;
+}
+
+struct tagInfo readHeader(char *file){
+//if (DEBUG==1) putlog("reading header");
+	FILE *f;
+	//int buffer[5120];
+	int versionB, layerB, bitrateB, freqB, modeB;
+	int header[4];
+	int count=0;
+	int cc=0;
+	struct tagInfo info;
+	info.artist=NULL;
+
+	f = fopen(file,"rb");
+	if (f==NULL)
+	{
+       xchat_print(ph,"file not found while trying to read mp3 header");
+       //if (DEBUG==1) putlog("file not found while trying to read mp3 header");
+       return info;
+    }
+	//struct tagInfo tagv2
+	
+	info=readID3V2(file);
+	//struct tagInfo tagv1;//=readID3V1(file);
+	//if 	(tagv2.artist!=NULL){info=tagv2;}
+	//else {
+	if (info.artist==NULL){
+		//printf("searching for id3v1\n");
+		//tagv1=readID3V1(file);
+		info=readID3V1(file); //#####################
+	}
+	/*
+	if (tagv1.artist!=NULL){
+		//printf("Artist: %s\nTitle: %s\nAlbum: %s\nComment: %s\nGenre: %s\n",tagv1.artist,tagv1.title,tagv1.album,tagv1.comment,tagv1.genre);
+		info=tagv1;
+	}
+	*/
+	while ((count<5120)&&(cc!=EOF)&&(cc!=255)) {cc=fgetc(f);count++;}
+	if ((cc==EOF)||(count==5119)) printf("no header found\n");
+	else {
+		//printf("located header at %i\n",count);
+		header[0]=255;
+		for (count=1;count<4;count++){
+			header[count]=fgetc(f);
+			//printf("header[%i]=%i\n",count,header[count]);
+		}
+		versionB=(header[1]&8)>>3;
+		layerB=(header[1]&6)>>1;
+		bitrateB=(header[2]&240)>>4; //4
+		freqB=(header[2]&12)>>2;//2
+		modeB=(header[3]&192)>>6;//6
+		//printf("Mpeg: %i\nLayer: %i\nBitrate: %i\nFreq: %i\nMode: %i\n",versionB, layerB, bitrateB, freqB, modeB);
+		//int Bitrate=RATES[versionB][layerB-1][bitrateB];
+		//int Freq=FREQS[versionB][freqB];
+		info.bitrate=RATES[versionB][layerB-1][bitrateB];
+		info.freq=FREQS[versionB][freqB];
+		info.mode=modeB;	
+	}
+	fclose(f);
+	//if (DEBUG==1) putlog("header readed");
+	return info;
+}
+/*
+static void printMp3Info(char *file){
+	//printf("\nScanning Mp3-File for Informations: %s\n",file);
+	//printf("size:\t%10d byte\n",getSize(file));
+	struct tagInfo info =readHeader(file);
+	printf("%s | %10d",file,getSize(file));
+	if  (info.bitrate>0){
+		//printf("Bitrate: %i\nFreq: %i\nMode: %s\n",info.bitrate,info.freq,MODES[info.mode]);
+		printf(" | %i kbps | %i kHz | %s",info.bitrate,info.freq,MODES[info.mode]);
+		//if (info.artist!=NULL) printf("\nArtist: %s\nTitle: %s\nAlbum: %s\nComment: %s\nGenre: %s\n",info.artist,info.title,info.album,info.comment,info.genre);
+		if (info.artist!=NULL) {
+			printf("| %s | %s | %s | %s | %s",info.artist,info.title,info.album,info.comment,info.genre);
+			//printf("| %s ",info.title);//,info.title,info.album,info.comment,info.genre
+		}
+	}
+	printf("\n");
+	
+}
+*/
diff --git a/plugins/mpcinfo/mpcInfo.c b/plugins/mpcinfo/mpcInfo.c
new file mode 100644
index 00000000..e467e516
--- /dev/null
+++ b/plugins/mpcinfo/mpcInfo.c
@@ -0,0 +1,149 @@
+/*
+ *  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 DEBUG=0;
+static char *VERSION="0.0.6";
+
+#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include "xchat-plugin.h"
+static xchat_plugin *ph;
+
+#include "functions.c"
+#include "mp3Info.c"
+#include "oggInfo.c"
+#include "theme.c"
+
+static int print_themes (char *word[], char *word_eol[], void *userdata){
+       printThemes();
+       return XCHAT_EAT_ALL;
+}
+
+static int mpc_themeReload(char *word[], char *word_eol[], void *userdata){
+   themeInit();
+   loadThemes();
+   return XCHAT_EAT_ALL;
+}
+
+static int mpc_tell(char *word[], char *word_eol[], void *userdata){
+       char *tTitle, *zero, *oggLine, *line;
+	   struct tagInfo info;
+	   HWND hwnd = FindWindow("MediaPlayerClassicW",NULL);
+       if (hwnd==0) {xchat_command(ph, randomLine(notRunTheme));return XCHAT_EAT_ALL;}
+       
+       tTitle=(char*)malloc(sizeof(char)*1024);
+       GetWindowText(hwnd, tTitle, 1024);
+       zero=strstr(tTitle," - Media Player Classic");
+       if (zero!=NULL) zero[0]=0;
+       else xchat_print(ph,"pattern not found");
+       
+       if ((tTitle[1]==':')&&(tTitle[2]=='\\')){
+          //xchat_print(ph,"seams to be full path");
+          if (endsWith(tTitle,".mp3")==1){
+             //xchat_print(ph,"seams to be a mp3 file");
+             info = readHeader(tTitle);
+             
+             if ((info.artist!=NULL)&&(strcmp(info.artist,"")!=0)){
+                char *mode=MODES[info.mode];
+                //xchat_printf(ph,"mode: %s\n",mode);
+                char *mp3Line=randomLine(mp3Theme);
+                mp3Line=replace(mp3Line,"%art",info.artist);
+                mp3Line=replace(mp3Line,"%tit",info.title);
+                mp3Line=replace(mp3Line,"%alb",info.album);
+                mp3Line=replace(mp3Line,"%com",info.comment);
+                mp3Line=replace(mp3Line,"%gen",info.genre);
+                //mp3Line=replace(mp3Line,"%time",pos);
+                //mp3Line=replace(mp3Line,"%length",len);
+                //mp3Line=replace(mp3Line,"%ver",waVers);
+                //mp3Line=intReplace(mp3Line,"%br",br);
+                //mp3Line=intReplace(mp3Line,"%frq",frq);
+                
+                mp3Line=intReplace(mp3Line,"%br",info.bitrate);
+                mp3Line=intReplace(mp3Line,"%frq",info.freq);
+                mp3Line=replace(mp3Line,"%mode",mode);
+                //mp3Line=replace(mp3Line,"%size",size);
+                //mp3Line=intReplace(mp3Line,"%perc",perc);
+                //mp3Line=replace(mp3Line,"%plTitle",title);
+                mp3Line=replace(mp3Line,"%file",tTitle);
+                xchat_command(ph, mp3Line);
+                return XCHAT_EAT_ALL;
+             }
+          }
+          if (endsWith(tTitle,".ogg")==1){
+             xchat_printf(ph,"Ogg detected\n");
+             info = getOggHeader(tTitle);
+             if (info.artist!=NULL){
+                char *cbr;
+                if (info.cbr==1) cbr="CBR"; else cbr="VBR";
+                oggLine=randomLine(oggTheme);
+                //if (cue==1) oggLine=cueLine;
+                //xchat_printf(ph,"ogg-line: %s\n",oggLine);
+                oggLine=replace(oggLine,"%art",info.artist);
+                oggLine=replace(oggLine,"%tit",info.title);
+                oggLine=replace(oggLine,"%alb",info.album);
+                oggLine=replace(oggLine,"%com",info.comment);
+                oggLine=replace(oggLine,"%gen",info.genre);
+                //oggLine=replace(oggLine,"%time",pos);
+                //oggLine=replace(oggLine,"%length",len);
+                //oggLine=replace(oggLine,"%ver",waVers);
+                oggLine=intReplace(oggLine,"%chan",info.mode);
+                oggLine=replace(oggLine,"%cbr",cbr);
+                oggLine=intReplace(oggLine,"%br",info.bitrate/1000);//br);
+                oggLine=intReplace(oggLine,"%frq",info.freq);
+                //oggLine=replace(oggLine,"%size",size);
+                //oggLine=intReplace(oggLine,"%perc",perc);
+                //oggLine=replace(oggLine,"%plTitle",title);
+                oggLine=replace(oggLine,"%file",tTitle);
+                xchat_command(ph, oggLine);
+                return XCHAT_EAT_ALL;
+             }
+          }
+       }
+       line=randomLine(titleTheme);
+       line=replace(line,"%title", tTitle);
+       xchat_command(ph,line); 
+       return XCHAT_EAT_ALL;
+}
+
+int xchat_plugin_init(xchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg){
+	ph = plugin_handle;
+	*plugin_name = "mpcInfo";
+	*plugin_desc = "Information-Script for Media Player Classic"; 
+	*plugin_version=VERSION;
+
+	xchat_hook_command(ph, "mpc", XCHAT_PRI_NORM, mpc_tell,"no help text", 0);
+	xchat_hook_command(ph, "mpc_themes", XCHAT_PRI_NORM, print_themes,"no help text", 0);
+	xchat_hook_command(ph, "mpc_reloadthemes", XCHAT_PRI_NORM, mpc_themeReload,"no help text", 0);
+	xchat_command (ph, "MENU -ietc\\music.png ADD \"Window/Display Current Song (MPC)\" \"MPC\"");
+
+	themeInit();
+	loadThemes();
+	xchat_printf(ph, "%s %s plugin loaded\n",*plugin_name, VERSION);
+
+	return 1;
+}
+
+int
+xchat_plugin_deinit (void)
+{
+	xchat_command (ph, "MENU DEL \"Window/Display Current Song (MPC)\"");
+	xchat_print (ph, "mpcInfo plugin unloaded\n");
+	return 1;
+}
diff --git a/plugins/mpcinfo/oggInfo.c b/plugins/mpcinfo/oggInfo.c
new file mode 100644
index 00000000..83c2beb5
--- /dev/null
+++ b/plugins/mpcinfo/oggInfo.c
@@ -0,0 +1,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);
+}
+*/
diff --git a/plugins/mpcinfo/theme.c b/plugins/mpcinfo/theme.c
new file mode 100644
index 00000000..000c00b1
--- /dev/null
+++ b/plugins/mpcinfo/theme.c
@@ -0,0 +1,136 @@
+/*
+ *  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.
+ */
+
+#include <time.h>
+
+struct theme{
+       int size;
+       char **line;
+};
+
+static struct theme notRunTheme;
+static struct theme titleTheme;
+static struct theme mp3Theme;
+static struct theme oggTheme;
+
+
+void themeInit(){
+     //if (DEBUG==1) putlog("init theme");
+     /*mp3Theme.size=0;oggTheme.size=0;cueTheme.size=0;streamTheme.size=0;etcTheme.size=0;
+     stopTheme.size=0;pauseTheme.size=0;*/
+     
+     notRunTheme.size=0;titleTheme.size=0;
+     srand((unsigned int)time((time_t *)NULL));
+     //if (DEBUG==1) putlog("theme init done");
+}
+
+void printTheme(struct theme data){
+     int i;
+     for (i=0;i<data.size;i++) xchat_printf(ph,"line[%i]=%s\n",i,data.line[i]);
+}
+
+void printThemes(){
+     xchat_printf(ph,"\nNotRun-Theme:\n");printTheme(notRunTheme);
+     xchat_printf(ph,"\nMP3-Theme:\n");printTheme(mp3Theme);
+     xchat_printf(ph,"\nOGG-Theme:\n");printTheme(oggTheme);
+     xchat_printf(ph,"\nTitle-Theme:\n");printTheme(titleTheme);
+}
+
+void cbFix(char *line){
+     //if (DEBUG==1) putlog("cbfix");
+     int i, j;
+     for (i=0;i<strlen(line);i++){
+         if (line[i]=='%'){
+            if ((line[i+1]=='C')||(line[i+1]=='B')||(line[i+1]=='U')||(line[i+1]=='O')||(line[i+1]=='R')){
+               if(line[i+1]=='C') line[i]=3;
+               if(line[i+1]=='B') line[i]=2;
+               if(line[i+1]=='U') line[i]=37;
+               if(line[i+1]=='O') line[i]=17;
+               if(line[i+1]=='R') line[i]=26;
+
+               for (j=i+1;j<strlen(line)-1;j++) line[j]=line[j+1];
+               line[strlen(line)-1]=0;
+            }
+         }
+     }
+     //if (DEBUG==1) putlog("cbfix done");
+}
+
+struct theme themeAdd(struct theme data, char *info){
+       //if (DEBUG==1) putlog("adding theme");
+       struct theme ret;
+       char **newLine=(char **)calloc(data.size+1,sizeof(char*));
+       int i;
+       for (i=0;i<data.size;i++) newLine[i]=data.line[i];
+       cbFix(info);
+       newLine[data.size]=info;
+       ret.line=newLine;ret.size=data.size+1;
+       //if (DEBUG==1) putlog("theme added");
+       return ret;
+}
+
+void loadThemes(){
+    char *hDir, *hFile, *line, *val;
+	FILE *f;
+	xchat_print(ph,"loading themes\n");
+    hDir=(char*)calloc(1024,sizeof(char));
+    strcpy(hDir,xchat_get_info(ph,"xchatdirfs"));
+    hFile=str3cat(hDir,"\\","mpcInfo.theme.txt");
+    f = fopen(hFile,"r");
+    if(f==NULL)
+	{
+		xchat_print(ph,"no theme in homedir, checking global theme");
+		f=fopen("mpcInfo.theme.txt","r");
+    }
+	//xchat_printf(ph,"file_desc: %p\n",f);
+	if (f==NULL) xchat_print(ph, "no theme found, using hardcoded\n");
+	else {
+		if (f > 0)
+		{
+			line=" ";
+		} else
+		{
+			line="\0";
+		}
+
+		while (line[0]!=0)
+		{
+			line=readLine(f);
+			val=split(line,'=');
+			printf("line: %s\n",line);
+			printf("val: %s\n",val);
+			if (strcmp(toUpper(line),"OFF_LINE")==0) notRunTheme=themeAdd(notRunTheme,val);
+			if (strcmp(toUpper(line),"TITLE_LINE")==0) titleTheme=themeAdd(titleTheme,val);
+			if (strcmp(toUpper(line),"MP3_LINE")==0) mp3Theme=themeAdd(mp3Theme,val);
+			if (strcmp(toUpper(line),"OGG_LINE")==0) mp3Theme=themeAdd(oggTheme,val);
+		}
+		fclose(f);
+		xchat_print(ph, "theme loaded successfull\n");
+	}
+	if (notRunTheme.size==0) notRunTheme=themeAdd(notRunTheme,"say Media Player Classic not running");
+	if (titleTheme.size==0) titleTheme=themeAdd(titleTheme,"say Playing %title in Media Player Classic");
+	if (mp3Theme.size==0) mp3Theme=themeAdd(mp3Theme,"me listens to %art with %tit from %alb [%gen|%br kbps|%frq kHz|%mode] in Media Player Classic ");
+	if (oggTheme.size==0) oggTheme=themeAdd(oggTheme,"me listens to %art with %tit from %alb [%gen|%br kbps|%frq kHz|%chan channels] in Media Player Classic ");
+	//mp3Theme=themeAdd(mp3Theme,"me listens to %art with %tit from %alb [%time|%length|%perc%|%br kbps|%frq kHz|%mode] in Media Player Classic ");
+}
+
+int rnd(int max){
+    return rand()%max;
+}
+
+char *randomLine(struct theme data){
+     return data.line[rnd(data.size)];
+}