Browse Source

initial code

Nikola Kotur 6 years ago
commit
6c4af8201d
10 changed files with 1826 additions and 0 deletions
  1. 7 0
      ChangeLog
  2. 26 0
      INSTALL
  3. 15 0
      LICENSE
  4. 31 0
      README
  5. 5 0
      TODO
  6. 262 0
      Xlib_textfader.cc
  7. 145 0
      Xlib_textfader.h
  8. 1089 0
      configuration.h
  9. 59 0
      myhelpfunctions.h
  10. 187 0
      titlefader.cc

+ 7 - 0
ChangeLog

@@ -0,0 +1,7 @@
+12.05.04 - version 0.4.8
+slightly modified - Nikola Kotur
+
+16.04.02 - version 0.4.7
+first official release
+why i named it 0.4.7?? My sense told me to do :)
+

+ 26 - 0
INSTALL

@@ -0,0 +1,26 @@
+1. Read the LICENSE file. It's the BSD license.
+
+2. compile the source code.
+     g++ -shared `gtk-config --cflags --libs` titlefader.cc -o libtitlefader.so
+
+	 Nikola Kotur's remark:
+	 Youd probably should add -Wno-deprecated to avoid annoying warrning
+	 about deprecetated include statements, and for ignoring namespace
+	 conventions, which is a buzz anyway :)
+
+3. install it.
+   
+   if you want to install the plugin locally
+     mv libtitlefader.so ~/.xmms/Plugins/General
+   make sure .xmms/Plugins/General exists!
+   
+
+   if you want to install the plugin system wide
+     mv libtitlefader.so `xmms-config --general-plugin-dir`
+   Probably you have to become root.
+
+4. configure the plugin. Just play around and you'll understand the
+   configuration dialog. Use the test button!!
+               ---------------------
+     at least: | !!CHOOSE A FONT!! |
+               ---------------------

+ 15 - 0
LICENSE

@@ -0,0 +1,15 @@
+Copyright (c) 2002, Marc Bruenink
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. 
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+

+ 31 - 0
README

@@ -0,0 +1,31 @@
+This piece of code was written by Marc Bruenink.
+I took his code and made some modifications, mainly
+throwing out fade option (just putting plain name song
+without fade-out fun), and making it stable
+with my version of XMMS.
+
+Nikola Kotur <kotnik@ns-linux.org>
+
+
+-- Original README:
+
+if you want to install: just read INSTALL
+
+
+
+
+
+--------------------------
+|my code classifications:|
+--------------------------
+
+great and functional but upgradable (of course):
+  myhelpfunctions.h ( why a header?? i don't know ;)
+  Xlib_textfader.h
+  Xlib_textfader.cc
+
+simple & pseudo c++:
+  titlefader.cc
+
+fucking code but operative (at least)
+  configuration.h (should be splited in h and cc)

+ 5 - 0
TODO

@@ -0,0 +1,5 @@
+split configuration.h -> .h and .cc
+program milisecond in xlibtextfader
+configure script
+.deb .rpm
+cleanup code

+ 262 - 0
Xlib_textfader.cc

@@ -0,0 +1,262 @@
+/**
+ *
+ * Copyright (c) 2002, Marc Bruenink
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of his contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+
+#ifndef _XLIB_TEXTFADER_CPP_
+#define _XLIB_TEXTFADER_CPP_
+
+#include "Xlib_textfader.h"
+#include <time.h> // test
+
+  
+Xlib_textfader::Xlib_textfader(){
+    
+    dpy = XOpenDisplay(NULL);
+    screen = DefaultScreen(dpy);
+    screenWidth = XDisplayWidth(dpy, screen);
+    screenHeight = XDisplayHeight(dpy, screen);
+    screenDepth = DefaultDepth(dpy, screen);
+    screenVisual = DefaultVisual(dpy,screen);
+    font = NULL;
+    attrValueMask = 0;
+    gc_valValueMask = 0;
+    
+
+    // don't use the window manager
+    attr.override_redirect = True;
+    attrValueMask |= CWOverrideRedirect;
+    
+}
+  
+  Xlib_textfader::~Xlib_textfader(){
+    XFreeFont(dpy, font);
+    
+    XCloseDisplay(dpy);
+  }
+  
+
+int  Xlib_textfader::fade(char* text, int iTextLength, unsigned int steps,unsigned long optionmask=0){
+
+  if (font == NULL) return 0;
+
+  Window win;
+  XEvent event;
+  //int pos_y=0, pos_x=0;
+  unsigned long pix;
+  int iRand;
+  XImage *backImg, *dstImg;
+  int iWindowWidth, iWindowHeight;
+  int iModCount = 0;
+
+  // init vars
+  iWindowWidth = XTextWidth(font, text, iTextLength);
+  iWindowHeight = get_font_height();
+
+
+  XSync(dpy, False);
+  
+  if (optionmask & (1<<1)) {
+    // TF_WINDOW_CENTER
+    pos_y = screenHeight / 2;
+    pos_x = screenWidth / 2;
+    optionmask |= (1<<2);
+    pos_y -= iWindowHeight / 2;
+    pos_x -= iWindowWidth / 2;
+  }
+
+	switch(TF_COORDINATES_GET(optionmask)) {
+	case TF_COORDINATES_UPPER_LEFT:
+		// nothing to change:
+		break;
+	case TF_COORDINATES_UPPER_CENTER:
+		pos_x -= iWindowWidth /2;
+		break;
+	case TF_COORDINATES_UPPER_RIGHT:
+		pos_x -= iWindowWidth;
+		break;
+
+	case TF_COORDINATES_CENTER_LEFT:
+		pos_y -= iWindowHeight / 2;
+		break;
+	case TF_COORDINATES_CENTER_CENTER:
+		pos_y -= iWindowHeight / 2;
+		pos_x -= iWindowWidth /2;
+		break;
+	case TF_COORDINATES_CENTER_RIGHT:
+		pos_y -= iWindowHeight / 2;
+		pos_x -= iWindowWidth;
+		break;
+	case TF_COORDINATES_LOWER_LEFT:
+		pos_y -= iWindowHeight;
+		break;
+	case TF_COORDINATES_LOWER_CENTER:
+		pos_y -= iWindowHeight;
+		pos_x -= iWindowWidth /2;
+		break;
+	case TF_COORDINATES_LOWER_RIGHT:
+		pos_y -= iWindowHeight;
+		pos_x -= iWindowWidth;
+		break;
+	}
+
+
+
+	// if you want to fade there... ok its your problem, but i have NOT to
+	// fade and produce a Bad Match so i say hey i've faded and return 1
+	if ((pos_x >= screenWidth) || (pos_y >=screenHeight)) {
+		return 1;
+	}
+
+	// perhaps i've to code a better solution with half seeable windows 
+	// in the left and top
+	if((pos_x < 0 ) || (pos_y < 0)) {
+	  return 0;
+	}
+
+	if ((pos_x+iWindowWidth) > screenWidth) {
+		iWindowWidth = screenWidth - pos_x;
+	}
+	if ((pos_y + iWindowHeight) > screenHeight) {
+		iWindowHeight = screenHeight - pos_y;
+	}
+	
+	win = XCreateWindow(dpy, DefaultRootWindow(dpy), pos_x, pos_y, iWindowWidth, iWindowHeight, 0, screenDepth, InputOutput, screenVisual,  attrValueMask, &attr);
+
+
+  // m o v e     your ass!!
+  
+  XSelectInput(dpy, win, ExposureMask);
+  
+  GC gc = XCreateGC(dpy, win, gc_valValueMask, &gc_val);
+  
+  XFlush(dpy);
+  XMapWindow(dpy, win);
+  XFlush(dpy);
+
+
+    while(1){
+    XNextEvent(dpy,&event);
+    switch(event.type){
+    case Expose:
+
+
+      // save background
+//      backImg = XGetImage(dpy, win, 0, 0, iWindowWidth, iWindowHeight, AllPlanes, XYPixmap);
+
+      XDrawString(dpy,win,gc,0 ,get_font_height(), text, iTextLength);
+      XSync(dpy,False);
+
+//      dstImg = XGetImage(dpy, win, 0, 0, iWindowWidth, iWindowHeight, AllPlanes,XYPixmap);
+
+	sleep(steps/100);
+/*
+      for(int iCountSteps = 0;iCountSteps < steps; iCountSteps++) {
+	for (int y=0; y< iWindowHeight ;y++) {
+	  for (int x=0; x< iWindowWidth ; x++) {
+
+	  // print pixel??
+	    pix = XGetPixel(dstImg, x ,y);
+	    if (pix == gc_val.foreground) {
+	      if ((rand() % (int)(steps - iCountSteps))==0) {}
+		//XPutPixel(dstImg, x, y, XGetPixel(backImg, x, y));
+	    }
+	  }
+	}
+	//XPutImage(dpy, win, gc, dstImg, 0,0,0,0,iTextLength * get_font_width(), get_font_height());
+      }
+*/
+//      XDestroyImage(dstImg);
+//      XDestroyImage(backImg);
+      XFreeGC(dpy ,gc);
+      XDestroyWindow(dpy,win);
+      XSync(dpy,False);
+      return True;
+    }
+  }
+    //  }// end test for
+
+  return True;
+}
+
+int Xlib_textfader::get_font_height(){
+  return font->max_bounds.ascent + font->max_bounds.descent;
+}
+
+int Xlib_textfader::get_font_width() {
+  return font->max_bounds.rbearing + font->max_bounds.lbearing;
+}
+
+int Xlib_textfader::set_font(char *name){
+  //    if (font != NULL) XFreeFont(dpy,font);
+    font = XLoadQueryFont(dpy, name);
+    if (font == NULL) 
+      return 0;
+    gc_val.font = font->fid;
+    gc_valValueMask |= GCFont;
+    XSync(dpy,False);
+    return 1;
+  }
+
+char** Xlib_textfader::get_list_fonts(int* count, char *pattern="*"){
+  return XListFonts(dpy, "*", INT_MAX, count);
+}
+
+
+int Xlib_textfader::set_text_color(char *name) {
+    XColor exactColor;
+    int ret;
+ 
+    ret = XAllocNamedColor(dpy, DefaultColormap(dpy, screen), name, &textColor, &exactColor); 
+    if (ret) {
+      gc_val.foreground =  textColor.pixel;
+      gc_valValueMask |= GCForeground;
+    }
+ return ret;
+}
+
+int Xlib_textfader::set_text_color(double red, double green, double blue) {
+  XColor col;
+  int ret;
+
+
+
+  col.red =  (unsigned short)(65535 * red);
+  col.green =  (unsigned short)(65535 * green);
+  col.blue =  (unsigned short)(65535 * blue);
+  ret = XAllocColor(dpy, DefaultColormap(dpy, 0), &col);
+  if (ret) {
+      gc_val.foreground =  col.pixel;
+      gc_valValueMask |= GCForeground;
+    }
+  return ret;
+  }
+#endif

+ 145 - 0
Xlib_textfader.h

@@ -0,0 +1,145 @@
+/**
+ *
+ * Copyright (c) 2002, Marc Bruenink
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of his contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef _XLIB_TEXTFADER_H_
+#define _XLIB_TEXTFADER_H_
+
+#include <X11/Xlib.h>
+#include <X11/Xcms.h>   // color 
+#include <X11/Xutil.h> // XGetPixel
+
+#include <climits> // MAX_INT
+#include <ostream.h>
+#include <unistd.h>
+#include <stdlib.h> //rand() 
+
+// class define
+
+//text will be faded in the center of the screen. 
+#define TF_WINDOW_CENTER (1<<1)
+
+// Coordinates marks the middlex and middley of the text 
+// default: upper left corner of text
+//#define TF_COORDINATES_CENTER (1<<2)
+
+
+// some defines for the arrangement method
+// first 2 bytes marks the row and last 2 bytes the column
+// use XOR !!!!
+#define TF_COORDINATES_UPPER_LEFT 	((1<<2)		|(1<<4))
+#define TF_COORDINATES_UPPER_CENTER 	((1<<2)		|(1<<5))
+#define TF_COORDINATES_UPPER_RIGHT  	((1<<2)		|(1<<4)|(1<<5))
+#define TF_COORDINATES_CENTER_LEFT	((1<<3)		|(1<<4))
+#define TF_COORDINATES_CENTER_CENTER	((1<<3)		|(1<<5))
+#define TF_COORDINATES_CENTER_RIGHT	((1<<3)		|(1<<4)|(1<<5))
+#define TF_COORDINATES_LOWER_LEFT		((1<<2)|(1<<3)	|(1<<4))
+#define TF_COORDINATES_LOWER_CENTER	((1<<2)|(1<<3)	|(1<<5))
+#define TF_COORDINATES_LOWER_RIGHT	((1<<2)|(1<<3)	|(1<<4)|(1<<5))
+#define TF_COORDINATES_SET(old, new)   ((old & (~((unsigned long) (1<<2)|(1<<3)|(1<<4)|(1<<5)))) | new)
+#define TF_COORDINATES_GET(old)		(old & ((unsigned long)(1<<2)|(1<<3)|(1<<4)|(1<<5)))
+
+
+class Xlib_textfader {
+
+   Display *dpy;
+   int screen;
+   int screenHeight, screenWidth;
+   int screenDepth;
+   Visual *screenVisual;
+   XFontStruct *font;
+   XGCValues gc_val;
+   unsigned long gc_valValueMask;
+   XSetWindowAttributes attr;
+   unsigned long attrValueMask;
+
+   XColor textColor;
+
+   // fade positions
+   int pos_x, pos_y;
+
+ public:
+
+   Xlib_textfader();
+   ~Xlib_textfader();
+
+
+
+   // fade section
+   int fade(char* text, int length, unsigned int fadeTime, unsigned long optionmask);
+   inline int get_fade_position_x() {
+     return pos_x;
+   }
+   inline int get_fade_position_y() {
+     return pos_y;
+   }
+   inline void set_fade_position_x(int _x){
+     pos_x = _x;
+   }
+   inline void set_fade_position_y(int _y) {
+     pos_y = _y;
+   }
+   inline void set_fade_position(int _x, int _y){
+     pos_y = _y;
+     pos_x = _x;
+   }
+
+
+
+   // font section
+   int get_font_height();
+   int get_font_width();
+   inline XFontStruct* get_font(){
+     return font;
+   }
+   int set_font(char* name);
+   char** get_list_fonts(int* count, char *pattern);
+
+
+   // screen section
+   inline int get_screen_height(){
+     return screenHeight;
+   }
+   inline int get_screen_width() {
+     return screenWidth;
+   }
+
+   // gc values section
+   int set_text_color(char* name);
+   int set_text_color(double red, double green, double blue);
+   inline unsigned long get_text_color(){
+     return gc_val.foreground;
+   }
+
+
+};// end class 
+
+#endif

+ 1089 - 0
configuration.h

@@ -0,0 +1,1089 @@
+/**
+ *
+ * Copyright (c) 2002, Marc Bruenink
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of his contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+
+#ifndef _TITLEFADER_CONFIG_H_
+#define _TITLEFADER_CONFIG_H_
+
+//#include <xmms/xmmsctrl.h>
+#include <xmms/configfile.h>
+
+#include <gtk/gtk.h>
+
+#include <string>
+
+#include <stdio.h> // sprintf
+
+#include "myhelpfunctions.h"
+#include "Xlib_textfader.h"
+//#include "positionsel.h"
+
+// error defines
+#define CONFIGCANNOTOPEN -1001
+
+// config defines
+// defines the upper value from the frame scale
+#define MAXFRAMESTOFADE 250
+#define XMMSCONFIGNAME "Title Fader Plugin"
+//pos_sel win = root window / POSSELCONFIGWIN2ROOTWIN
+#define POSSELCONFIGWIN2ROOTWIN 5
+
+class Config {
+
+
+private:
+    GtkWidget *win;
+    GtkWidget *hWinScale, *vWinScale;
+
+    GtkWidget *color, *font;
+	//positon selection drawable
+  GtkWidget* pos_sel;
+	  GtkWidget *frameScale;
+
+
+ 
+	// load help vars
+
+	gchar *vAlignComboSelection, *hAlignComboSelection;
+	
+
+	// handler id to block changed signal in position selection
+	guint pos_sel_changed_handler_id;
+
+    // back image position selection
+    GdkPixmap *pos_sel_pixmap;
+    //PositionSel pos_sel;
+
+    // xmms config file
+    ConfigFile *confFile;
+
+	// gtk widget alginment  combos
+	GtkWidget *vAlignCombo, *hAlignCombo;
+	
+	// i allways make a centered blending
+	// to implement different fading position i've to correct
+	// the x and y values.....
+	int xCorrect, yCorrect;
+
+	gchar *cArrangePoint;
+ 
+ public:
+
+	int vWinScalePos, hWinScalePos;
+	int frameScalePos;
+
+
+	unsigned long fadeOptions;
+    // last selected color   
+    gdouble col_selected[4];
+    // selected font
+    gchar * font_selected;
+
+    // width and height of position selection
+    int pos_sel_width, pos_sel_height;
+    int screen_width, screen_height;
+
+ public:
+  Config();
+  ~Config();
+
+
+	
+  // show the configuration window
+ int show();
+ void hide();
+  // button callbacks
+
+  // buttons
+ public:
+  void main_ok_button_clicked();
+  void main_test_button_clicked();
+  void main_cancel_button_clicked();
+  void main_center_button_clicked();
+  void main_color_button_clicked() ;
+  void main_font_button_clicked();	
+
+	void main_scale_value_changed(GtkWidget*);
+
+  void color_cancel_button_clicked();
+  void color_ok_button_clicked();
+  void font_ok_button_clicked();
+  void font_cancel_button_clicked();
+
+  //position selector callbacks
+ public:
+  void pos_sel_motion_notified(GtkWidget*,GdkEventButton*);
+  void pos_sel_exposed(GtkWidget*,GdkEventExpose*);
+  void pos_sel_configure(GtkWidget*, GdkEventConfigure*);
+  void pos_sel_mouse_released(GtkWidget*, GdkEventButton*);	
+
+	void main_pos_sel_combo_changed(GtkWidget*); 
+
+ private:
+  void pos_sel_update(GtkWidget *widget, const int& x, const int&y);
+  int read_values();
+  int save_values();
+  
+
+};
+
+
+/*
+  some pseudo oop funtions
+  button callbacks
+*/
+static void st_main_ok_button_clicked(GtkWidget*, Config*);
+static void st_main_test_button_clicked(GtkWidget*, Config*);
+static void st_main_cancel_button_clicked(GtkWidget*, Config*);
+static void st_main_center_button_clicked(GtkWidget*, Config*);
+static void st_main_font_button_clicked(GtkWidget *widget, Config *object);
+static void st_main_color_button_clicked(GtkWidget *widget, Config *object);
+static void st_main_win_closed(GtkWidget*, Config*);
+static void st_color_cancel_button_clicked(GtkWidget *widget, Config *config);
+static void st_color_ok_button_clicked(GtkWidget *widget, Config *config);
+static void st_font_ok_button_clicked(GtkWidget *widget, Config *config);
+static void st_font_cancel_button_clicked(GtkWidget *widget, Config *config);
+
+
+static void st_main_scale_value_changed(GtkWidget*, Config*);
+
+/*
+  yooo hoooo no O O (P)
+*/
+static void st_pos_sel_motion_notified(GtkWidget*, GdkEventButton*,Config*);
+static gint st_pos_sel_exposed(GtkWidget*,GdkEventExpose* ,Config*);
+static void st_pos_sel_configure(GtkWidget*,GdkEventConfigure* ,Config*);
+static void st_pos_sel_mouse_released(GtkWidget*, GdkEventButton*, Config*);
+
+static void st_main_pos_sel_combo_changed(GtkWidget*, /*GdkEventAny*,*/ Config*);
+/*
+  constructors
+*/
+Config::Config() {
+	
+  win = NULL;
+  screen_width = gdk_screen_width();
+  pos_sel_width = screen_width / POSSELCONFIGWIN2ROOTWIN;
+  screen_height = gdk_screen_height();
+  pos_sel_height = screen_height / POSSELCONFIGWIN2ROOTWIN;
+
+	/* load last values */
+	xCorrect = 0;
+	yCorrect = 0;
+	col_selected[0]=1;
+	col_selected[1]=1;
+	col_selected[2]=1;
+	col_selected[3]=1;
+
+	font_selected = NULL;
+	hWinScale = NULL;
+
+	vWinScalePos = screen_height / 2; 
+	hWinScalePos = screen_width / 2;
+	hAlignComboSelection = vAlignComboSelection = "center";
+	frameScalePos = 60;
+
+	
+	fadeOptions = TF_COORDINATES_CENTER_CENTER;
+	
+	read_values();
+}
+
+
+
+/*
+  destructor
+*/
+Config::~Config() {
+  g_free(font_selected);
+
+	gtk_widget_destroy(GTK_WIDGET(win));
+}
+
+
+/*
+  show main configuration window
+*/
+
+int Config::show() {
+  GtkWidget *hBox, *vBox, *vBox2, *hBox2;
+  GtkWidget *button;
+//  GtkWidget *frameScale;
+  GtkObject *adj;
+  GtkWidget *table, *frame;
+//GtkWidget *vWinScale, *hWinScale;
+	GtkWidget *label;
+
+  GList *glist=NULL; 
+
+
+  	read_values();
+
+	if (win != NULL) return 1;
+
+  // create window
+   win = gtk_window_new(GTK_WINDOW_DIALOG);
+   gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &win);
+   gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(st_main_win_closed), this);
+   //   gtk_signal_connect(GTK_OBJECT
+   gtk_window_set_title(GTK_WINDOW(win), "Title Fader Plugin - Configuration");
+   gtk_container_set_border_width (GTK_CONTAINER (win), 15);
+
+   
+   vBox = gtk_vbox_new(FALSE, 10);
+   gtk_container_add(GTK_CONTAINER(win), vBox);
+
+   // Color + Font + position row
+   hBox = gtk_hbox_new(FALSE, 10);
+   gtk_box_pack_start(GTK_BOX(vBox), hBox, FALSE, FALSE, 0);
+   // position selection
+   frame = gtk_frame_new("Position Selection");
+   gtk_box_pack_start(GTK_BOX(hBox), frame, FALSE, FALSE, 0);
+   table = gtk_table_new(6, 3, FALSE);
+   gtk_container_add(GTK_CONTAINER(frame), table);
+   
+
+   label = gtk_label_new("Just play around. You'll get it!!\nThe management of different sizes of the fade-window is influenced by your alignment choice.\n");
+   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+   gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+   gtk_table_attach((GtkTable*)table, label, 0, 3, 0, 1, GTK_SHRINK, GTK_SHRINK, 10, 10);
+   gtk_widget_show(label);
+
+
+
+
+      //position selection visualization
+
+   pos_sel = gtk_drawing_area_new();
+
+   gtk_drawing_area_size(GTK_DRAWING_AREA(pos_sel), pos_sel_width, pos_sel_height);
+
+   gtk_widget_set_events (pos_sel, GDK_EXPOSURE_MASK
+			  | GDK_BUTTON_PRESS_MASK
+			  | GDK_BUTTON_MOTION_MASK
+			  | GDK_POINTER_MOTION_HINT_MASK);
+   gtk_signal_connect (GTK_OBJECT (pos_sel), "expose_event", (GtkSignalFunc)st_pos_sel_exposed, this);
+   gtk_signal_connect (GTK_OBJECT(pos_sel),"configure_event", (GtkSignalFunc) st_pos_sel_configure, this);
+   gtk_signal_connect (GTK_OBJECT (pos_sel), "motion_notify_event", (GtkSignalFunc)st_pos_sel_motion_notified, this);
+   gtk_signal_connect (GTK_OBJECT (pos_sel), "button_press_event", (GtkSignalFunc)st_pos_sel_mouse_released, this);
+
+  //  gtk_signal_connect (GTK_OBJECT (pos_sel.pixmap), "button_press_event",  (GtkSignalFunc)st_pos_sel_button_pressed, NULL);
+
+   gtk_table_attach((GtkTable*)table, pos_sel, 0, 1, 1, 2, GTK_EXPAND, GTK_EXPAND, 10, 10);
+
+
+
+   // hWinScale
+
+   adj = gtk_adjustment_new(hWinScalePos,0, screen_width,1,10,0);
+ gtk_signal_connect(GTK_OBJECT(adj), "value_changed", GTK_SIGNAL_FUNC(st_main_scale_value_changed), this);
+
+ hWinScale = gtk_hscale_new((GtkAdjustment*)adj); 
+ gtk_scale_set_draw_value((GtkScale*)hWinScale, TRUE );
+ gtk_scale_set_digits((GtkScale*)hWinScale, 0);
+ gtk_scale_set_value_pos((GtkScale*)hWinScale, GTK_POS_TOP);
+ gtk_table_attach_defaults((GtkTable*)table, hWinScale, 0, 1, 2, 3);
+ gtk_widget_show(hWinScale);
+ // vWinScale
+
+ adj = gtk_adjustment_new(vWinScalePos,0,screen_height,1,10,0);
+ gtk_signal_connect(GTK_OBJECT(adj), "value_changed", GTK_SIGNAL_FUNC(st_main_scale_value_changed), this);
+ vWinScale = gtk_vscale_new((GtkAdjustment*)adj); 
+ gtk_scale_set_draw_value((GtkScale*)hWinScale, TRUE );
+ gtk_scale_set_digits((GtkScale*)vWinScale, 0);
+ gtk_scale_set_value_pos((GtkScale*)vWinScale, GTK_POS_LEFT);
+ gtk_table_attach((GtkTable*)table, vWinScale, 1, 2, 1, 2, GTK_EXPAND, GTK_FILL, 10, 0);
+ gtk_widget_show(vWinScale);
+
+
+hBox2 = gtk_hbox_new(FALSE, 10);
+	gtk_table_attach((GtkTable*)table, hBox2, 0, 3, 3, 4, GTK_EXPAND, GTK_EXPAND, 10, 10);
+	
+
+	label = gtk_label_new("choose v-alignment: ");
+	gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+	gtk_box_pack_start(GTK_BOX(hBox2), label, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+
+	vAlignCombo = gtk_combo_new();
+	
+	gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(vAlignCombo)->entry), FALSE);
+
+	//glist = g_list_alloc();
+    glist = g_list_append(glist, (void*)"above");
+    glist = g_list_append(glist,(void*) "center");
+    glist = g_list_append(glist, (void*)"under");
+   gtk_combo_set_popdown_strings(GTK_COMBO(vAlignCombo), glist) ;
+	g_list_free(glist);
+	glist = NULL;
+	
+	gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(vAlignCombo)->entry), vAlignComboSelection);
+	main_pos_sel_combo_changed(GTK_COMBO(vAlignCombo)->entry);
+
+	gtk_box_pack_start(GTK_BOX(hBox2), vAlignCombo, FALSE, FALSE, 0);
+	gtk_signal_connect(GTK_OBJECT(GTK_COMBO(vAlignCombo)->entry), "changed", GTK_SIGNAL_FUNC(st_main_pos_sel_combo_changed), this);
+	
+	gtk_widget_show(vAlignCombo);
+
+
+gtk_widget_show(hBox2);
+
+
+
+hBox2 = gtk_hbox_new(FALSE, 10);
+	gtk_table_attach((GtkTable*)table, hBox2, 0, 3, 4, 5, GTK_EXPAND, GTK_EXPAND, 10, 10);
+	
+	label = gtk_label_new("choose h-alignment: ");
+	gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+	gtk_box_pack_start(GTK_BOX(hBox2), label, FALSE, FALSE, 0);
+	gtk_widget_show(label);
+
+	hAlignCombo = gtk_combo_new();
+	gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(hAlignCombo)->entry), FALSE);
+	//glist = g_list_alloc();
+    glist = g_list_append(glist, (void*)"left");
+    glist = g_list_append(glist,(void*) "center");
+    glist = g_list_append(glist, (void*)"right");
+   gtk_combo_set_popdown_strings(GTK_COMBO(hAlignCombo), glist) ;
+	g_list_free(glist);
+	glist = NULL;
+
+	gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(hAlignCombo)->entry), hAlignComboSelection);
+	main_pos_sel_combo_changed(GTK_COMBO(hAlignCombo)->entry);
+
+	gtk_box_pack_start(GTK_BOX(hBox2), hAlignCombo, FALSE, FALSE, 0);
+
+		gtk_signal_connect(GTK_OBJECT(GTK_COMBO(hAlignCombo)->entry), "changed", GTK_SIGNAL_FUNC(st_main_pos_sel_combo_changed), this);
+
+	gtk_widget_show(hAlignCombo);
+
+
+gtk_widget_show(hBox2);
+
+
+ button = gtk_button_new_with_label(" center ");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(st_main_center_button_clicked), this);
+ gtk_table_attach((GtkTable*)table, button, 0, 1, 5, 6, GTK_FILL , GTK_FILL, 10, 10);
+ gtk_widget_show(button);
+
+  
+ gtk_widget_show(frame);
+ gtk_widget_show(table);
+
+
+ // color + font
+ //color
+ vBox2 = gtk_vbox_new(FALSE, 10);
+ gtk_box_pack_start(GTK_BOX(hBox), vBox2, FALSE, FALSE, 0);
+ color = gtk_color_selection_dialog_new("Title Fader Plugin - Color");
+
+ // set saved color!!
+ GtkColorSelection *colorsel;
+ colorsel = GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color)->colorsel);
+ 
+	//gtk_color_selection_get_color(colorsel, col_selected);
+	gtk_color_selection_set_color(colorsel, col_selected);
+ gtk_color_selection_set_opacity(colorsel, FALSE );
+ // color dialog ok button
+ gtk_signal_connect(GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(color)->ok_button), "clicked", GTK_SIGNAL_FUNC(st_color_ok_button_clicked), this);
+ // color dialog cancel button
+ gtk_signal_connect(GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(color)->cancel_button), "clicked", GTK_SIGNAL_FUNC(st_color_cancel_button_clicked), this);
+ // color dialog help button
+ // if you need help in a color selection dialog you're an idiot 
+ // so you're a normal user  ;-)
+ // but in fact if've not a good mind to create a help window. 
+ // it seems to be useless.
+ // Soooooooo...    Lets kill the help button
+ gtk_widget_destroy(GTK_COLOR_SELECTION_DIALOG(color)->help_button);
+
+ button = gtk_button_new_with_label(" choose color ");
+ gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_show), GTK_OBJECT(color));
+ gtk_box_pack_start(GTK_BOX(vBox2), button, FALSE, FALSE, 0);
+ gtk_widget_show(button);
+
+ //font selection
+ font = gtk_font_selection_dialog_new("Title Fader Plugin - Font");
+	gtk_font_selection_set_font_name(GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(font)->fontsel), font_selected);
+ // font selection ok button
+ gtk_signal_connect(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font)->ok_button), "clicked", GTK_SIGNAL_FUNC(st_font_ok_button_clicked), this);
+ // font selection cancel button
+ gtk_signal_connect(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font)->cancel_button), "clicked", GTK_SIGNAL_FUNC(st_font_cancel_button_clicked), this);
+
+   
+
+ button = gtk_button_new_with_label(" choose font ");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(st_main_font_button_clicked), this);
+ gtk_box_pack_start(GTK_BOX(vBox2), button, FALSE, FALSE, 0);
+ gtk_widget_show(button);
+ gtk_widget_show(vBox2);
+
+
+   gtk_widget_show(hBox);
+   
+   // frames row
+   hBox = gtk_hbox_new(FALSE, 10);
+   gtk_box_pack_start(GTK_BOX(vBox), hBox, TRUE, TRUE, 0);
+   label = gtk_label_new("\nChoose the number of frames:");
+   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+   gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+   gtk_box_pack_start(GTK_BOX(hBox), label, FALSE, FALSE, 0);
+   gtk_box_pack_start(GTK_BOX(hBox), NULL, TRUE, TRUE, 0);
+   gtk_widget_show(label);
+   gtk_widget_show(hBox);
+
+   adj = gtk_adjustment_new( frameScalePos, 0, 250, 1, 10, 0 );
+   frameScale = gtk_hscale_new((GtkAdjustment *)adj);
+   gtk_scale_set_draw_value((GtkScale*)frameScale, TRUE );
+   gtk_scale_set_digits((GtkScale*)frameScale, 0);
+   gtk_box_pack_start(GTK_BOX(vBox), frameScale, FALSE, FALSE, 0);
+   gtk_widget_show(frameScale);
+
+
+   
+   // button row
+   hBox = gtk_hbox_new(FALSE, 10);
+   gtk_box_pack_start(GTK_BOX(vBox), hBox, FALSE, FALSE, 0);
+
+   button = gtk_button_new_with_label(" Test ");
+   gtk_box_pack_start(GTK_BOX(hBox), button, FALSE, FALSE, 0);
+   gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(st_main_test_button_clicked), this);
+   gtk_widget_show(button);
+
+   button = gtk_button_new_with_label(" OK ");
+   gtk_box_pack_start(GTK_BOX(hBox), button, FALSE, FALSE, 0);
+   gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(st_main_ok_button_clicked), this);
+   gtk_widget_show(button);
+
+   button = gtk_button_new_with_label(" Cancel ");
+   gtk_box_pack_start(GTK_BOX(hBox), button, FALSE, FALSE, 0);
+   gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(st_main_cancel_button_clicked), this);
+   gtk_widget_show(button);
+
+
+   gtk_widget_show(hBox);
+
+
+
+
+   gtk_widget_show(vBox);
+
+   // free of charge 
+   gtk_widget_show_all (win);
+
+   
+   pos_sel_update(pos_sel, hWinScalePos/ POSSELCONFIGWIN2ROOTWIN, vWinScalePos / POSSELCONFIGWIN2ROOTWIN);
+
+}
+
+
+void Config::hide() {
+  
+  // gtk_widget_destroy(win);
+  //win = NULL;
+  gtk_widget_destroy(hWinScale);
+  hWinScale = NULL;
+  gtk_widget_destroy(vWinScale);
+  vWinScale = NULL;
+  gtk_widget_destroy(color);
+  color = NULL;
+  gtk_widget_destroy(font);
+  font = NULL;
+  gtk_widget_destroy(pos_sel);
+  pos_sel = NULL;
+
+}
+
+/*
+  main configuration window button callbacks
+*/
+
+static void st_main_win_closed(GtkWidget*, Config *conf) {
+  conf ->hide();
+}
+
+static void st_main_ok_button_clicked(GtkWidget *widget, Config *object){
+  object->main_ok_button_clicked();
+}
+static void st_main_test_button_clicked(GtkWidget *widget, Config *object){
+  object->main_test_button_clicked();
+}
+static void st_main_cancel_button_clicked(GtkWidget *widget, Config *object){
+  object->main_cancel_button_clicked();
+}
+static void st_main_center_button_clicked(GtkWidget *widget, Config *object){
+  object->main_center_button_clicked();
+}
+static void st_main_color_button_clicked(GtkWidget *widget, Config *object){
+  object->main_color_button_clicked();
+}
+static void st_main_font_button_clicked(GtkWidget *widget, Config *object){
+  object->main_font_button_clicked();
+}
+
+static void st_main_scale_value_changed(GtkWidget *widget, Config *config){
+	config->main_scale_value_changed(widget);
+}
+
+
+
+void Config::main_ok_button_clicked() {
+  //save!!
+  // reset plugin!!
+
+  
+  hWinScalePos =  (int)gtk_range_get_adjustment(GTK_RANGE(hWinScale))->value;
+  vWinScalePos =  (int)gtk_range_get_adjustment(GTK_RANGE(vWinScale))->value;
+  frameScalePos = (int)gtk_range_get_adjustment(GTK_RANGE(frameScale))->value;
+
+  save_values();
+  // implicit call of hide()
+  gtk_widget_destroy(win);
+  win = NULL;
+
+}
+
+void Config::main_test_button_clicked() {
+
+  if (font_selected == NULL) {
+    return;
+  }
+
+	Xlib_textfader fader;
+
+	fader.set_font(font_selected);
+	fader.set_text_color(col_selected[0], col_selected[1], col_selected[2]);
+	fader.set_fade_position(gtk_range_get_adjustment(GTK_RANGE(hWinScale))->value, gtk_range_get_adjustment(GTK_RANGE(vWinScale))->value);
+	fader.fade("Test button clicked!!", 21, gtk_range_get_adjustment(GTK_RANGE(frameScale))->value, fadeOptions);
+}
+
+void Config::main_cancel_button_clicked() {
+  read_values();
+  gtk_widget_destroy(win);
+  win= NULL;
+}
+
+void Config::main_center_button_clicked() {
+  GtkAdjustment *adj;
+
+	// block changed signal
+	//gtk_signal_handler_block_by_func(GTK_OBJECT(gtk_range_get_adjustment(GTK_RANGE(vWinScale))), GTK_SIGNAL_FUNC(st_main_scale_value_changed),NULL);
+
+
+  adj = gtk_range_get_adjustment((GtkRange*)vWinScale);
+  gtk_adjustment_set_value(adj, (adj->upper - adj->lower) / 2);
+
+
+//gtk_signal_emit_stop_by_name(GTK_OBJECT(gtk_range_get_adjustment(GTK_RANGE(vWinScale))), "value_changed");
+
+
+	//gtk_signal_handler_unblock_by_func(GTK_OBJECT(gtk_range_get_adjustment(GTK_RANGE(vWinScale))), GTK_SIGNAL_FUNC(st_main_scale_value_changed),NULL);
+
+  //gtk_signal_handler_block_by_func(GTK_OBJECT(gtk_range_get_adjustment(GTK_RANGE(hWinScale))), GTK_SIGNAL_FUNC(st_main_scale_value_changed),NULL);
+  adj = gtk_range_get_adjustment((GtkRange*)hWinScale);
+  gtk_adjustment_set_value(adj, (adj->upper - adj->lower) / 2);
+//gtk_signal_emit_stop_by_name(GTK_OBJECT(gtk_range_get_adjustment(GTK_RANGE(hWinScale))), "value_changed");
+
+  //gtk_signal_handler_unblock_by_func(GTK_OBJECT(gtk_range_get_adjustment(GTK_RANGE(hWinScale))), GTK_SIGNAL_FUNC(st_main_scale_value_changed),NULL);
+}
+
+void Config::main_font_button_clicked() {
+  gtk_widget_show(font);
+}
+
+void Config::main_color_button_clicked() {
+  //  gtk_widget_show(color);
+}
+
+
+// scale values changed
+void Config::main_scale_value_changed(GtkWidget *widget) {
+
+  pos_sel_update(pos_sel, gtk_range_get_adjustment(GTK_RANGE(hWinScale))->value / POSSELCONFIGWIN2ROOTWIN,   gtk_range_get_adjustment(GTK_RANGE(vWinScale))->value / POSSELCONFIGWIN2ROOTWIN);
+
+
+}
+
+
+
+/*
+  colorselectiondialog buttons
+*/
+
+static void st_color_cancel_button_clicked(GtkWidget *widget, Config *object){
+  object->color_cancel_button_clicked();
+}
+static void st_color_ok_button_clicked(GtkWidget *widget, Config *object){
+  object->color_ok_button_clicked();
+}
+
+void Config::color_cancel_button_clicked(){
+  GtkColorSelection *colorsel  = GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color)->colorsel);
+
+  gtk_color_selection_set_color(colorsel, col_selected);
+  gtk_widget_hide(color);
+}
+void Config::color_ok_button_clicked(){
+  GtkColorSelection *colorsel  = GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(color)->colorsel);
+  gtk_color_selection_get_color(colorsel, col_selected);
+  gtk_widget_hide(color);
+}
+
+
+/*
+  font selection dialog button callbacks
+*/
+static void st_font_ok_button_clicked(GtkWidget * widget, Config *config) {
+  config->font_ok_button_clicked();
+}
+static void st_font_cancel_button_clicked(GtkWidget * widget, Config *config) {
+  config->font_cancel_button_clicked();
+}
+
+void Config::font_ok_button_clicked() {
+  g_free(font_selected);
+
+  GtkFontSelection *fontsel =  GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(font)->fontsel);
+  font_selected = gtk_font_selection_get_font_name(fontsel);
+  gtk_widget_hide(font);
+}
+void Config::font_cancel_button_clicked() {
+  GtkFontSelection *fontsel =  GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(font)->fontsel);
+  gtk_font_selection_set_font_name(fontsel, font_selected);
+  gtk_widget_hide(font);
+}
+
+
+
+
+/*
+  position selector callbacks
+*/
+
+static void st_pos_sel_motion_notified(GtkWidget* widget, GdkEventButton *event, Config* config){
+  config->pos_sel_motion_notified(widget, event);
+}
+static gint st_pos_sel_exposed(GtkWidget* widget,GdkEventExpose *event, Config* config){
+  config->pos_sel_exposed(widget,event);
+  return TRUE;
+}
+static void st_pos_sel_configure(GtkWidget* widget, GdkEventConfigure *event, Config* config){
+  config->pos_sel_configure(widget, event);
+}
+static void st_pos_sel_mouse_released(GtkWidget* widget,  GdkEventButton *event, Config* config){
+    
+  config->pos_sel_mouse_released(widget, event);
+}
+static void st_main_pos_sel_combo_changed(GtkWidget* widget, /*GdkEventAny* event,*/ Config* config) {
+	config->main_pos_sel_combo_changed(widget/*, event*/);
+}
+
+
+
+void Config::pos_sel_motion_notified(GtkWidget *widget, GdkEventButton *event){
+  
+  gint x, y;
+
+  gtk_widget_get_pointer (widget, &x, &y);
+  gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)vWinScale), y * POSSELCONFIGWIN2ROOTWIN);
+  gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)hWinScale), x * POSSELCONFIGWIN2ROOTWIN);
+//  pos_sel_update(widget, x, y);
+}
+void Config::pos_sel_mouse_released(GtkWidget *widget, GdkEventButton *event){
+   
+ gint x, y;
+
+  gtk_widget_get_pointer (widget, &x, &y);
+  gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)vWinScale), y * POSSELCONFIGWIN2ROOTWIN);
+  gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)hWinScale), x * POSSELCONFIGWIN2ROOTWIN);
+//  pos_sel_update(widget, x, y);
+// value changed soo implicit call of pos_sel_update
+}
+void Config::pos_sel_exposed(GtkWidget *widget, GdkEventExpose *event){
+    //   gdk_draw_pixmap(widget->window, widget->style->black_gc, pos_sel_pixmap ,0,0,0, 0, 100, 100);
+  gdk_draw_pixmap(widget->window,
+                  widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                  pos_sel_pixmap,
+                  event->area.x, event->area.y,
+                  event->area.x, event->area.y,
+                  event->area.width, event->area.height); 
+
+}
+void Config::pos_sel_configure(GtkWidget *widget, GdkEventConfigure *event) {
+   if (pos_sel_pixmap)
+    gdk_pixmap_unref(pos_sel_pixmap);  
+
+ pos_sel_pixmap = gdk_pixmap_new(widget->window,
+                          widget->allocation.width,
+                          widget->allocation.height,
+                          -1);
+ pos_sel_update(widget, 0, 0);
+}
+void Config::main_pos_sel_combo_changed(GtkWidget* widget/*, GdkEventAny *event*/) {
+
+  std::string str;
+
+	// xy position corrections
+	str =(std::string)gtk_entry_get_text(GTK_ENTRY(widget));
+
+
+	// hey which fucking widget was changed ??
+	if (widget == GTK_COMBO(vAlignCombo)->entry) {
+
+	if (str == "under") {
+	yCorrect =	5;
+	if ((fadeOptions & TF_COORDINATES_CENTER_LEFT) ||
+	(fadeOptions & TF_COORDINATES_LOWER_LEFT)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_UPPER_LEFT);
+
+}else
+	if ((fadeOptions & TF_COORDINATES_CENTER_CENTER) ||
+	(fadeOptions & TF_COORDINATES_LOWER_CENTER)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_UPPER_CENTER);
+
+
+}else
+	if((fadeOptions & TF_COORDINATES_CENTER_RIGHT) ||
+	(fadeOptions & TF_COORDINATES_LOWER_RIGHT)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_UPPER_RIGHT);
+	
+}
+}
+	if (str == "above") {
+	yCorrect = -5;
+	if ((fadeOptions & TF_COORDINATES_UPPER_LEFT) ||
+	(fadeOptions & TF_COORDINATES_CENTER_LEFT)) {
+	fadeOptions = TF_COORDINATES_SET (fadeOptions, TF_COORDINATES_LOWER_LEFT);
+	
+}else
+	if ((fadeOptions & TF_COORDINATES_UPPER_CENTER) ||
+	(fadeOptions & TF_COORDINATES_CENTER_CENTER)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_LOWER_CENTER);
+	
+}else
+	if ((fadeOptions & TF_COORDINATES_UPPER_RIGHT) ||
+	(fadeOptions & TF_COORDINATES_CENTER_RIGHT)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_LOWER_RIGHT);
+	
+}
+}
+	if (str == "center") {
+	yCorrect = 0;
+	if ((fadeOptions & TF_COORDINATES_UPPER_LEFT) ||
+	(fadeOptions & TF_COORDINATES_LOWER_LEFT)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_CENTER_LEFT);
+	
+}else
+	if ((fadeOptions & TF_COORDINATES_UPPER_CENTER) ||
+	(fadeOptions & TF_COORDINATES_LOWER_CENTER)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_CENTER_CENTER);
+	
+}else
+	if ((fadeOptions &TF_COORDINATES_UPPER_RIGHT) ||
+	(fadeOptions & TF_COORDINATES_LOWER_RIGHT)) {
+	fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_CENTER_RIGHT);
+	
+}
+}
+}
+	else if (widget == GTK_COMBO(hAlignCombo)->entry){
+	if (str == "right") {
+	xCorrect = 50;
+	switch(TF_COORDINATES_GET(fadeOptions)) {
+	case TF_COORDINATES_UPPER_CENTER:
+	case TF_COORDINATES_UPPER_RIGHT:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_UPPER_LEFT);
+	
+		break;
+	case TF_COORDINATES_CENTER_CENTER:
+	case TF_COORDINATES_CENTER_RIGHT:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_CENTER_LEFT);
+	
+		break;
+	case TF_COORDINATES_LOWER_CENTER:
+	case TF_COORDINATES_LOWER_RIGHT:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_LOWER_LEFT);
+	
+		break;
+}
+}else
+	if(str == "left") {
+	xCorrect= -50;
+	switch(TF_COORDINATES_GET(fadeOptions)) {
+	case TF_COORDINATES_UPPER_LEFT:
+	case TF_COORDINATES_UPPER_CENTER:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_UPPER_RIGHT);
+	
+		break;
+	case TF_COORDINATES_CENTER_LEFT:
+	case TF_COORDINATES_CENTER_CENTER:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_CENTER_RIGHT);
+	
+		break;
+	case TF_COORDINATES_LOWER_LEFT:
+	case TF_COORDINATES_LOWER_CENTER:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_LOWER_RIGHT);
+	
+		break;
+}
+}else
+	if (str == "center") {
+	xCorrect = 0;
+	switch(TF_COORDINATES_GET(fadeOptions)) {
+	case TF_COORDINATES_UPPER_LEFT:
+	case TF_COORDINATES_UPPER_RIGHT:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_UPPER_CENTER);
+	
+		break;
+	case TF_COORDINATES_CENTER_LEFT:
+	case TF_COORDINATES_CENTER_RIGHT:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_CENTER_CENTER);
+	
+		break;
+	case TF_COORDINATES_LOWER_LEFT:
+	case TF_COORDINATES_LOWER_RIGHT:
+		fadeOptions = TF_COORDINATES_SET(fadeOptions, TF_COORDINATES_LOWER_CENTER);
+	
+		break;
+
+	}
+	}
+}
+	// complications: the life becomes meaningful   ;)
+	
+
+
+
+  pos_sel_update(pos_sel, gtk_range_get_adjustment(GTK_RANGE(hWinScale))->value / POSSELCONFIGWIN2ROOTWIN, gtk_range_get_adjustment(GTK_RANGE(vWinScale))->value / POSSELCONFIGWIN2ROOTWIN);
+
+
+}
+
+/*
+  private functions
+*/
+int Config::read_values(){
+	
+
+	ConfigFile *conf;
+	gchar *cBuffer;
+
+	if(!(conf = xmms_cfg_open_default_file())) {
+		return CONFIGCANNOTOPEN;
+	}
+
+
+	
+		
+	if(xmms_cfg_read_string(conf, "TitleFader", "color-red", &cBuffer)){
+		col_selected[0] = atoi(cBuffer);
+		g_free(cBuffer);
+	}
+
+
+	
+
+	if(xmms_cfg_read_string(conf, "TitleFader", "color-green", &cBuffer)) {
+		col_selected[1] = atoi(cBuffer);
+		g_free(cBuffer);
+	}
+
+
+	
+
+	if(xmms_cfg_read_string(conf, "TitleFader", "color-blue", &cBuffer)) {
+		col_selected[2] = atoi(cBuffer);
+		g_free(cBuffer);
+	}
+
+
+
+	
+	
+	if(xmms_cfg_read_string(conf, "TitleFader", "font", &cBuffer)) {
+	  font_selected = cBuffer;
+		cBuffer = NULL;
+	}
+
+
+	
+	
+	if(xmms_cfg_read_string(conf, "TitleFader", "vAlignComboSelection", &cBuffer)){
+		vAlignComboSelection = cBuffer;
+	}
+
+	if(xmms_cfg_read_string(conf, "TitleFader", "hAlignComboSelection", &cBuffer)) {
+		hAlignComboSelection = cBuffer;
+	}
+
+
+	
+	if (xmms_cfg_read_string(conf, "TitleFader", "vWinScalePos", &cBuffer)){
+		vWinScalePos = atoi(cBuffer);
+		g_free(cBuffer);
+	}
+
+
+	if (xmms_cfg_read_string(conf, "TitleFader", "hWinScalePos", &cBuffer)) {
+		hWinScalePos = atoi (cBuffer);
+		g_free(cBuffer);
+	}
+
+
+	if (xmms_cfg_read_string(conf, "TitleFader", "frameScalePos", &cBuffer)) {
+	  frameScalePos = atoi(cBuffer);
+	  g_free(cBuffer);
+	}
+
+	
+	if (xmms_cfg_read_string(conf, "TitleFader", "fadeoptions", &cBuffer)) {
+	  fadeOptions = atol(cBuffer);
+	  g_free(cBuffer);
+	}
+
+
+	xmms_cfg_free(conf);
+
+}
+
+int Config::save_values(){
+	
+
+	ConfigFile *conf;
+	char *cBuffer= new char[sizeof(float) * 8 + 1];
+		
+	if (!(conf = xmms_cfg_open_default_file())) {
+		return CONFIGCANNOTOPEN;
+	}
+
+	sprintf(cBuffer, "%f", (float)col_selected[0]);
+	xmms_cfg_write_string(conf, "TitleFader", "color-red", cBuffer);
+
+
+	sprintf(cBuffer, "%f", (float)col_selected[1]);
+	xmms_cfg_write_string(conf, "TitleFader", "color-green", cBuffer);
+
+
+	sprintf(cBuffer, "%f", (float)col_selected[2]);
+	xmms_cfg_write_string(conf, "TitleFader", "color-blue", cBuffer);
+
+
+	// font save
+	g_free(cBuffer);
+	  cBuffer = gtk_font_selection_get_font_name(GTK_FONT_SELECTION(GTK_FONT_SELECTION_DIALOG(font)->fontsel));
+
+	xmms_cfg_write_string(conf, "TitleFader", "font", cBuffer);
+
+	g_free(cBuffer);
+
+	
+	//save fade position
+	cBuffer = new char[sizeof(int) * 8 + 1];
+	sprintf(cBuffer, "%i",(int)((gtk_range_get_adjustment(GTK_RANGE(hWinScale)))->value));
+	xmms_cfg_write_string(conf, "TitleFader", "hWinScalePos", cBuffer);
+
+
+	sprintf(cBuffer, "%i", (int)((gtk_range_get_adjustment(GTK_RANGE(vWinScale)))->value));
+	xmms_cfg_write_string(conf, "TitleFader", "vWinScalePos", cBuffer);
+	
+
+	sprintf(cBuffer, "%i", (int)((gtk_range_get_adjustment(GTK_RANGE(frameScale)))->value));
+	xmms_cfg_write_string(conf, "TitleFader", "frameScalePos", cBuffer);
+
+	g_free(cBuffer);
+	
+
+	// save alignment
+	// don't free because its a pointer upon a pointer
+	cBuffer =  gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(hAlignCombo)->entry));
+	xmms_cfg_write_string(conf, "TitleFader", "hAlignComboSelection", cBuffer);
+
+
+	cBuffer = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(vAlignCombo)->entry));
+	xmms_cfg_write_string(conf, "TitleFader", "vAlignComboSelection", cBuffer);
+
+
+	cBuffer = new char[sizeof(long) * 8 + 1];
+	sprintf(cBuffer, "%u", fadeOptions);
+
+
+
+	xmms_cfg_write_string(conf, "TitleFader", "fadeOptions", cBuffer);
+	
+	g_free(cBuffer);
+
+	
+	// at the end: save it !!
+	xmms_cfg_write_default_file(conf);
+	xmms_cfg_free(conf);	
+		
+	
+
+}
+
+void Config::pos_sel_update(GtkWidget *widget, const int &_x, const  int &_y)  {
+  int x, y;
+  GdkRectangle update_rect;
+
+
+	// x y limiting
+  x = _x>pos_sel_width-1 ? pos_sel_width : _x;
+  x = _x<0 ? 0 : x;
+  y = _y>pos_sel_height-1 ? pos_sel_height : _y;
+  y = _y<0? 0: y;
+
+
+  update_rect.x = 0;
+  update_rect.y = 0;
+  update_rect.width = pos_sel_width;
+  update_rect.height = pos_sel_height;
+
+  
+
+  // bad delete change this!!
+  gdk_draw_rectangle (pos_sel_pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height);  
+
+
+
+  gdk_draw_rectangle(pos_sel_pixmap, widget->style->black_gc, 0, x- 50 + xCorrect,  y-5 + yCorrect, 100, 10);
+   gdk_draw_line(pos_sel_pixmap, widget->style->black_gc, -1, y, x -50+ xCorrect, y);
+   gdk_draw_line(pos_sel_pixmap, widget->style->black_gc,  x + 50 + xCorrect, y, pos_sel_width, y);
+
+   gdk_draw_line(pos_sel_pixmap, widget->style->black_gc, x, -1, x, y -5+ yCorrect);
+   gdk_draw_line(pos_sel_pixmap, widget->style->black_gc,  x, y +5+ yCorrect, x , pos_sel_height);
+
+  gtk_widget_draw (widget, &update_rect);
+
+
+}
+
+
+#endif

+ 59 - 0
myhelpfunctions.h

@@ -0,0 +1,59 @@
+/**
+ *
+ * Copyright (c) 2002, Marc Bruenink
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of his contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+
+#ifndef _MY_HELP_FUNCTIONS_H_
+#define _MY_HELP_FUNCTIONS_H_
+
+#include <string>
+
+char* convertString2Char(std::string str) {
+  char* cBuffer;
+  cBuffer = (char*) malloc( sizeof(char) * (str.size()+1));
+  int i;
+  for (i=0;i<str.size();i++) {
+    cBuffer[i]=str[i];
+  }
+  cBuffer[i] = '\0';
+  return cBuffer;
+}
+
+
+int getCharLength(char* ch) {
+  for (int iCount = 0;;iCount++) {
+  if (ch[iCount] == '\0')
+    return iCount+1;
+  }
+}
+
+
+#endif

+ 187 - 0
titlefader.cc

@@ -0,0 +1,187 @@
+/**
+ *
+ * Copyright (c) 2002, Marc Bruenink
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of his contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <ostream.h>
+
+#include <cstdlib>
+
+#include <string.h>
+
+#include <gtk-1.2/gtk/gtk.h>
+
+#include <xmms/plugin.h>
+#include <xmms/xmmsctrl.h>
+#include <xmms/util.h>
+
+
+// my includes
+#include "Xlib_textfader.cc"
+#include "configuration.h"
+#include "myhelpfunctions.h"
+
+#define VERSION "0.4.7"
+
+
+extern "C" void init();
+extern "C" void about();
+extern "C" void configure();
+extern "C" void cleanup();
+extern "C" GeneralPlugin *get_gplugin_info();
+
+
+
+GeneralPlugin plugin = { NULL,
+			   NULL,
+			   -1,
+			   "Title Fader Plugin "VERSION,
+			   init,
+			   about,
+			   configure,
+			   cleanup};
+ 
+gint iTimeout;
+int timeoutFunction(gpointer);
+
+gchar *cLastTitle = NULL;
+
+Xlib_textfader *fader;
+
+
+Config conf;
+
+extern "C" {
+
+  void init() {
+     iTimeout = gtk_timeout_add(50, timeoutFunction, NULL);
+     fader = new Xlib_textfader();
+;
+
+	
+  }// end init()
+
+  
+  void about() {
+    xmms_show_message("Title Fader Plugin", "This xmms plugin blends the title of new songs on screen.\n\n send all complaints & suggestions to:\nfidor@users.sourceforge.net\n\nhttp://xmms-titlefader.sourceforge.net", "OK", TRUE, NULL, NULL);
+  }// end about()
+
+  void configure() {
+//	delete conf;    	
+	//static Config conf;
+//	conf = new Config();
+
+
+        conf.show();
+  }//end configure()
+
+  void cleanup() {
+    if(iTimeout){
+     gtk_timeout_remove(iTimeout);
+    }
+
+    if (cLastTitle != NULL) {
+      g_free(cLastTitle);
+      cLastTitle = NULL;
+    }
+
+    delete fader;
+    
+  }//endcleanup()
+
+
+GeneralPlugin *get_gplugin_info(void)
+{
+	return &plugin;
+}
+
+
+} // end extern
+
+
+
+
+
+
+int timeoutFunction(gpointer gpData){
+
+
+  if (xmms_remote_is_playing(plugin.xmms_session) == TRUE) {
+    
+    gchar *cBuffer = NULL;
+    
+    cBuffer = xmms_remote_get_playlist_title(plugin.xmms_session, xmms_remote_get_playlist_pos(plugin.xmms_session));
+    
+    // print title
+    
+    if (cLastTitle != NULL) {
+      if ( strcmp(cBuffer, cLastTitle) != 0) {
+	
+     fader->set_text_color(conf.col_selected[0], conf.col_selected[1], conf.col_selected[2]);
+     fader->set_font(conf.font_selected);
+
+     fader->set_fade_position(conf.hWinScalePos,conf.vWinScalePos);
+
+     fader->fade(cBuffer, getCharLength(cBuffer)-1, conf.frameScalePos, conf.fadeOptions);
+      }
+    }
+    else {
+      fader->set_text_color(conf.col_selected[0], conf.col_selected[1], conf.col_selected[2]);
+     fader->set_font(conf.font_selected);
+
+     fader->set_fade_position(conf.hWinScalePos,conf.vWinScalePos);
+     fader->fade(cBuffer, getCharLength(cBuffer)-1, conf.frameScalePos, conf.fadeOptions);
+
+    }
+    
+    
+    // strcpy(cLastTitle, cBuffer);
+    
+    if(cLastTitle != NULL) {
+      g_free(cLastTitle);
+      cLastTitle = NULL;
+    }
+    
+    cLastTitle = strdup(cBuffer);
+
+    
+    
+    // save old values
+    
+    if (cBuffer != NULL){
+      g_free(cBuffer);
+      cBuffer=NULL;
+    }
+    
+
+  }// end if playing
+    
+return TRUE;
+} // end timeout()
+