changeset 4751:b87f8c707b7f

branch merge
author Andrew O. Shadoura <bugzilla@tut.by>
date Wed, 06 Aug 2008 22:33:27 +0300
parents 74134c731db6 (current diff) b86e9f9663f4 (diff)
children 22b7212eb3f9
files src/audacious/Makefile src/audacious/ui_about.c src/audacious/ui_albumart.c src/audacious/ui_credits.c src/audacious/ui_credits.h src/audacious/ui_dock.c src/audacious/ui_dock.h src/audacious/ui_equalizer.c src/audacious/ui_equalizer.h src/audacious/ui_fileinfo.c src/audacious/ui_fileinfo.h src/audacious/ui_hints.c src/audacious/ui_hints.h src/audacious/ui_jumptotrack.c src/audacious/ui_jumptotrack.h src/audacious/ui_jumptotrack_cache.c src/audacious/ui_jumptotrack_cache.h src/audacious/ui_main.c src/audacious/ui_main.h src/audacious/ui_main_evlisteners.c src/audacious/ui_main_evlisteners.h src/audacious/ui_manager.c src/audacious/ui_manager.h src/audacious/ui_playlist.c src/audacious/ui_playlist.h src/audacious/ui_playlist_evlisteners.c src/audacious/ui_playlist_evlisteners.h src/audacious/ui_playlist_manager.c src/audacious/ui_playlist_manager.h src/audacious/ui_skin.c src/audacious/ui_skin.h src/audacious/ui_skinned_button.c src/audacious/ui_skinned_button.h src/audacious/ui_skinned_equalizer_graph.c src/audacious/ui_skinned_equalizer_graph.h src/audacious/ui_skinned_equalizer_slider.c src/audacious/ui_skinned_equalizer_slider.h src/audacious/ui_skinned_horizontal_slider.c src/audacious/ui_skinned_horizontal_slider.h src/audacious/ui_skinned_menurow.c src/audacious/ui_skinned_menurow.h src/audacious/ui_skinned_monostereo.c src/audacious/ui_skinned_monostereo.h src/audacious/ui_skinned_number.c src/audacious/ui_skinned_number.h src/audacious/ui_skinned_playlist.c src/audacious/ui_skinned_playlist.h src/audacious/ui_skinned_playlist_slider.c src/audacious/ui_skinned_playlist_slider.h src/audacious/ui_skinned_playstatus.c src/audacious/ui_skinned_playstatus.h src/audacious/ui_skinned_textbox.c src/audacious/ui_skinned_textbox.h src/audacious/ui_skinned_window.c src/audacious/ui_skinned_window.h src/audacious/ui_skinselector.c src/audacious/ui_skinselector.h src/audacious/ui_svis.c src/audacious/ui_svis.h src/audacious/ui_urlopener.c src/audacious/ui_urlopener.h src/audacious/ui_vis.c src/audacious/ui_vis.h
diffstat 141 files changed, 20564 insertions(+), 20487 deletions(-) [+]
line wrap: on
line diff
--- a/HACKING	Wed Aug 06 22:30:35 2008 +0300
+++ b/HACKING	Wed Aug 06 22:33:27 2008 +0300
@@ -1,8 +1,6 @@
 Hacking / coding guide for Audacious and Audacious-plugins
 ==========================================================
 (C) Copyright 2008 Audacious Development Team
-Written by Matti 'ccr' Hämäläinen <ccr@tnsp.org>, and mercilessly
-edited by others.
 
 
 Preamble
@@ -90,6 +88,9 @@
   Discuss about it with fellow developers.
 
 
+- In the core, DO NOT WRITE CODE THAT IS DEPENDENT ON A SPECIFIC UI OR
+  INTERFACE. The core should NEVER care what interface is in use.
+
 
 Additional style guidelines
 ===========================
--- a/acinclude.m4	Wed Aug 06 22:30:35 2008 +0300
+++ b/acinclude.m4	Wed Aug 06 22:33:27 2008 +0300
@@ -91,18 +91,18 @@
 
 dnl ** Check for GNU make
 AC_DEFUN([AUD_CHECK_GNU_MAKE],[
-    AC_CACHE_CHECK([for GNU make],cv_gnu_make_command,[
-    cv_gnu_make_command=""
+    AC_CACHE_CHECK([for GNU make],_cv_gnu_make_command,[
+    _cv_gnu_make_command=""
     for a in "$MAKE" make gmake gnumake; do
         test "x$a" = "x" && continue
         if ( sh -c "$a --version" 2>/dev/null | grep "GNU Make" >/dev/null ) ; then
-            cv_gnu_make_command="$a"
+            _cv_gnu_make_command="$a"
             break
         fi
     done
     ])
-    if test "x$cv_gnu_make_command" != "x" ; then
-        MAKE="$cv_gnu_make_command"
+    if test "x$_cv_gnu_make_command" != "x" ; then
+        MAKE="$_cv_gnu_make_command"
     else
         AC_MSG_ERROR([** GNU make not found. If it is installed, try setting MAKE environment variable. **])
     fi
--- a/buildsys.mk.in	Wed Aug 06 22:30:35 2008 +0300
+++ b/buildsys.mk.in	Wed Aug 06 22:33:27 2008 +0300
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2007, Jonathan Schleifer <js-buildsys@webkeks.org>
+#  Copyright (c) 2007 - 2008, Jonathan Schleifer <js-buildsys@webkeks.org>
 #
 #  https://webkeks.org/hg/buildsys/
 #
@@ -73,11 +73,11 @@
 OBJS3 = ${OBJS2:.cxx=.o}
 OBJS4 = ${OBJS3:.d=.o}
 OBJS5 = ${OBJS4:.erl=.beam}
-OBJS += ${OBJS5:.m=.o}
-DEPS += ${OBJS:.o=.dep}
+OBJS6 = ${OBJS5:.m=.o}
+OBJS += ${OBJS6:.xpm=.o}
 
 .SILENT:
-.SUFFIXES: .beam .c .cc .cxx .d .dep .erl .m
+.SUFFIXES: .beam .c .cc .cxx .d .dep .erl .m .xpm
 .PHONY: all subdirs pre-depend depend install install-extra uninstall uninstall-extra clean distclean
 
 all:
@@ -94,17 +94,25 @@
 
 depend: pre-depend ${SRCS}
 	regen=0; \
+	deps=""; \
 	test -f .deps || regen=1; \
-	for i in ${SRCS}; do test $$i -nt .deps && regen=1; done; \
-	if test x"$$regen" = x"1" -a x"${DEPS}" != "x"; then \
+	for i in ${SRCS}; do \
+		case $$i in \
+			*.o) \
+				test $$i -nt .deps && regen=1; \
+				deps="$${deps%.o}.dep $$i"; \
+				;; \
+		esac; \
+	done; \
+	if test x"$$regen" = x"1" -a x"$$deps" != "x"; then \
 		${DEPEND_STATUS}; \
 		rm -f .deps; \
-		if ${MAKE} ${MFLAGS} ${DEPS}; then \
-			cat ${DEPS} >.deps; \
-			rm -f ${DEPS}; \
+		if ${MAKE} ${MFLAGS} $$deps; then \
+			cat $$deps >.deps; \
+			rm -f $$deps; \
 			${DEPEND_OK}; \
 		else \
-			rm -f .deps ${DEPS}; \
+			rm -f .deps $$deps; \
 			${DEPEND_FAILED}; \
 		fi; \
 	fi
@@ -113,6 +121,7 @@
 	${CPP} ${CPPFLAGS} -M $< >$@
 
 .d.dep:
+.xpm.dep:
 
 pre-depend:
 
@@ -196,6 +205,14 @@
 		${COMPILE_FAILED}; \
 	fi
 
+.xpm.o:
+	${COMPILE_STATUS}
+	if ${CC} ${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<; then \
+		${COMPILE_OK}; \
+	else \
+		${COMPILE_FAILED}; \
+	fi
+
 install: ${LIB} ${STATIC_LIB} ${PLUGIN} ${PROG} install-extra
 	for i in ${SUBDIRS}; do \
 		${DIR_ENTER}; \
--- a/po/ja.po	Wed Aug 06 22:30:35 2008 +0300
+++ b/po/ja.po	Wed Aug 06 22:33:27 2008 +0300
@@ -14,7 +14,7 @@
 "Project-Id-Version: audacious HEAD\n"
 "Report-Msgid-Bugs-To: http://bugzilla.atheme.org/\n"
 "POT-Creation-Date: 2008-06-21 08:26+0300\n"
-"PO-Revision-Date: 2008-03-31 14:53+0900\n"
+"PO-Revision-Date: 2008-07-08 12:25+0900\n"
 "Last-Translator: dai <d+po@vdr.jp>\n"
 "Language-Team: Japanese <ja@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -102,9 +102,8 @@
 msgstr "標準出力に全てのエラーと警告を表示する"
 
 #: src/audacious/main.c:277
-#, fuzzy
 msgid "Show version"
-msgstr "プレイヤを表示する"
+msgstr "ヴァージョンを表示する"
 
 #: src/audacious/main.c:279
 msgid "Used in macpacking"
@@ -168,7 +167,6 @@
 "モジュール読み込みがサポートされていません! プラグインは読み込まれません.\n"
 
 #: src/audacious/signals.c:47
-#, fuzzy
 msgid ""
 "\n"
 "Audacious has caught signal 11 (SIGSEGV).\n"
@@ -193,8 +191,8 @@
 "これはプログラムのバグで,通常の環境では起こりえません.\n"
 "現在の設定は保存されており,影響は受けていないはずです.\n"
 "\n"
-"このバグを http://bugs-meta.atheme.org にファイルしていただけると,Audacious "
-"の品質向上の手助けとなります.\n"
+"このバグを http://bugzilla.atheme.org/ にファイルしていただけると,"
+"Audacious の品質向上の手助けとなります.\n"
 "あなたのバグレポートの取り扱いを素早く済ませるために,このメッセージの全文と"
 "クラッシュしたときに何をしていたかの解説を含めてください:\n"
 "\n"
@@ -204,17 +202,18 @@
 "Stacktrace was unavailable. You might want to reproduce this problem while "
 "running Audacious under GDB to get a proper backtrace.\n"
 msgstr ""
+"スタックトレースが利用できませんでした.正しいバックトレースを取得するには,"
+"Audacious を GDB 経由で起動して問題を再現させる必要があります.\n"
 
 #: src/audacious/signals.c:79
-#, fuzzy
 msgid ""
 "\n"
 "Bugs can be reported at http://bugzilla.atheme.org/ against the Audacious or "
 "Audacious Plugins product.\n"
 msgstr ""
 "\n"
-"Audacious プロダクトのバグは http://bugs-meta.atheme.org にレポートしてくださ"
-"い.\n"
+"Audacious や Audacious プラグインのバグは http://bugzilla.atheme.org/ に"
+"レポートしてください.\n"
 
 #: src/audacious/signals.c:297
 msgid ""
@@ -2242,7 +2241,7 @@
 
 #: src/audacious/ui_preferences.c:205
 msgid "Select playlist font:"
-msgstr "プレイリスで使用するフォントの選択"
+msgstr "プレイリストで使用するフォントの選択"
 
 #: src/audacious/ui_preferences.c:206
 msgid "Use Bitmap fonts if available"
@@ -2308,13 +2307,15 @@
 
 #: src/audacious/ui_preferences.c:219
 msgid "Allow loading incomplete skins"
-msgstr ""
+msgstr "不完全なスキンの読み込みを許可する"
 
 #: src/audacious/ui_preferences.c:220
 msgid ""
 "If selected, audacious won't refuse loading broken skins. Use only if your "
 "favourite skin doesn't work"
 msgstr ""
+"これを使うと,audacious は壊れたスキンの読み込みを拒絶しません."
+"お気に入りのスキンが動かないときだけ使用してください."
 
 #: src/audacious/ui_preferences.c:224
 msgid "<b>Format Detection</b>"
--- a/po/sr.po	Wed Aug 06 22:30:35 2008 +0300
+++ b/po/sr.po	Wed Aug 06 22:33:27 2008 +0300
@@ -8,15 +8,14 @@
 "Project-Id-Version: sr\n"
 "Report-Msgid-Bugs-To: http://bugzilla.atheme.org/\n"
 "POT-Creation-Date: 2008-06-21 08:26+0300\n"
-"PO-Revision-Date: 2008-04-05 12:27+0200\n"
+"PO-Revision-Date: 2008-07-19 11:57+0200\n"
 "Last-Translator: Strahinja Kustudic <kustudic@gmail.com>\n"
 "Language-Team:  <en@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
-"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
 #: src/audacious/input.c:552
 #, c-format
@@ -99,9 +98,8 @@
 msgstr "Штампај све грешке и упозорења у stdout"
 
 #: src/audacious/main.c:277
-#, fuzzy
 msgid "Show version"
-msgstr "Прикажи плејер"
+msgstr "Прикажи верзију"
 
 #: src/audacious/main.c:279
 msgid "Used in macpacking"
@@ -139,7 +137,7 @@
 
 #: src/audacious/main.c:667
 msgid "Sorry, threads aren't supported on your platform.\n"
-msgstr "Жао мије, али ваша платформа не подржава нити.\n"
+msgstr "Жао ми је, али ваша платформа не подржава нити.\n"
 
 #: src/audacious/main.c:701
 #, c-format
@@ -163,7 +161,6 @@
 msgstr "Учитавање модула није подржано! Додаци неће бити учитани.\n"
 
 #: src/audacious/signals.c:47
-#, fuzzy
 msgid ""
 "\n"
 "Audacious has caught signal 11 (SIGSEGV).\n"
@@ -184,8 +181,8 @@
 "\n"
 "Audacious је ухватио сигнал 11 (SIGSEGV).\n"
 "\n"
-"Извињавамо се због непрелика, али Audacious је отказао.\n"
-"Ово је грешка у програму, и никед не би требала да се деси под нормалним "
+"Извињавамо се због неприлика, али Audacious је отказао.\n"
+"Ово је грешка у програму, и никад не би требала да се деси под нормалним "
 "околностима.\n"
 "Ваша тренутна конфигурација је сачувана и неби требала бити оштећена.\n"
 "\n"
@@ -201,16 +198,17 @@
 "Stacktrace was unavailable. You might want to reproduce this problem while "
 "running Audacious under GDB to get a proper backtrace.\n"
 msgstr ""
+"Траг стека није доступан. Могли бисте да репродукујете овај проблем док "
+"покрећете Audacious у GDB-у да бисте добили исправно стабло позивања.\n"
 
 #: src/audacious/signals.c:79
-#, fuzzy
 msgid ""
 "\n"
 "Bugs can be reported at http://bugzilla.atheme.org/ against the Audacious or "
 "Audacious Plugins product.\n"
 msgstr ""
 "\n"
-"Грешке за производ Audacious се могу пријавити на http://bugs-meta.atheme."
+"Грешке за производе Audacious и Audacious Plugins се могу пријавити на http://bugs-meta.atheme."
 "org\n"
 
 #: src/audacious/signals.c:297
@@ -380,11 +378,11 @@
 
 #: src/audacious/ui_credits.c:243
 msgid "Serbian (Latin):"
-msgstr "Спрски (Латиница):"
+msgstr "Српски (Латиница):"
 
 #: src/audacious/ui_credits.c:246
 msgid "Serbian (Cyrillic):"
-msgstr "Спрски (Ћирилица):"
+msgstr "Српски (Ћирилица):"
 
 #: src/audacious/ui_credits.c:249
 msgid "Simplified Chinese:"
@@ -529,7 +527,7 @@
 
 #: src/audacious/ui_fileinfo.c:106
 msgid "Pranks"
-msgstr "Пранкс"
+msgstr "Шале"
 
 #: src/audacious/ui_fileinfo.c:106
 msgid "Soundtrack"
@@ -573,7 +571,7 @@
 
 #: src/audacious/ui_fileinfo.c:109
 msgid "Acid"
-msgstr "Ацид"
+msgstr "Асид"
 
 #: src/audacious/ui_fileinfo.c:109
 msgid "House"
@@ -605,7 +603,7 @@
 
 #: src/audacious/ui_fileinfo.c:111
 msgid "Soul"
-msgstr "Соул"
+msgstr "Сол"
 
 #: src/audacious/ui_fileinfo.c:111
 msgid "Punk"
@@ -713,7 +711,7 @@
 
 #: src/audacious/ui_fileinfo.c:120
 msgid "Showtunes"
-msgstr "Музика из представа"
+msgstr "Музика из представе"
 
 #: src/audacious/ui_fileinfo.c:120
 msgid "Trailer"
@@ -729,11 +727,11 @@
 
 #: src/audacious/ui_fileinfo.c:121
 msgid "Acid Punk"
-msgstr "Ацид панк"
+msgstr "Асид панк"
 
 #: src/audacious/ui_fileinfo.c:121
 msgid "Acid Jazz"
-msgstr "Ацид џез"
+msgstr "Асид џез"
 
 #: src/audacious/ui_fileinfo.c:121
 msgid "Polka"
@@ -929,7 +927,7 @@
 
 #: src/audacious/ui_fileinfo.c:135
 msgid "A Cappella"
-msgstr "Капела"
+msgstr "А капела"
 
 #: src/audacious/ui_fileinfo.c:136
 msgid "Euro-House"
@@ -945,7 +943,7 @@
 
 #: src/audacious/ui_fileinfo.c:137
 msgid "Drum & Bass"
-msgstr "Драменбес"
+msgstr "Драменбејс"
 
 #: src/audacious/ui_fileinfo.c:137
 msgid "Club-House"
@@ -1276,7 +1274,7 @@
 msgstr ""
 "<big><b>Покварена GTK машина у употреби</b></big>\n"
 "\n"
-"Audacious је открио да корисите покварену GTK машину.\n"
+"Audacious је открио да користите покварену GTK машину.\n"
 "\n"
 "Машина за теме коју користите, <i>%s</i>, није компатибилна са неким од "
 "елемената које користе модерне маске. Некомпатибилне особине су искључене за "
@@ -1301,7 +1299,7 @@
 #: src/audacious/ui_main.c:1521
 #, c-format
 msgid "Volume: %d%%"
-msgstr "Јачин звука: %d%%"
+msgstr "Јачина звука: %d%%"
 
 #: src/audacious/ui_main.c:1549
 #, c-format
@@ -1357,7 +1355,7 @@
 "<b><big>Није могуће отворити аудио.</big></b>\n"
 "\n"
 "Молим вас проверите:\n"
-"1. Да ли сте изабрали добар излазни додатак .\n"
+"1. Да ли сте изабрали добар излазни додатак.\n"
 "2. Ниједан други програм не блокира звучну картицу.\n"
 "3. Ваша звучна картица је исправно подешена.\n"
 
@@ -1476,7 +1474,7 @@
 
 #: src/audacious/ui_manager.c:122
 msgid "Solid Scope"
-msgstr "Испунњен досег"
+msgstr "Испуњен досег"
 
 #: src/audacious/ui_manager.c:128
 msgid "Ice"
@@ -1641,7 +1639,7 @@
 
 #: src/audacious/ui_manager.c:228
 msgid "Refreshes metadata associated with a playlist entry."
-msgstr "Освежава мета-податке придружене ставки листе нурма."
+msgstr "Освежава мета-податке придружене ставки листе нумера."
 
 #: src/audacious/ui_manager.c:231
 msgid "List Manager"
@@ -1680,7 +1678,8 @@
 "Searches the playlist and selects playlist entries based on specific "
 "criteria."
 msgstr ""
-"Претржује листу нумера и означи ставке листе нумера по одређеном критеријуму."
+"Претражује листу нумера и означи ставке листе нумера по одређеном "
+"критеријуму."
 
 #: src/audacious/ui_manager.c:256
 msgid "Invert Selection"
@@ -1783,7 +1782,7 @@
 
 #: src/audacious/ui_manager.c:307
 msgid "Randomizes the playlist."
-msgstr "Насумице испремешта листу нумера."
+msgstr "Насумице испремешта ставке у листи нумера."
 
 #: src/audacious/ui_manager.c:310
 msgid "Reverse List"
@@ -1803,7 +1802,7 @@
 
 #: src/audacious/ui_manager.c:320 src/audacious/ui_manager.c:350
 msgid "By Artist"
-msgstr "По озвођачу"
+msgstr "По извођачу"
 
 #: src/audacious/ui_manager.c:321 src/audacious/ui_manager.c:351
 msgid "Sorts the list by artist."
@@ -1957,11 +1956,11 @@
 
 #: src/audacious/ui_manager.c:440
 msgid "Load auto-load preset"
-msgstr "Учитати Ауто-учитана претподешавања"
+msgstr "Учитати ауто-учитана претподешавања"
 
 #: src/audacious/ui_manager.c:442 src/audacious/ui_manager.c:463
 msgid "Default"
-msgstr "Подразумеванo"
+msgstr "Подразумевано"
 
 #: src/audacious/ui_manager.c:443
 msgid "Load default preset into equalizer"
@@ -2046,9 +2045,10 @@
 "expressions work, simply insert a literal portion of what you're searching "
 "for."
 msgstr ""
-"Обележи ставке у листи нумера попуњавајући једно или више поља. Поља користе "
-"синтаксу обичних израза, разликују величину слова. Ако не знате како обични "
-"изрази функционишу, једноставно унесите дословно део онога што тражите."
+"Обележи ставке у листи нумера попуњавајући једно или више поља. Поља "
+"користе синтаксу регуларних израза и разликују величину слова. Ако не знате како "
+"регуларни изрази функционишу, једноставно унесите дословно део онога што "
+"тражите."
 
 #: src/audacious/ui_playlist.c:463
 msgid "Title: "
@@ -2273,12 +2273,11 @@
 
 #: src/audacious/ui_preferences.c:213
 msgid "This enables the window manager to show decorations for windows."
-msgstr ""
-"Ово омогућава програму за управљањe прозорима да прикаже украсе на прозорима."
+msgstr "Ово омогућава програму за управљањe прозорима да прикаже украсе на прозорима."
 
 #: src/audacious/ui_preferences.c:214
 msgid "Use XMMS-style file selector instead of the default selector"
-msgstr "Користи  XMMS-ов селектор датотека уместо подразумеваног"
+msgstr "Користи XMMS-ов селектор датотека уместо подразумеваног"
 
 #: src/audacious/ui_preferences.c:215
 msgid ""
@@ -2309,13 +2308,15 @@
 
 #: src/audacious/ui_preferences.c:219
 msgid "Allow loading incomplete skins"
-msgstr ""
+msgstr "Дозволи учитавање непотпуних маски"
 
 #: src/audacious/ui_preferences.c:220
 msgid ""
 "If selected, audacious won't refuse loading broken skins. Use only if your "
 "favourite skin doesn't work"
 msgstr ""
+"Ако је укључено, Audacious неће забранити учитавање неисправних маски. Користите само "
+"ако ваша омиљена маска не ради"
 
 #: src/audacious/ui_preferences.c:224
 msgid "<b>Format Detection</b>"
@@ -2382,12 +2383,12 @@
 msgstr ""
 "Покушај да проследиш излаз улазног додатка директно у излазни додатак, ако "
 "каснији подржава формат који ствара улазни додатак. Ако је ово тачно, свака "
-"обрада сигнала ће бити искључена (нпр. DSP додаци, еквилајзер, Replay Gain и "
-"остала софтверска контрола јачине звука)."
+"обрада сигнала ће бити искључена (нпр. DSP додаци, еквилајзер, Replay Gain "
+"и остала софтверска контрола јачине звука)."
 
 #: src/audacious/ui_preferences.c:245
 msgid "<b>Replay Gain configuration</b>"
-msgstr "<b>Конфигурација Replay Gain-а</b>"
+msgstr "<b>Replay Gain конфигурација</b>"
 
 #: src/audacious/ui_preferences.c:246
 msgid "Enable Replay Gain"
@@ -2495,8 +2496,7 @@
 
 #: src/audacious/ui_preferences.c:275
 msgid "Load metadata when adding the file to the playlist or opening it"
-msgstr ""
-"Учитај мета-податке при додавању датотеке у листу или приликом отварања"
+msgstr "Учитај мета-податке при додавању датотеке у листу или приликом отварања"
 
 #: src/audacious/ui_preferences.c:276
 msgid "On display"
@@ -2507,8 +2507,9 @@
 "Load metadata on demand when displaying the file in the playlist. You may "
 "need to set \"Detect file formats on demand\" in Audio page for full benefit."
 msgstr ""
-"Учитај мета податке приликом приказивања датотеке у листи нумера. Можда ћете "
-"морати да поставите \"Преопознај формат датотеке на захтев\" у Аудио одељку."
+"Учитај мета-податке приликом приказивања датотеке у листи нумера. Можда "
+"ћете морати да поставите \"Препознај формат датотеке на захтев\" у Аудио "
+"одељку."
 
 #: src/audacious/ui_preferences.c:278
 msgid "<b>File Dialog</b>"
@@ -2625,7 +2626,7 @@
 
 #: src/audacious/ui_preferences.c:1566
 msgid "Delay until filepopup comes up: "
-msgstr "Закашњење појављивања искачућег проз. датоетеке: "
+msgstr "Закашњење појављивања искачућег проз. датотеке: "
 
 #: src/audacious/ui_preferences.c:1611
 msgid "Auto character encoding detector for:"
@@ -2675,15 +2676,14 @@
 
 #: src/audacious/ui_preferences.c:1726
 msgid "This gain will be used if file doesn't contain Replay Gain metadata."
-msgstr ""
-"Ово појачање ће се користити ако датотека не садржи Replay Gain метаподатке."
+msgstr "Ово појачање ће се користити ако датотека не садржи Replay Gain метаподатке."
 
 #: src/audacious/ui_preferences.c:1742
 msgid ""
 "<span size=\"small\">Please remember that the most efficient way to prevent "
 "signal clipping is not to use positive values above.</span>"
 msgstr ""
-"<span size=\"small\">Запамтите да најефикаснији начин да спречитеодсецање "
+"<span size=\"small\">Запамтите да најефикаснији начин да спречите одсецање "
 "сигнала је да не користите позитивне вредности изнад.</span>"
 
 #: src/audacious/ui_preferences.c:1975
@@ -2753,8 +2753,8 @@
 "number, track length, and artwork."
 msgstr ""
 "Укључује/искључује искачући прозор са информацијама за показану ставку у "
-"листи нумера. Прозор приказује име песме, име албума, жанр, годину издавања, "
-"број нумере, дужину нумере и слику."
+"листи нумера. Прозор приказује име песме, име албума, жанр, годину "
+"издавања, број нумере, дужину нумере и слику."
 
 #: src/audacious/ui_preferences.c:2196
 msgid "Edit settings for popup information"
@@ -2874,8 +2874,8 @@
 "<span size=\"small\">Changing these settings will require a restart of "
 "Audacious.</span>"
 msgstr ""
-"<span size=\"small\">Мењање ових подешавања ће захтевати поновно покретање "
-"Audacious-а.</span>"
+"<span size=\"small\">Мењање ових подешавања ће захтевати поновно "
+"покретање Audacious-а.</span>"
 
 #: src/audacious/ui_preferences.c:2745
 msgid "_Decoder list:"
@@ -2999,8 +2999,7 @@
 
 #: src/libeggsmclient/eggdesktopfile.c:1278
 msgid "Can't pass document URIs to a 'Type=Link' desktop entry"
-msgstr ""
-"Не могу да проследим адресе документа у ставку радне површи 'Тип=Link' "
+msgstr "Не могу да проследим адресе документа у ставку радне површи 'Тип=Link' "
 
 #: src/libeggsmclient/eggdesktopfile.c:1297
 msgid "Not a launchable item"
@@ -3034,11 +3033,3 @@
 msgid "Show Session Management options"
 msgstr "Прикажи опције управљања сесије"
 
-#~ msgid "Show version and builtin features"
-#~ msgstr "Прикажи верзију и уграђена својства"
-
-#~ msgid "Use custom cursors"
-#~ msgstr "Користи сопствени курсор"
-
-#~ msgid "Reload Plugins"
-#~ msgstr "Освежи додатке"
--- a/po/sr@Latn.po	Wed Aug 06 22:30:35 2008 +0300
+++ b/po/sr@Latn.po	Wed Aug 06 22:33:27 2008 +0300
@@ -8,15 +8,14 @@
 "Project-Id-Version: sr@Latn\n"
 "Report-Msgid-Bugs-To: http://bugzilla.atheme.org/\n"
 "POT-Creation-Date: 2008-06-21 08:26+0300\n"
-"PO-Revision-Date: 2008-04-05 12:25+0200\n"
+"PO-Revision-Date: 2008-07-19 11:56+0200\n"
 "Last-Translator: Strahinja Kustudic <kustudic@gmail.com>\n"
 "Language-Team:  <en@li.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
-"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
 #: src/audacious/input.c:552
 #, c-format
@@ -64,7 +63,7 @@
 
 #: src/audacious/main.c:268
 msgid "Pause if playing, play otherwise"
-msgstr "Pauziraj ako svira, inče pusti"
+msgstr "Pauziraj ako svira, inače pusti"
 
 #: src/audacious/main.c:269
 msgid "Skip forward in playlist"
@@ -99,13 +98,12 @@
 msgstr "Štampaj sve greške i upozorenja u stdout"
 
 #: src/audacious/main.c:277
-#, fuzzy
 msgid "Show version"
-msgstr "Prikaži plejer"
+msgstr "Prikaži verziju"
 
 #: src/audacious/main.c:279
 msgid "Used in macpacking"
-msgstr "Koristi se za macpakovanje"
+msgstr "Koristi se za makpakovanje"
 
 #: src/audacious/main.c:281
 msgid "FILE..."
@@ -135,7 +133,7 @@
 "<b><big>Nije moguće učitati masku.</big></b>\n"
 "\n"
 "Proverite da li je maska u '%s' upotrebljiva i da li je podrazumevana maska "
-"ispravno instalirana u '%s'\n"
+"pravilno instalirana u '%s'\n"
 
 #: src/audacious/main.c:667
 msgid "Sorry, threads aren't supported on your platform.\n"
@@ -163,7 +161,6 @@
 msgstr "Učitavanje modula nije podržano! Dodaci neće biti učitani.\n"
 
 #: src/audacious/signals.c:47
-#, fuzzy
 msgid ""
 "\n"
 "Audacious has caught signal 11 (SIGSEGV).\n"
@@ -193,7 +190,7 @@
 "meta.atheme.org\n"
 "Molim vas uključite celokupan tekst ove poruke i opišite nam šta ste radili "
 "kad se ovaj\n"
-"otkaz desio, da bismo brzo mogli obraditi Vaš izveštaj greške:\n"
+"otkaz dogodio, da bismo brzo mogli obraditi Vaš izveštaj greške:\n"
 "\n"
 
 #: src/audacious/signals.c:75
@@ -201,16 +198,17 @@
 "Stacktrace was unavailable. You might want to reproduce this problem while "
 "running Audacious under GDB to get a proper backtrace.\n"
 msgstr ""
+"Trag steka nije dostupan. Mogli biste da reprodukujete ovaj problem dok "
+"pokrećete Audacious u GDB-u da biste dobili ispravno stablo pozivanja.\n"
 
 #: src/audacious/signals.c:79
-#, fuzzy
 msgid ""
 "\n"
 "Bugs can be reported at http://bugzilla.atheme.org/ against the Audacious or "
 "Audacious Plugins product.\n"
 msgstr ""
 "\n"
-"Greške za proizvod Audacious se mogu prijaviti na http://bugs-meta.atheme."
+"Greške za proizvode Audacious i Audacious Plugins se mogu prijaviti na http://bugs-meta.atheme."
 "org\n"
 
 #: src/audacious/signals.c:297
@@ -268,7 +266,7 @@
 
 #: src/audacious/ui_credits.c:79
 msgid "Default skin:"
-msgstr "Podrazumevana Maska:"
+msgstr "Podrazumevana maska:"
 
 #: src/audacious/ui_credits.c:85
 msgid "Plugin development:"
@@ -288,7 +286,7 @@
 
 #: src/audacious/ui_credits.c:163
 msgid "Brazilian Portuguese:"
-msgstr "Brazilsko Posrtugalski:"
+msgstr "Brazilsko Portugalski:"
 
 #: src/audacious/ui_credits.c:167
 msgid "Breton:"
@@ -316,7 +314,7 @@
 
 #: src/audacious/ui_credits.c:186
 msgid "Estonian:"
-msgstr "Estonski"
+msgstr "Estonski:"
 
 #: src/audacious/ui_credits.c:189
 msgid "Finnish:"
@@ -388,7 +386,7 @@
 
 #: src/audacious/ui_credits.c:249
 msgid "Simplified Chinese:"
-msgstr "Uprošteni Kineski:"
+msgstr "Uprošten Kineski:"
 
 #: src/audacious/ui_credits.c:252
 msgid "Slovak:"
@@ -465,7 +463,7 @@
 
 #: src/audacious/ui_fileinfo.c:102
 msgid "Hip-Hop"
-msgstr "Hip Hop"
+msgstr "Hip hop"
 
 #: src/audacious/ui_fileinfo.c:103
 msgid "Jazz"
@@ -529,7 +527,7 @@
 
 #: src/audacious/ui_fileinfo.c:106
 msgid "Pranks"
-msgstr "Pranks"
+msgstr "Šale"
 
 #: src/audacious/ui_fileinfo.c:106
 msgid "Soundtrack"
@@ -537,7 +535,7 @@
 
 #: src/audacious/ui_fileinfo.c:107
 msgid "Euro-Techno"
-msgstr "Euro-Tehno"
+msgstr "Euro-tehno"
 
 #: src/audacious/ui_fileinfo.c:107
 msgid "Ambient"
@@ -573,7 +571,7 @@
 
 #: src/audacious/ui_fileinfo.c:109
 msgid "Acid"
-msgstr "Acid"
+msgstr "Asid"
 
 #: src/audacious/ui_fileinfo.c:109
 msgid "House"
@@ -605,7 +603,7 @@
 
 #: src/audacious/ui_fileinfo.c:111
 msgid "Soul"
-msgstr "Soul"
+msgstr "Sol"
 
 #: src/audacious/ui_fileinfo.c:111
 msgid "Punk"
@@ -677,7 +675,7 @@
 
 #: src/audacious/ui_fileinfo.c:117
 msgid "Top 40"
-msgstr "Najpolularnijih 40"
+msgstr "Najpopularnijih 40"
 
 #: src/audacious/ui_fileinfo.c:117
 msgid "Christian Rap"
@@ -729,11 +727,11 @@
 
 #: src/audacious/ui_fileinfo.c:121
 msgid "Acid Punk"
-msgstr "Acid pank"
+msgstr "Asid pank"
 
 #: src/audacious/ui_fileinfo.c:121
 msgid "Acid Jazz"
-msgstr "Acid džez"
+msgstr "Asid džez"
 
 #: src/audacious/ui_fileinfo.c:121
 msgid "Polka"
@@ -833,7 +831,7 @@
 
 #: src/audacious/ui_fileinfo.c:129
 msgid "Acoustic"
-msgstr "Akuctična"
+msgstr "Akustična"
 
 #: src/audacious/ui_fileinfo.c:129
 msgid "Humour"
@@ -929,7 +927,7 @@
 
 #: src/audacious/ui_fileinfo.c:135
 msgid "A Cappella"
-msgstr "A Cappella"
+msgstr "A kapela"
 
 #: src/audacious/ui_fileinfo.c:136
 msgid "Euro-House"
@@ -945,7 +943,7 @@
 
 #: src/audacious/ui_fileinfo.c:137
 msgid "Drum & Bass"
-msgstr "Dramenbes"
+msgstr "Dramenbejs"
 
 #: src/audacious/ui_fileinfo.c:137
 msgid "Club-House"
@@ -973,7 +971,7 @@
 
 #: src/audacious/ui_fileinfo.c:139
 msgid "Polsk Punk"
-msgstr "Poljsk pank"
+msgstr "Poljski pank"
 
 #: src/audacious/ui_fileinfo.c:139
 msgid "Beat"
@@ -1013,7 +1011,7 @@
 
 #: src/audacious/ui_fileinfo.c:142
 msgid "Thrash Metal"
-msgstr "Threš metal"
+msgstr "Treš metal"
 
 #: src/audacious/ui_fileinfo.c:143
 msgid "Anime"
@@ -1274,16 +1272,16 @@
 "\n"
 "To use these features, please consider using a different GTK theme engine."
 msgstr ""
-"<big><b>Pokrvarena GTK mašina u upotrebi</b></big>\n"
+"<big><b>Pokvarena GTK mašina u upotrebi</b></big>\n"
 "\n"
 "Audacious je otkrio da koristite pokvarenu GTK mašinu.\n"
 "\n"
-"Mašina za tema koju koristite, <i>%s</i>, nije kompatibilna sa nekim od "
-"elemenata koje koriste moderne maske. Nekompatibilne osobine su isključene "
-"za ovu sesiju.\n"
+"Mašina za teme koju koristite, <i>%s</i>, nije kompatibilna sa nekim od "
+"elemenata koje koriste moderne maske. Nekompatibilne osobine su isključene za "
+"ovu sesiju.\n"
 "\n"
-"Da biste koristili ove osobine, razmislite o korišćenju neke druge GTK "
-"mašine za teme."
+"Da biste koristili ove osobine, razmislite o korišćenju neke druge GTK mašine "
+"za teme."
 
 #: src/audacious/ui_main.c:1223
 msgid "Do not display this warning again"
@@ -1435,7 +1433,7 @@
 
 #: src/audacious/ui_manager.c:103
 msgid "Scope"
-msgstr "Dosega"
+msgstr "Doseg"
 
 #: src/audacious/ui_manager.c:104
 msgid "Voiceprint"
@@ -1504,11 +1502,11 @@
 
 #: src/audacious/ui_manager.c:144 src/audacious/ui_manager.c:152
 msgid "Slowest"
-msgstr "Najsporiji"
+msgstr "Najsporije"
 
 #: src/audacious/ui_manager.c:145 src/audacious/ui_manager.c:153
 msgid "Slow"
-msgstr "Spor"
+msgstr "Sporo"
 
 #: src/audacious/ui_manager.c:146 src/audacious/ui_manager.c:154
 msgid "Medium"
@@ -1576,7 +1574,7 @@
 
 #: src/audacious/ui_manager.c:195
 msgid "WindowShade VU Mode"
-msgstr "VU režim delimičnog skrivenog prozora"
+msgstr "VU režim delimično skrivenog prozora"
 
 #: src/audacious/ui_manager.c:196
 msgid "Refresh Rate"
@@ -1633,7 +1631,7 @@
 
 #: src/audacious/ui_manager.c:224
 msgid "Saves the selected playlist to the default location."
-msgstr "Sačuva izabranu listu numera u podrazumevanu lokaciju."
+msgstr "Sačuvaj izabranu listu numera u podrazumevanu lokaciju."
 
 #: src/audacious/ui_manager.c:227
 msgid "Refresh List"
@@ -1645,11 +1643,11 @@
 
 #: src/audacious/ui_manager.c:231
 msgid "List Manager"
-msgstr "Menađžer liste"
+msgstr "Menadžer liste"
 
 #: src/audacious/ui_manager.c:232
 msgid "Opens the playlist manager."
-msgstr "Otvara menađžer liste."
+msgstr "Otvara menadžer liste."
 
 #: src/audacious/ui_manager.c:238
 msgid "View"
@@ -1751,7 +1749,7 @@
 
 #: src/audacious/ui_manager.c:289
 msgid "Removes duplicate entries from the playlist by filename."
-msgstr "Uklanja duplikate iz liste numera na osnovu imenu datoteke."
+msgstr "Uklanja duplikate iz liste numera na osnovu imena datoteke."
 
 #: src/audacious/ui_manager.c:292 src/audacious/ui_manager.c:328
 #: src/audacious/ui_manager.c:358
@@ -1768,7 +1766,7 @@
 
 #: src/audacious/ui_manager.c:297
 msgid "Remove unselected entries from the playlist."
-msgstr "Uklanja neoznačene stavke iz listi numera."
+msgstr "Uklanja neoznačene stavke iz liste numera."
 
 #: src/audacious/ui_manager.c:300
 msgid "Remove Selected"
@@ -1776,7 +1774,7 @@
 
 #: src/audacious/ui_manager.c:301
 msgid "Remove selected entries from the playlist."
-msgstr "Uklanja označene stavke iz listi numera."
+msgstr "Uklanja označene stavke iz liste numera."
 
 #: src/audacious/ui_manager.c:306
 msgid "Randomize List"
@@ -1958,15 +1956,15 @@
 
 #: src/audacious/ui_manager.c:440
 msgid "Load auto-load preset"
-msgstr "Učitati аuto-učitana pretpodešavanja"
+msgstr "Učitati auto-učitana pretpodešavanja"
 
 #: src/audacious/ui_manager.c:442 src/audacious/ui_manager.c:463
 msgid "Default"
-msgstr "Podrazumevanо"
+msgstr "Podrazumevano"
 
 #: src/audacious/ui_manager.c:443
 msgid "Load default preset into equalizer"
-msgstr "Učitati podrazumevano pretpodešavawe u ekvilajzer"
+msgstr "Učitati podrazumevano pretpodešavanje u ekvilajzer"
 
 #: src/audacious/ui_manager.c:445
 msgid "Zero"
@@ -1990,7 +1988,7 @@
 
 #: src/audacious/ui_manager.c:452
 msgid "Load preset from WinAMP EQF file"
-msgstr "Učitati pretpodešavawe iz WinAMP EQF datoteke"
+msgstr "Učitati pretpodešavanje iz WinAMP EQF datoteke"
 
 #: src/audacious/ui_manager.c:454
 msgid "WinAMP Presets"
@@ -2048,8 +2046,8 @@
 "for."
 msgstr ""
 "Obeleži stavke u listi numera popunjavajući jedno ili više polja. Polja "
-"koriste sintaksu običnih izraza, razlikuju veličinu slova. Ako ne znate kako "
-"obični izrazi funkcionišu, jednostavno unesite doslovno deo onoga što "
+"koriste sintaksu regularnih izraza i razlikuju veličinu slova. Ako ne znate kako "
+"regularni izrazi funkcionišu, jednostavno unesite doslovno deo onoga što "
 "tražite."
 
 #: src/audacious/ui_playlist.c:463
@@ -2247,7 +2245,7 @@
 
 #: src/audacious/ui_preferences.c:206
 msgid "Use Bitmap fonts if available"
-msgstr "Koristi bit mapirane fontove, ako su dostupni"
+msgstr "Koristi bitmapirane fontove, ako su dostupni"
 
 #: src/audacious/ui_preferences.c:206
 msgid ""
@@ -2275,9 +2273,7 @@
 
 #: src/audacious/ui_preferences.c:213
 msgid "This enables the window manager to show decorations for windows."
-msgstr ""
-"Ovo omogućava programu za upravljanje prozorima da prikaže ukrase na "
-"prozorima."
+msgstr "Ovo omogućava programu za upravljanje prozorima da prikaže ukrase na prozorima."
 
 #: src/audacious/ui_preferences.c:214
 msgid "Use XMMS-style file selector instead of the default selector"
@@ -2302,7 +2298,7 @@
 "If selected, the file information text in the main window will scroll back "
 "and forth. If not selected, the text will only scroll in one direction."
 msgstr ""
-"Ako je uključeno, tekst koji prkazuje imformacije o datoteci u glavnom "
+"Ako je uključeno, tekst koji prikazuje informacije o datoteci u glavnom "
 "prozoru će klizati napred i nazad. Ako je isključeno, tekst će se klizati "
 "samo u jednom smeru."
 
@@ -2312,13 +2308,15 @@
 
 #: src/audacious/ui_preferences.c:219
 msgid "Allow loading incomplete skins"
-msgstr ""
+msgstr "Dozvoli učitavanje nepotpunih maski"
 
 #: src/audacious/ui_preferences.c:220
 msgid ""
 "If selected, audacious won't refuse loading broken skins. Use only if your "
 "favourite skin doesn't work"
 msgstr ""
+"Ako je uključeno, Audacious neće zabraniti učitavanje neispravnih maski. Koristite samo "
+"ako vaša omiljena maska ne radi"
 
 #: src/audacious/ui_preferences.c:224
 msgid "<b>Format Detection</b>"
@@ -2418,7 +2416,7 @@
 
 #: src/audacious/ui_preferences.c:252
 msgid "Use peak value from Replay Gain info for clipping prevention"
-msgstr "Koristi vrednost vrhunca iz Replay Gain-a kao zastitu od odsecanja"
+msgstr "Koristi vrednost vrhunca iz Replay Gain-a kao zaštitu od odsecanja"
 
 #: src/audacious/ui_preferences.c:253
 msgid "Dynamically adjust scale factor to prevent clipping"
@@ -2498,8 +2496,7 @@
 
 #: src/audacious/ui_preferences.c:275
 msgid "Load metadata when adding the file to the playlist or opening it"
-msgstr ""
-"Učitaj meta-podatke pri dodavanju datoteke u listu ili prilikom otvaranja"
+msgstr "Učitaj meta-podatke pri dodavanju datoteke u listu ili prilikom otvaranja"
 
 #: src/audacious/ui_preferences.c:276
 msgid "On display"
@@ -2528,7 +2525,7 @@
 "directories, and Gnome VFS should handle automatically)."
 msgstr ""
 "Uvek osveži okvir datoteke (ovo će usporiti otvaranje okvira za velike "
-"direktorijume, i GNOME VFS bi trebao automatski obaviti)."
+"direktorijume, i Gnome VFS bi trebao automatski obaviti)."
 
 #: src/audacious/ui_preferences.c:283
 msgid "<b>Mouse wheel</b>"
@@ -2633,7 +2630,7 @@
 
 #: src/audacious/ui_preferences.c:1611
 msgid "Auto character encoding detector for:"
-msgstr "Auto-prepozavanje kodiranja karaktera za:"
+msgstr "Auto-prepoznavanje kodiranja karaktera za:"
 
 #: src/audacious/ui_preferences.c:1630
 msgid ""
@@ -2643,13 +2640,13 @@
 "fall back conversion from these encodings to UTF-8 would be attempted."
 msgstr ""
 "Lista kodiranja karaktera koja se koriste za rezervnu konverziju meta-"
-"podataka. Ako automatsko prepoznavanje kodiranja ne uspe ili je isključeno, "
-"kodiranja u ovoj listi će biti kandidati za šifrovanje meta-podataka, i "
-"rezervna konverzija iz ovih kodiranja u UTF-8 će biti pokušana."
+"podataka. Ako automatsko prepoznavanje kodiranja karaktera ne upse ili je "
+"isključeno, kodiranja u ovoj listi će biti kandidati za šifrovanje meta-"
+"poataka, i rezervna konverzija iz ovih kodiranja u UTF-8 će biti pokušana."
 
 #: src/audacious/ui_preferences.c:1632
 msgid "Fallback character encodings:"
-msgstr "Rezervno kodiranja karaktera:"
+msgstr "Rezervno kodiranje karaktera:"
 
 #: src/audacious/ui_preferences.c:1660
 msgid "Output bit depth:"
@@ -2679,8 +2676,7 @@
 
 #: src/audacious/ui_preferences.c:1726
 msgid "This gain will be used if file doesn't contain Replay Gain metadata."
-msgstr ""
-"Ovo pojačanje će se koristiti ako datoteka ne sadrži Replay Gain metapodatke."
+msgstr "Ovo pojačanje će se koristiti ako datoteka ne sadrži Replay Gain metapodatke."
 
 #: src/audacious/ui_preferences.c:1742
 msgid ""
@@ -2770,7 +2766,7 @@
 
 #: src/audacious/ui_preferences.c:2316
 msgid "Buffer size:"
-msgstr "Veličina bafer:"
+msgstr "Veličina bafera:"
 
 #: src/audacious/ui_preferences.c:2322
 msgid ""
@@ -2971,7 +2967,7 @@
 
 #: src/audacious/ui_urlopener.c:86
 msgid "Add/Open URL Dialog"
-msgstr "Dodaj/otvori URL okvir"
+msgstr "Okvir dodaj/otvori URL"
 
 #: src/audacious/util.c:1047
 #, c-format
@@ -3003,8 +2999,7 @@
 
 #: src/libeggsmclient/eggdesktopfile.c:1278
 msgid "Can't pass document URIs to a 'Type=Link' desktop entry"
-msgstr ""
-"Ne mogu da prosledim adrese dokumenta u stavku radne površi 'Tip=Link' "
+msgstr "Ne mogu da prosledim adrese dokumenta u stavku radne površi 'Tip=Link' "
 
 #: src/libeggsmclient/eggdesktopfile.c:1297
 msgid "Not a launchable item"
@@ -3012,7 +3007,7 @@
 
 #: src/libeggsmclient/eggsmclient.c:183
 msgid "Disable connection to session manager"
-msgstr "Isključi vezu sa menadžerom sesije"
+msgstr "Isljuči vezu sa menadžerom sesije"
 
 #: src/libeggsmclient/eggsmclient.c:186
 msgid "Specify file containing saved configuration"
@@ -3038,11 +3033,3 @@
 msgid "Show Session Management options"
 msgstr "Prikaži opcije upravljanja sesije"
 
-#~ msgid "Show version and builtin features"
-#~ msgstr "Prikaži verziju i ugrađena svojstva"
-
-#~ msgid "Use custom cursors"
-#~ msgstr "Koristi sopstveni kursor"
-
-#~ msgid "Reload Plugins"
-#~ msgstr "Osveži dodatke"
--- a/src/audacious/Makefile	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/Makefile	Wed Aug 06 22:33:27 2008 +0300
@@ -3,87 +3,90 @@
 SUBDIRS = ${INTL_OBJECTIVE}
 
 PROG = audacious${PROG_SUFFIX}
-SRCS = af_equalizer.c					\
-       auddrct.c						\
-       audconfig.c						\
-       build_stamp.c					\
-       configdb.c						\
-       custom_uri.c						\
-       discovery.c						\
-       dnd.c							\
-       effect.c							\
-       equalizer_flow.c					\
-       eventqueue.c						\
-       fft.c							\
-       flow.c							\
-       general.c						\
-       hook.c							\
-       icons-stock.c					\
-       interface.c						\
-       input.c							\
-       logger.c							\
-       main.c							\
-       mime.c							\
-       output.c							\
-       pixbuf_effects.c					\
-       playback.c						\
-       playback_evlisteners.c			\
-       playlist.c						\
-       playlist_container.c				\
-       pluginenum.c						\
-       rcfile.c							\
-       signals.c						\
-       src_flow.c						\
-       strings.c						\
-       tuple.c							\
-       tuple_formatter.c				\
-       tuple_compiler.c					\
+SRCS = af_equalizer.c							\
+       auddrct.c								\
+       audconfig.c								\
+       build_stamp.c							\
+       configdb.c								\
+       custom_uri.c								\
+       discovery.c								\
+       dnd.c									\
+       effect.c									\
+       equalizer.c								\
+       equalizer_flow.c							\
+       equalizer_preset.c						\
+       eventqueue.c								\
+       fft.c									\
+       flow.c									\
+       general.c								\
+       hook.c									\
+       icons-stock.c							\
+       interface.c								\
+       input.c									\
+       logger.c									\
+       main.c									\
+       mime.c									\
+       output.c									\
+       pixbuf_effects.c							\
+       playback.c								\
+       playback_evlisteners.c					\
+       playlist.c								\
+       playlist_container.c						\
+       pluginenum.c								\
+       rcfile.c									\
+       signals.c								\
+       src_flow.c								\
+       strings.c								\
+       tuple.c									\
+       tuple_formatter.c						\
+       tuple_compiler.c							\
+       ui_fileinfopopup.c						\
+       ui_fileopener.c							\
+       ui_headless.c							\
+       ui_legacy.c								\
+       ui_new.c									\
+       ui_preferences.c							\
+       util.c									\
+       vfs.c									\
+       vfs_buffer.c								\
+       vfs_buffered_file.c						\
+       vfs_common.c								\
+       visualization.c							\
+       volumecontrol.c							\
+       sync-menu.c								\
        ui_about.c						\
-       ui_albumart.c					\
+       ui_albumart.c						\
        ui_credits.c						\
-       ui_dock.c						\
-       ui_equalizer.c					\
-       ui_fileinfo.c					\
-       ui_fileinfopopup.c				\
-       ui_fileopener.c					\
-       ui_headless.c					\
-       ui_hints.c						\
+       legacy/ui_dock.c							\
+       legacy/ui_equalizer.c					\
+       ui_fileinfo.c						\
+       legacy/ui_hints.c						\
        ui_jumptotrack.c					\
        ui_jumptotrack_cache.c			\
-       ui_legacy.c				\
-       ui_main.c						\
-       ui_main_evlisteners.c			\
-       ui_manager.c						\
-       ui_new.c							\
-       ui_playlist.c					\
-       ui_playlist_evlisteners.c		\
-       ui_playlist_manager.c			\
-       ui_preferences.c					\
-       ui_skin.c						\
-       ui_skinned_window.c				\
-       ui_skinned_button.c				\
-       ui_skinned_textbox.c				\
-       ui_skinned_number.c				\
-       ui_skinned_horizontal_slider.c	\
-       ui_vis.c							\
-       ui_svis.c						\
-       ui_skinned_menurow.c				\
-       ui_skinned_playstatus.c			\
-       ui_skinned_monostereo.c			\
-       ui_skinned_equalizer_slider.c	\
-       ui_skinned_equalizer_graph.c		\
-       ui_skinned_playlist_slider.c		\
-       ui_skinned_playlist.c			\
-       ui_skinselector.c				\
+       legacy/ui_main.c							\
+       legacy/ui_main_evlisteners.c				\
+       legacy/ui_manager.c						\
+       legacy/ui_playlist.c						\
+       legacy/ui_playlist_evlisteners.c			\
+       legacy/ui_playlist_manager.c				\
+       legacy/ui_skin.c							\
+       legacy/ui_skinned_window.c				\
+       legacy/ui_skinned_button.c				\
+       legacy/ui_skinned_textbox.c				\
+       legacy/ui_skinned_number.c				\
+       legacy/ui_skinned_horizontal_slider.c	\
+       legacy/ui_vis.c							\
+       legacy/ui_svis.c							\
+       legacy/ui_skinned_menurow.c				\
+       legacy/ui_skinned_playstatus.c			\
+       legacy/ui_skinned_monostereo.c			\
+       legacy/ui_skinned_equalizer_slider.c		\
+       legacy/ui_skinned_equalizer_graph.c		\
+       legacy/ui_skinned_playlist_slider.c		\
+       legacy/ui_skinned_playlist.c				\
+       legacy/ui_skinselector.c					\
        ui_urlopener.c					\
-       util.c							\
-       vfs.c							\
-       vfs_buffer.c						\
-       vfs_buffered_file.c				\
-       vfs_common.c						\
-       visualization.c					\
-       volumecontrol.c					\
-       sync-menu.c
+       ui_playlist_widget.c				\
 
 ifeq ($(USE_DBUS),yes)
 SRCS += dbus.c
@@ -96,13 +99,14 @@
            dbus.h				\
            discovery.h			\
            dbus-service.h		\
+           equalizer_preset.h			\
            eventqueue.h			\
            flow.h				\
            rcfile.h				\
            i18n.h				\
            input.h				\
            hook.h				\
-           interface.h				\
+           interface.h			\
            main.h				\
            mime.h				\
            output.h				\
@@ -180,7 +184,8 @@
 		-I../libSAD				\
 		${EGGSM_CFLAGS}			\
 		-I.. -I../..			\
-		-I./intl
+		-I./intl			\
+		-I.
 
 LIBS += ${LDADD}						\
 		${LIBINTL}						\
--- a/src/audacious/audconfig.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/audconfig.c	Wed Aug 06 22:33:27 2008 +0300
@@ -37,11 +37,11 @@
 #include "general.h"
 #include "playback.h"
 #include "pluginenum.h"
-#include "ui_equalizer.h"
-#include "ui_playlist.h"
-#include "ui_skin.h"
-#include "ui_skinned_window.h"
-#include "ui_vis.h"
+#include "legacy/ui_equalizer.h"
+#include "legacy/ui_playlist.h"
+#include "legacy/ui_skin.h"
+#include "legacy/ui_skinned_window.h"
+#include "legacy/ui_vis.h"
 #include "util.h"
 #include "visualization.h"
 
--- a/src/audacious/dbus-service.h	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/dbus-service.h	Wed Aug 06 22:33:27 2008 +0300
@@ -194,8 +194,6 @@
 gboolean audacious_rc_activate(RemoteObject *obj, GError **error);
 gboolean audacious_rc_queue_get_list_pos(RemoteObject *obj, gint qpos, gint *pos, GError **error);
 gboolean audacious_rc_queue_get_queue_pos(RemoteObject *obj, gint pos, gint *qpos, GError **error);
-gboolean audacious_rc_get_skin(RemoteObject *obj, gchar **skin, GError **error);
-gboolean audacious_rc_set_skin(RemoteObject *obj, gchar *skin, GError **error);
 gboolean audacious_rc_get_info(RemoteObject *obj, gint *rate, gint *freq, gint *nch, GError **error);
 gboolean audacious_rc_toggle_aot(RemoteObject *obj, gboolean ontop, GError **error);
 gboolean audacious_rc_get_playqueue_length(RemoteObject *obj, gint *length, GError **error);
--- a/src/audacious/dbus.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/dbus.c	Wed Aug 06 22:33:27 2008 +0300
@@ -32,15 +32,13 @@
 #include "dbus-server-bindings.h"
 
 #include <math.h>
+#include "equalizer.h"
+#include "input.h"
 #include "main.h"
-#include "input.h"
 #include "playback.h"
 #include "playlist.h"
+#include "strings.h"
 #include "tuple.h"
-#include "strings.h"
-
-#include "ui_equalizer.h"
-#include "ui_skin.h"
 
 static DBusGConnection *dbus_conn = NULL;
 static guint signals[LAST_SIG] = { 0 };
@@ -838,18 +836,6 @@
     return TRUE;
 }
 
-/* TODO: these skin functions should be removed when skin functionality
- * disappears --mf0102 */
-gboolean audacious_rc_get_skin(RemoteObject *obj, gchar **skin, GError **error) {
-    *skin = g_strdup(aud_active_skin->path);
-    return TRUE;
-}
-
-gboolean audacious_rc_set_skin(RemoteObject *obj, gchar *skin, GError **error) {
-    aud_active_skin_load(skin);
-    return TRUE;
-}
-
 gboolean audacious_rc_get_info(RemoteObject *obj, gint *rate, gint *freq, gint *nch, GError **error) {
     playback_get_sample_params(rate, freq, nch);
     return TRUE;
@@ -941,11 +927,11 @@
 {
     int i;
 
-    *preamp = (gdouble)equalizerwin_get_preamp();
+    *preamp = (gdouble)equalizer_get_preamp();
     *bands = g_array_sized_new(FALSE, FALSE, sizeof(gdouble), AUD_EQUALIZER_NBANDS);
 
     for(i=0; i < AUD_EQUALIZER_NBANDS; i++){
-        gdouble val = (gdouble)equalizerwin_get_band(i);
+        gdouble val = (gdouble)equalizer_get_band(i);
         g_array_append_val(*bands, val);
     }
 
@@ -954,13 +940,13 @@
 
 gboolean audacious_rc_get_eq_preamp(RemoteObject *obj, gdouble *preamp, GError **error)
 {
-    *preamp = (gdouble)equalizerwin_get_preamp();
+    *preamp = (gdouble)equalizer_get_preamp();
     return TRUE;
 }
 
 gboolean audacious_rc_get_eq_band(RemoteObject *obj, gint band, gdouble *value, GError **error)
 {
-    *value = (gdouble)equalizerwin_get_band(band);
+    *value = (gdouble)equalizer_get_band(band);
     return TRUE;
 }
 
@@ -969,34 +955,31 @@
     gdouble element;
     int i;
     
-    equalizerwin_set_preamp((gfloat)preamp);
+    equalizer_set_preamp((gfloat)preamp);
 
     for (i = 0; i < AUD_EQUALIZER_NBANDS; i++) {
         element = g_array_index(bands, gdouble, i);
-        equalizerwin_set_band(i, (gfloat)element);
+        equalizer_set_band(i, (gfloat)element);
     }
-    equalizerwin_eq_changed();
 
     return TRUE;
 }
 
 gboolean audacious_rc_set_eq_preamp(RemoteObject *obj, gdouble preamp, GError **error)
 {
-    equalizerwin_set_preamp((gfloat)preamp);
-    equalizerwin_eq_changed();
+    equalizer_set_preamp((gfloat)preamp);
     return TRUE;
 }
 
 gboolean audacious_rc_set_eq_band(RemoteObject *obj, gint band, gdouble value, GError **error)
 {
-    equalizerwin_set_band(band, (gfloat)value);
-    equalizerwin_eq_changed();
+    equalizer_set_band(band, (gfloat)value);
     return TRUE;
 }
 
 gboolean audacious_rc_equalizer_activate(RemoteObject *obj, gboolean active, GError **error)
 {
-    equalizer_activate(active);
+    equalizer_set_active(active);
     return TRUE;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/equalizer.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,58 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2008  Audacious development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#include "equalizer.h"
+
+#include "audconfig.h"
+#include "legacy/ui_equalizer.h"
+
+gfloat
+equalizer_get_preamp(void)
+{
+    return equalizerwin_get_preamp();
+}
+
+void
+equalizer_set_preamp(gfloat preamp)
+{
+    equalizerwin_set_preamp(preamp);
+}
+
+gfloat
+equalizer_get_band(gint band)
+{
+    return equalizerwin_get_band(band);
+}
+
+void
+equalizer_set_band(gint band, gfloat value)
+{
+    equalizerwin_set_band(band, value);
+}
+
+gboolean equalizer_get_active(gboolean active)
+{
+    return cfg.equalizer_active;
+}
+
+void
+equalizer_set_active(gboolean active)
+{
+    equalizerwin_activate(active);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/equalizer.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,33 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2008  Audacious development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_EQUALIZER_H
+#define AUDACIOUS_EQUALIZER_H
+
+#include <glib.h>
+
+gfloat equalizer_get_preamp(void);
+void equalizer_set_preamp(gfloat preamp);
+gfloat equalizer_get_band(gint band);
+void equalizer_set_band(gint band, gfloat value);
+
+gboolean equalizer_get_active();
+void equalizer_set_active(gboolean active);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/equalizer_preset.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,240 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2008  Audacious team
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+/*#define AUD_DEBUG*/
+
+#include <glib.h>
+#include <math.h>
+#include "config.h"
+#include "i18n.h"
+#include "main.h"
+#include "plugin.h"
+#include "rcfile.h"
+#include "equalizer_preset.h"
+#include "equalizer_flow.h"
+
+EqualizerPreset *
+equalizer_preset_new(const gchar * name)
+{
+    EqualizerPreset *preset = g_new0(EqualizerPreset, 1);
+    preset->name = g_strdup(name);
+    return preset;
+}
+
+void
+equalizer_preset_free(EqualizerPreset * preset)
+{
+    if (!preset)
+        return;
+
+    g_free(preset->name);
+    g_free(preset);
+}
+
+GList *
+equalizer_read_presets(const gchar * basename)
+{
+    gchar *filename, *name;
+    RcFile *rcfile;
+    GList *list = NULL;
+    gint i, p = 0;
+    EqualizerPreset *preset;
+
+    /* START mod: add check for the default presets locate in system path ({prefix}/share/audacious)
+       by Massimo Cavalleri (submax) */
+
+    filename = g_build_filename(aud_paths[BMP_PATH_USER_DIR], basename, NULL);
+
+    if ((rcfile = aud_rcfile_open(filename)) == NULL) {
+        g_free(filename);
+        // DATA_DIR = "{prefix}/share/audacious" ; example is "/usr/share/audacious"
+        filename = g_build_filename(DATA_DIR, basename, NULL);
+        if ((rcfile = aud_rcfile_open(filename)) == NULL) {
+           g_free(filename);
+           return NULL;
+        }
+    }
+
+    // END mod
+
+    g_free(filename);
+
+    for (;;) {
+        gchar section[32];
+
+        g_snprintf(section, sizeof(section), "Preset%d", p++);
+        if (aud_rcfile_read_string(rcfile, "Presets", section, &name)) {
+            preset = g_new0(EqualizerPreset, 1);
+            preset->name = name;
+            aud_rcfile_read_float(rcfile, name, "Preamp", &preset->preamp);
+            for (i = 0; i < AUD_EQUALIZER_NBANDS; i++) {
+                gchar band[16];
+                g_snprintf(band, sizeof(band), "Band%d", i);
+                aud_rcfile_read_float(rcfile, name, band, &preset->bands[i]);
+            }
+            list = g_list_prepend(list, preset);
+        }
+        else
+            break;
+    }
+    list = g_list_reverse(list);
+    aud_rcfile_free(rcfile);
+    return list;
+}
+
+void
+equalizer_write_preset_file(GList * list, const gchar * basename)
+{
+    gchar *filename, *tmp;
+    gint i, p;
+    EqualizerPreset *preset;
+    RcFile *rcfile;
+    GList *node;
+
+    rcfile = aud_rcfile_new();
+    p = 0;
+    for (node = list; node; node = g_list_next(node)) {
+        preset = node->data;
+        tmp = g_strdup_printf("Preset%d", p++);
+        aud_rcfile_write_string(rcfile, "Presets", tmp, preset->name);
+        g_free(tmp);
+        aud_rcfile_write_float(rcfile, preset->name, "Preamp",
+                               preset->preamp);
+        for (i = 0; i < 10; i++) {
+            tmp = g_strdup_printf("Band%d\n", i);
+            aud_rcfile_write_float(rcfile, preset->name, tmp,
+                                   preset->bands[i]);
+            g_free(tmp);
+        }
+    }
+
+    filename = g_build_filename(aud_paths[BMP_PATH_USER_DIR], basename, NULL);
+    aud_rcfile_write(rcfile, filename);
+    aud_rcfile_free(rcfile);
+    g_free(filename);
+}
+
+GList *
+import_winamp_eqf(VFSFile * file)
+{
+    gchar header[31];
+    gchar bands[11];
+    gint i = 0;
+    EqualizerPreset *preset = NULL;
+    GList *list = NULL;
+    GtkWidget *dialog;
+    gchar *realfn;
+    gchar preset_name[0xb4];
+
+    vfs_fread(header, 1, 31, file);
+    if (strncmp(header, "Winamp EQ library file v1.1", 27)) goto error;
+
+    AUDDBG("The EQF header is OK\n");
+
+    if (vfs_fseek(file, 0x1f, SEEK_SET) == -1) goto error;
+
+    while (vfs_fread(preset_name, 1, 0xb4, file) == 0xb4) {
+        AUDDBG("The preset name is '%s'\n", preset_name);
+        vfs_fseek(file, 0x4d, SEEK_CUR); /* unknown crap --asphyx */
+        if (vfs_fread(bands, 1, 11, file) != 11) break;
+
+        preset = equalizer_preset_new(preset_name);
+        /*this was divided by 63, but shouldn't it be 64? --majeru*/
+        preset->preamp = EQUALIZER_MAX_GAIN - ((bands[10] * EQUALIZER_MAX_GAIN * 2) / 64.0);
+
+        for (i = 0; i < 10; i++)
+            preset->bands[i] = EQUALIZER_MAX_GAIN - ((bands[i] * EQUALIZER_MAX_GAIN * 2) / 64.0);
+
+        list = g_list_prepend(list, preset);
+    }
+
+    list = g_list_reverse(list);
+    if (list == NULL) goto error;
+
+    return list;
+
+error:
+    realfn = g_filename_from_uri(file->uri, NULL, NULL);
+    dialog = gtk_message_dialog_new (GTK_WINDOW(mainwin),
+                                     GTK_DIALOG_DESTROY_WITH_PARENT,
+                                     GTK_MESSAGE_ERROR,
+                                     GTK_BUTTONS_CLOSE,
+                                     _("Error importing Winamp EQF file '%s'"),
+                                     realfn);
+    gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy (dialog);
+    g_free(realfn);
+    return NULL;
+}
+
+void
+save_preset_file(EqualizerPreset *preset, const gchar * filename)
+{
+    RcFile *rcfile;
+    gint i;
+
+    rcfile = aud_rcfile_new();
+    aud_rcfile_write_float(rcfile, "Equalizer preset", "Preamp",
+                           preset->preamp);
+
+    for (i = 0; i < 10; i++) {
+        gchar tmp[7];
+        g_snprintf(tmp, sizeof(tmp), "Band%d", i);
+        aud_rcfile_write_float(rcfile, "Equalizer preset", tmp,
+                               preset->bands[i]);
+    }
+
+    aud_rcfile_write(rcfile, filename);
+    aud_rcfile_free(rcfile);
+}
+
+EqualizerPreset *
+equalizer_read_aud_preset(const gchar * filename)
+{
+    gfloat val;
+    gint i;
+    EqualizerPreset *preset = g_new0(EqualizerPreset, 1);
+    preset->name = g_strdup("");
+
+    RcFile *rcfile = aud_rcfile_open(filename);
+    if (rcfile == NULL)
+        return NULL;
+
+    if (aud_rcfile_read_float(rcfile, "Equalizer preset", "Preamp", &val))
+        preset->preamp = val;
+    for (i = 0; i < 10; i++) {
+        gchar tmp[7];
+        g_snprintf(tmp, sizeof(tmp), "Band%d", i);
+        if (aud_rcfile_read_float(rcfile, "Equalizer preset", tmp, &val))
+            preset->bands[i] = val;
+    }
+    aud_rcfile_free(rcfile);
+    return preset;
+}
+
+EqualizerPreset *
+load_preset_file(const gchar *filename)
+{
+    if (filename) {
+        EqualizerPreset *preset = equalizer_read_aud_preset(filename);
+        return preset;
+    }
+    return NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/equalizer_preset.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,42 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2008  Audacious team
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_EQUALIZER_PRESET_H
+#define AUDACIOUS_EQUALIZER_PRESET_H
+
+#include "audacious/rcfile.h"
+
+struct _EqualizerPreset {
+    gchar *name;
+    gfloat preamp, bands[10];
+};
+
+typedef struct _EqualizerPreset EqualizerPreset;
+
+EqualizerPreset * equalizer_preset_new(const gchar * name);
+void    equalizer_preset_free(EqualizerPreset * preset);
+GList * equalizer_read_presets(const gchar * basename);
+void    equalizer_write_preset_file(GList * list, const gchar * basename);
+GList * import_winamp_eqf(VFSFile * file);
+void    save_preset_file(EqualizerPreset *preset, const gchar * filename);
+
+EqualizerPreset * equalizer_read_aud_preset(const gchar * filename);
+EqualizerPreset * load_preset_file(const gchar *filename);
+
+#endif
--- a/src/audacious/eventqueue.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/eventqueue.c	Wed Aug 06 22:33:27 2008 +0300
@@ -40,7 +40,6 @@
     HookCallQueue *hq;
 
     g_return_if_fail(name != NULL);
-    g_return_if_fail(user_data != NULL);
 
     hq = g_slice_new0(HookCallQueue);
     hq->name = g_strdup(name);
@@ -55,7 +54,6 @@
     HookCallQueue *hq;
 
     g_return_if_fail(name != NULL);
-    g_return_if_fail(user_data != NULL);
 
     hq = g_slice_new0(HookCallQueue);
     hq->name = g_strdup(name);
--- a/src/audacious/input.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/input.c	Wed Aug 06 22:33:27 2008 +0300
@@ -173,6 +173,7 @@
 void
 input_add_vis_pcm(gint time, AFormat fmt, gint nch, gint length, gpointer ptr)
 {
+#if 0
     VisNode *vis_node;
     gint max;
     
@@ -203,6 +204,7 @@
     G_LOCK(vis_mutex);
     vis_list = g_list_append(vis_list, vis_node);
     G_UNLOCK(vis_mutex);
+#endif
 }
 
 void
@@ -524,7 +526,6 @@
         }
 
         tuple_associate_int(input, FIELD_LENGTH, NULL, -1);
-
     }
 
     g_free(filename_proxy);
--- a/src/audacious/interface.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/interface.c	Wed Aug 06 22:33:27 2008 +0300
@@ -1,6 +1,7 @@
 /*
  * Audacious2
  * Copyright (c) 2008 William Pitcock <nenolod@dereferenced.org>
+ * Copyright (c) 2008 Tomasz Moń <desowin@gmail.com>
  *
  * 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
@@ -22,9 +23,25 @@
 #include <mowgli.h>
 
 #include "interface.h"
+#include "ui_fileopener.h"
+#include "ui_urlopener.h"
+#include "ui_preferences.h"
+#include "ui_jumptotrack.h"
+#include "ui_credits.h"
 
 static mowgli_dictionary_t *interface_dict_ = NULL;
 
+static InterfaceOps interface_ops = {
+    .create_prefs_window = create_prefs_window,
+    .show_prefs_window = show_prefs_window,
+    .hide_prefs_window = hide_prefs_window,
+
+    .filebrowser_show = run_filebrowser,
+    .urlopener_show = show_add_url_window,
+    .jump_to_track_show = ui_jump_to_track,
+    .aboutwin_show = show_about_window,
+};
+
 void
 interface_register(Interface *i)
 {
@@ -42,13 +59,10 @@
     mowgli_dictionary_delete(interface_dict_, i->id);
 }
 
-/*
- * TODO:
- *     - set up InterfaceOps struct for the Interface to use
- */
 void
 interface_run(Interface *i)
 {
+    i->ops = &interface_ops;
     i->init();
 }
 
--- a/src/audacious/interface.h	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/interface.h	Wed Aug 06 22:33:27 2008 +0300
@@ -1,6 +1,7 @@
 /*
  * Audacious2
  * Copyright (c) 2008 William Pitcock <nenolod@dereferenced.org>
+ * Copyright (c) 2008 Tomasz Moń <desowin@gmail.com>
  *
  * 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
@@ -28,11 +29,26 @@
 #ifndef __AUDACIOUS2_INTERFACE_H__
 #define __AUDACIOUS2_INTERFACE_H__
 
+#include <gtk/gtk.h>
+
 typedef struct {
+	void (*create_prefs_window)(void);
+	void (*show_prefs_window)(void);
+	void (*hide_prefs_window)(void);
+
+	void (*filebrowser_show)(gboolean play_button);
+	void (*urlopener_show)(void);
+	void (*jump_to_track_show)(void);
+	void (*aboutwin_show)(void);
+} InterfaceOps;
+
+typedef struct _Interface {
 	gchar *id;		/* simple ID like 'skinned' */
 	gchar *desc;		/* description like 'Skinned Interface' */
 	gboolean (*init)(void); /* init UI */
 	gboolean (*fini)(void); /* shutdown UI */
+
+	InterfaceOps *ops;
 } Interface;
 
 void interface_register(Interface *i);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_dock.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,531 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team
+ *
+ *  Based on BMP:
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_dock.h"
+
+#include <gdk/gdk.h>
+#include <stdlib.h>
+#include "main.h"
+#include "ui_skinned_window.h"
+
+#include "platform/smartinclude.h"
+
+static GList *dock_window_list = NULL;
+
+struct _DockedWindow {
+    GtkWindow *w;
+    gint offset_x, offset_y;
+};
+
+typedef struct _DockedWindow DockedWindow;
+
+
+static gint
+docked_list_compare(DockedWindow * a, DockedWindow * b)
+{
+    if (a->w == b->w)
+        return 0;
+    return 1;
+}
+
+static void
+snap_edge(gint * x, gint * y, gint w, gint h, gint bx, gint by,
+          gint bw, gint bh)
+{
+    gint sd = cfg.snap_distance;
+
+    if ((*x + w > bx - sd) && (*x + w < bx + sd) &&
+        (*y > by - h - sd) && (*y < by + bh + sd)) {
+        *x = bx - w;
+        if ((*y > by - sd) && (*y < by + sd))
+            *y = by;
+        if ((*y + h > by + bh - sd) && (*y + h < by + bh + sd))
+            *y = by + bh - h;
+    }
+    if ((*x > bx + bw - sd) && (*x < bx + bw + sd) &&
+        (*y > by - h - sd) && (*y < by + bh + sd)) {
+        *x = bx + bw;
+        if ((*y > by - sd) && (*y < by + sd))
+            *y = by;
+        if ((*y + h > by + bh - sd) && (*y + h < by + bh + sd))
+            *y = by + bh - h;
+    }
+}
+
+static void
+snap(gint * x, gint * y, gint w, gint h, gint bx, gint by, gint bw, gint bh)
+{
+    snap_edge(x, y, w, h, bx, by, bw, bh);
+    snap_edge(y, x, h, w, by, bx, bh, bw);
+}
+
+static void
+calc_snap_offset(GList * dlist, GList * wlist, gint x, gint y,
+                 gint * off_x, gint * off_y)
+{
+    gint nx, ny, nw, nh, sx, sy, sw, sh;
+    GtkWindow *w;
+    GList *dnode, *wnode;
+    DockedWindow temp, *dw;
+
+
+    *off_x = 0;
+    *off_y = 0;
+
+    if (!cfg.snap_windows)
+        return;
+
+    /*
+     * FIXME: Why not break out of the loop when we find someting
+     * to snap to?
+     */
+    for (dnode = dlist; dnode; dnode = g_list_next(dnode)) {
+        dw = dnode->data;
+        gtk_window_get_size(dw->w, &nw, &nh);
+
+        nx = dw->offset_x + *off_x + x;
+        ny = dw->offset_y + *off_y + y;
+
+        /* Snap to screen edges */
+        if (abs(nx) < cfg.snap_distance)
+            *off_x -= nx;
+        if (abs(ny) < cfg.snap_distance)
+            *off_y -= ny;
+        if (abs(nx + nw - gdk_screen_width()) < cfg.snap_distance)
+            *off_x -= nx + nw - gdk_screen_width();
+        if (abs(ny + nh - gdk_screen_height()) < cfg.snap_distance)
+            *off_y -= ny + nh - gdk_screen_height();
+
+        /* Snap to other windows */
+        for (wnode = wlist; wnode; wnode = g_list_next(wnode)) {
+            temp.w = wnode->data;
+            if (g_list_find_custom
+                (dlist, &temp, (GCompareFunc) docked_list_compare))
+                /* These windows are already docked */
+                continue;
+
+            w = GTK_WINDOW(wnode->data);
+            gtk_window_get_position(w, &sx, &sy);
+            gtk_window_get_size(w, &sw, &sh);
+
+            nx = dw->offset_x + *off_x + x;
+            ny = dw->offset_y + *off_y + y;
+
+            snap(&nx, &ny, nw, nh, sx, sy, sw, sh);
+
+            *off_x += nx - (dw->offset_x + *off_x + x);
+            *off_y += ny - (dw->offset_y + *off_y + y);
+        }
+    }
+}
+
+
+static gboolean
+is_docked(gint a_x, gint a_y, gint a_w, gint a_h,
+          gint b_x, gint b_y, gint b_w, gint b_h)
+{
+    if (((a_x == b_x + b_w) || (a_x + a_w == b_x)) &&
+        (b_y + b_h >= a_y) && (b_y <= a_y + a_h))
+        return TRUE;
+
+    if (((a_y == b_y + b_h) || (a_y + a_h == b_y)) &&
+        (b_x >= a_x - b_w) && (b_x <= a_x + a_w))
+        return TRUE;
+
+    return FALSE;
+}
+
+/*
+ * Builds a list of all windows that are docked to the window "w".
+ * Recursively adds all windows that are docked to the windows that are
+ * docked to "w" and so on...
+ * FIXME: init_off_?  ?
+ */
+
+static GList *
+get_docked_list(GList * dlist, GList * wlist, GtkWindow * w,
+                gint init_off_x, gint init_off_y)
+{
+    GList *node;
+    DockedWindow *dwin, temp;
+    gint w_x, w_y, w_width, w_height;
+    gint t_x, t_y, t_width, t_height;
+
+
+    gtk_window_get_position(w, &w_x, &w_y);
+    gtk_window_get_size(w, &w_width, &w_height);
+    if (!dlist) {
+        dwin = g_new0(DockedWindow, 1);
+        dwin->w = w;
+        dlist = g_list_append(dlist, dwin);
+    }
+
+    for (node = wlist; node; node = g_list_next(node)) {
+        temp.w = node->data;
+        if (g_list_find_custom
+            (dlist, &temp, (GCompareFunc) docked_list_compare))
+            continue;
+
+        gtk_window_get_position(GTK_WINDOW(node->data), &t_x, &t_y);
+        gtk_window_get_size(GTK_WINDOW(node->data), &t_width, &t_height);
+        if (is_docked
+            (w_x, w_y, w_width, w_height, t_x, t_y, t_width, t_height)) {
+            dwin = g_new0(DockedWindow, 1);
+            dwin->w = node->data;
+
+            dwin->offset_x = t_x - w_x + init_off_x;
+            dwin->offset_y = t_y - w_y + init_off_y;
+
+            dlist = g_list_append(dlist, dwin);
+
+            dlist =
+                get_docked_list(dlist, wlist, dwin->w, dwin->offset_x,
+                                dwin->offset_y);
+        }
+    }
+    return dlist;
+}
+
+static void
+free_docked_list(GList * dlist)
+{
+    GList *node;
+
+    for (node = dlist; node; node = g_list_next(node))
+        g_free(node->data);
+    g_list_free(dlist);
+}
+
+static void
+docked_list_move(GList * list, gint x, gint y)
+{
+    GList *node;
+    DockedWindow *dw;
+
+    for (node = list; node; node = g_list_next(node)) {
+        dw = node->data;
+        gtk_window_move(dw->w, x + dw->offset_x, y + dw->offset_y);
+
+        SkinnedWindow *window = SKINNED_WINDOW(dw->w);
+        if (window) {
+            switch(window->type) {
+
+            case WINDOW_MAIN:
+                cfg.player_x = x + dw->offset_x;
+                cfg.player_y = y + dw->offset_y;
+                break;
+            case WINDOW_EQ:
+                cfg.equalizer_x = x + dw->offset_x;
+                cfg.equalizer_y = y + dw->offset_y;
+                break;
+            case WINDOW_PLAYLIST:
+                cfg.playlist_x = x + dw->offset_x;
+                cfg.playlist_y = y + dw->offset_y;
+                break;
+            }
+
+            window->x = x + dw->offset_x;
+            window->y = y + dw->offset_y;
+        }
+    }
+}
+
+static GList *
+shade_move_list(GList * list, GtkWindow * widget, gint offset)
+{
+    gint x, y, w, h;
+    GList *node;
+    DockedWindow *dw;
+
+    gtk_window_get_position(widget, &x, &y);
+    gtk_window_get_size(widget, &w, &h);
+
+
+    for (node = list; node;) {
+        gint dx, dy, dwidth, dheight;
+
+        dw = node->data;
+        gtk_window_get_position(dw->w, &dx, &dy);
+        gtk_window_get_size(dw->w, &dwidth, &dheight);
+        if (is_docked(x, y, w, h, dx, dy, dwidth, dheight) &&
+            ((dx + dwidth) > x && dx < (x + w))) {
+            list = g_list_remove_link(list, node);
+            g_list_free_1(node);
+
+            node = list = shade_move_list(list, dw->w, offset);
+        }
+        else
+            node = g_list_next(node);
+    }
+    gtk_window_move(widget, x, y + offset);
+    return list;
+}
+
+/*
+ * Builds a list of the windows in the list of DockedWindows "winlist"
+ * that are docked to the top or bottom of the window, and recursively
+ * adds all windows that are docked to the top or bottom of that window,
+ * and so on...
+ * Note: The data in "winlist" is not copied.
+ */
+static GList *
+find_shade_list(GtkWindow * widget, GList * winlist, GList * shade_list)
+{
+    gint x, y, w, h;
+    gint dx, dy, dwidth, dheight;
+    GList *node;
+
+    gtk_window_get_position(widget, &x, &y);
+    gtk_window_get_size(widget, &w, &h);
+    for (node = winlist; node; node = g_list_next(node)) {
+        DockedWindow *dw = node->data;
+        if (g_list_find_custom
+            (shade_list, dw, (GCompareFunc) docked_list_compare))
+            continue;
+        gtk_window_get_position(dw->w, &dx, &dy);
+        gtk_window_get_size(dw->w, &dwidth, &dheight);
+
+        /* FIXME. Is the is_docked() necessary? */
+        if (is_docked(x, y, w, h, dx, dy, dwidth, dheight) &&
+            ((dx + dwidth) > x && dx < (x + w))) {
+            shade_list = g_list_append(shade_list, dw);
+            shade_list = find_shade_list(dw->w, winlist, shade_list);
+        }
+    }
+    return shade_list;
+}
+
+void
+dock_window_resize(GtkWindow * widget, gint new_w, gint new_h, gint w, gint h)
+{
+    gdk_window_set_hints(GTK_WIDGET(widget)->window, 0, 0, MIN(w, new_w),
+                         MIN(h, new_h), MAX(w, new_w), MAX(h, new_h),
+                         GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
+    gdk_window_resize(GTK_WIDGET(widget)->window, new_w, new_h);
+    gdk_window_set_hints(GTK_WIDGET(widget)->window, 0, 0, new_w, new_h,
+                         new_w, new_h, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
+}
+
+void
+dock_shade(GList * window_list, GtkWindow * widget, gint new_h)
+{
+    gint x, y, w, h, off_y, orig_off_y;
+    GList *node, *docked_list, *slist;
+    DockedWindow *dw;
+
+    gtk_window_get_position(widget, &x, &y);
+    gtk_window_get_size(widget, &w, &h);
+
+    if (cfg.show_wm_decorations) {
+        dock_window_resize(widget, w, new_h, w, h);
+        return;
+    }
+
+    docked_list = get_docked_list(NULL, window_list, widget, 0, 0);
+    slist = find_shade_list(widget, docked_list, NULL);
+
+    off_y = new_h - h;
+    do {
+        orig_off_y = off_y;
+        for (node = slist; node; node = g_list_next(node)) {
+            gint dx, dy, dwidth, dheight;
+
+            dw = node->data;
+            if (dw->w == widget)
+                continue;
+            gtk_window_get_position(dw->w, &dx, &dy);
+            gtk_window_get_size(dw->w, &dwidth, &dheight);
+            if ((dy >= y) && ((dy + off_y + dheight) > gdk_screen_height()))
+                off_y -= (dy + off_y + dheight) - gdk_screen_height();
+            else if ((dy >= y) && ((dy + dheight) == gdk_screen_height()))
+                off_y = 0;
+
+            if (((dy >= y) && ((dy + off_y) < 0)))
+                off_y -= dy + off_y;
+            if ((dy < y) && ((dy + (off_y - (new_h - h))) < 0))
+                off_y -= dy + (off_y - (new_h - h));
+        }
+    } while (orig_off_y != off_y);
+    if (slist) {
+        GList *mlist = g_list_copy(slist);
+
+        /* Remove this widget from the list */
+        for (node = mlist; node; node = g_list_next(node)) {
+            dw = node->data;
+            if (dw->w == widget) {
+                mlist = g_list_remove_link(mlist, node);
+                g_list_free_1(node);
+                break;
+            }
+        }
+        for (node = mlist; node;) {
+            GList *temp;
+            gint dx, dy, dwidth, dheight;
+
+            dw = node->data;
+
+            gtk_window_get_position(dw->w, &dx, &dy);
+            gtk_window_get_size(dw->w, &dwidth, &dheight);
+            /*
+             * Find windows that are directly docked to this window,
+             * move it, and any windows docked to that window again
+             */
+            if (is_docked(x, y, w, h, dx, dy, dwidth, dheight) &&
+                ((dx + dwidth) > x && dx < (x + w))) {
+                mlist = g_list_remove_link(mlist, node);
+                g_list_free_1(node);
+                if (dy > y)
+                    temp = shade_move_list(mlist, dw->w, off_y);
+                else if (off_y - (new_h - h) != 0)
+                    temp = shade_move_list(mlist, dw->w, off_y - (new_h - h));
+                else
+                    temp = mlist;
+                node = mlist = temp;
+            }
+            else
+                node = g_list_next(node);
+        }
+        g_list_free(mlist);
+    }
+    g_list_free(slist);
+    free_docked_list(docked_list);
+    gtk_window_move(widget, x, y + off_y - (new_h - h));
+    dock_window_resize(widget, w, new_h, w, h);
+}
+
+void
+dock_move_press(GList * window_list, GtkWindow * w,
+                GdkEventButton * event, gboolean move_list)
+{
+    gint mx, my;
+    DockedWindow *dwin;
+
+    if (cfg.show_wm_decorations)
+        return;
+
+    gtk_window_present(w);
+    mx = event->x;
+    my = event->y;
+    gtk_object_set_data(GTK_OBJECT(w), "move_offset_x", GINT_TO_POINTER(mx));
+    gtk_object_set_data(GTK_OBJECT(w), "move_offset_y", GINT_TO_POINTER(my));
+    if (move_list)
+        gtk_object_set_data(GTK_OBJECT(w), "docked_list",
+                            get_docked_list(NULL, window_list, w, 0, 0));
+    else {
+        dwin = g_new0(DockedWindow, 1);
+        dwin->w = w;
+        gtk_object_set_data(GTK_OBJECT(w), "docked_list",
+                            g_list_append(NULL, dwin));
+    }
+    gtk_object_set_data(GTK_OBJECT(w), "window_list", window_list);
+    gtk_object_set_data(GTK_OBJECT(w), "is_moving", GINT_TO_POINTER(1));
+}
+
+void
+dock_move_motion(GtkWindow * w, GdkEventMotion * event)
+{
+    gint offset_x, offset_y, x, y;
+    GList *dlist;
+    GList *window_list;
+
+    if (!gtk_object_get_data(GTK_OBJECT(w), "is_moving"))
+        return;
+
+    offset_x =
+        GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(w), "move_offset_x"));
+    offset_y =
+        GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(w), "move_offset_y"));
+    dlist = gtk_object_get_data(GTK_OBJECT(w), "docked_list");
+    window_list = gtk_object_get_data(GTK_OBJECT(w), "window_list");
+
+    x = event->x_root - offset_x;
+    y = event->y_root - offset_y;
+
+    calc_snap_offset(dlist, window_list, x, y, &offset_x, &offset_y);
+    x += offset_x;
+    y += offset_y;
+
+    docked_list_move(dlist, x, y);
+}
+
+void
+dock_move_release(GtkWindow * w)
+{
+    GList *dlist;
+    gtk_object_remove_data(GTK_OBJECT(w), "is_moving");
+    gtk_object_remove_data(GTK_OBJECT(w), "move_offset_x");
+    gtk_object_remove_data(GTK_OBJECT(w), "move_offset_y");
+    if ((dlist = gtk_object_get_data(GTK_OBJECT(w), "docked_list")) != NULL)
+        free_docked_list(dlist);
+    gtk_object_remove_data(GTK_OBJECT(w), "docked_list");
+    gtk_object_remove_data(GTK_OBJECT(w), "window_list");
+}
+
+gboolean
+dock_is_moving(GtkWindow * w)
+{
+    if (gtk_object_get_data(GTK_OBJECT(w), "is_moving"))
+        return TRUE;
+    return FALSE;
+}
+
+GList *
+dock_add_window(GList * list, GtkWindow * window)
+{
+    return g_list_append(list, window);
+}
+
+GList *
+dock_remove_window(GList * list, GtkWindow * window)
+{
+    return g_list_remove(list, window);
+}
+
+GList *
+dock_window_set_decorated(GList * list, GtkWindow * window,
+                          gboolean decorated)
+{
+    if (gtk_window_get_decorated(window) == decorated)
+        return list;
+
+    if (decorated)
+        list = dock_remove_window(list, window);
+    else
+        list = dock_add_window(list, window);
+
+    gtk_window_set_decorated(window, decorated);
+
+    return list;
+}
+
+GList *
+get_dock_window_list() {
+    return dock_window_list;
+}
+
+void
+set_dock_window_list(GList * list) {
+    dock_window_list = list;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_dock.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,50 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team
+ *
+ *  Based on BMP:
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_DOCK_H
+#define AUDACIOUS_UI_DOCK_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+void dock_set_uposition(GtkWindow * widget, gint x, gint y);
+GList *dock_add_window(GList * window_list, GtkWindow * window);
+GList *dock_remove_window(GList * window_list, GtkWindow * window);
+void dock_move_press(GList * window_list, GtkWindow * w,
+                     GdkEventButton * event, gboolean move_list);
+void dock_move_motion(GtkWindow * w, GdkEventMotion * event);
+void dock_move_release(GtkWindow * w);
+void dock_get_widget_pos(GtkWindow * w, gint * x, gint * y);
+gboolean dock_is_moving(GtkWindow * w);
+void dock_shade(GList * window_list, GtkWindow * widget, gint new_h);
+
+GList *dock_window_set_decorated(GList * list, GtkWindow * window,
+                                 gboolean decorated);
+void dock_window_resize(GtkWindow * widget, gint new_w, gint new_h, gint w, gint h);
+
+GList *get_dock_window_list();
+void set_dock_window_list(GList * list);
+
+#endif /* AUDACIOUS_UI_DOCK_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_equalizer.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,1333 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  Based on BMP:
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+/*#define AUD_DEBUG*/
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "ui_equalizer.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include "platform/smartinclude.h"
+#include "ui_skin.h"
+#include "input.h"
+#include "main.h"
+#include "ui_manager.h"
+#include "actions-equalizer.h"
+#include "playlist.h"
+#include "ui_playlist.h"
+#include "util.h"
+#include "output.h"
+#include "equalizer_flow.h"
+#include "equalizer_preset.h"
+
+#include "rcfile.h"
+#include "vfs.h"
+
+#include "images/audacious_eq.xpm"
+
+#include "ui_dock.h"
+#include "ui_skinned_window.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_horizontal_slider.h"
+#include "ui_skinned_equalizer_slider.h"
+#include "ui_skinned_equalizer_graph.h"
+
+enum PresetViewCols {
+    PRESET_VIEW_COL_NAME,
+    PRESET_VIEW_N_COLS
+};
+
+GtkWidget *equalizerwin;
+GtkWidget *equalizerwin_graph;
+
+static GtkWidget *equalizerwin_load_window = NULL;
+static GtkWidget *equalizerwin_load_auto_window = NULL;
+static GtkWidget *equalizerwin_save_window = NULL;
+static GtkWidget *equalizerwin_save_entry = NULL;
+static GtkWidget *equalizerwin_save_auto_window = NULL;
+static GtkWidget *equalizerwin_save_auto_entry = NULL;
+static GtkWidget *equalizerwin_delete_window = NULL;
+static GtkWidget *equalizerwin_delete_auto_window = NULL;
+
+static GtkWidget *equalizerwin_on, *equalizerwin_auto;
+
+static GtkWidget *equalizerwin_close, *equalizerwin_presets, *equalizerwin_shade;
+static GtkWidget *equalizerwin_preamp,*equalizerwin_bands[AUD_EQUALIZER_NBANDS];
+static GtkWidget *equalizerwin_volume, *equalizerwin_balance;
+
+static GList *equalizer_presets = NULL, *equalizer_auto_presets = NULL;
+
+void
+equalizerwin_set_scaled(gboolean ds)
+{
+    gint height;
+
+    if (cfg.equalizer_shaded)
+        height = 14;
+    else
+        height = 116;
+
+    if (cfg.scaled) {
+        dock_window_resize(GTK_WINDOW(equalizerwin), 275 * cfg.scale_factor, 
+            height * cfg.scale_factor, 275 * cfg.scale_factor, height * cfg.scale_factor);
+    } else {
+        dock_window_resize(GTK_WINDOW(equalizerwin), 275, height, 275, height);
+    }
+
+    GList *iter;
+    for (iter = GTK_FIXED (SKINNED_WINDOW(equalizerwin)->fixed)->children; iter; iter = g_list_next (iter)) {
+        GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
+        GtkWidget *child = child_data->widget;
+        g_signal_emit_by_name(child, "toggle-scaled");
+    }
+    gtk_widget_shape_combine_mask(equalizerwin, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
+}
+
+void
+equalizerwin_set_shade_menu_cb(gboolean shaded)
+{
+    cfg.equalizer_shaded = shaded;
+
+    if (shaded) {
+        dock_shade(get_dock_window_list(), GTK_WINDOW(equalizerwin),
+                   14 * EQUALIZER_SCALE_FACTOR);
+        ui_skinned_set_push_button_data(equalizerwin_shade, -1, 3, -1, 47);
+        ui_skinned_button_set_skin_index1(equalizerwin_shade, SKIN_EQ_EX);
+        ui_skinned_set_push_button_data(equalizerwin_close, 11, 38, 11, 47);
+        ui_skinned_button_set_skin_index(equalizerwin_close, SKIN_EQ_EX);
+        gtk_widget_show(equalizerwin_volume);
+        gtk_widget_show(equalizerwin_balance);
+    }
+    else {
+        dock_shade(get_dock_window_list(), GTK_WINDOW(equalizerwin),
+                   116 * EQUALIZER_SCALE_FACTOR);
+        ui_skinned_set_push_button_data(equalizerwin_shade, -1, 137, -1, 38);
+        ui_skinned_button_set_skin_index1(equalizerwin_shade, SKIN_EQMAIN);
+        ui_skinned_set_push_button_data(equalizerwin_close, 0, 116, 0, 125);
+        ui_skinned_button_set_skin_index(equalizerwin_close, SKIN_EQMAIN);
+        gtk_widget_hide(equalizerwin_volume);
+        gtk_widget_hide(equalizerwin_balance);
+    }
+
+    gtk_widget_shape_combine_mask(equalizerwin, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
+}
+
+static void
+equalizerwin_set_shade(gboolean shaded)
+{
+    GtkAction *action = gtk_action_group_get_action(
+      toggleaction_group_others , "roll up equalizer" );
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded );
+}
+
+static void
+equalizerwin_shade_toggle(void)
+{
+    equalizerwin_set_shade(!cfg.equalizer_shaded);
+}
+
+void
+equalizerwin_eq_changed(void)
+{
+    gint i;
+
+    cfg.equalizer_preamp = equalizerwin_get_preamp();
+    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+        cfg.equalizer_bands[i] = equalizerwin_get_band(i);
+
+    output_set_eq(cfg.equalizer_active, cfg.equalizer_preamp,
+                  cfg.equalizer_bands);
+
+    gtk_widget_queue_draw(equalizerwin_graph);
+}
+
+static void
+equalizerwin_apply_preset(EqualizerPreset *preset)
+{
+    if (preset == NULL)
+       return;
+
+    gint i;
+
+    equalizerwin_set_preamp(preset->preamp);
+    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+        equalizerwin_set_band(i, preset->bands[i]);
+}
+
+static void
+equalizerwin_on_pushed(void)
+{
+    equalizerwin_activate(!cfg.equalizer_active);
+}
+
+static void
+equalizerwin_presets_pushed(void)
+{
+    GdkModifierType modmask;
+    gint x, y;
+
+    gdk_window_get_pointer(NULL, &x, &y, &modmask);
+    ui_manager_popup_menu_show(GTK_MENU(equalizerwin_presets_menu), x, y, 1, GDK_CURRENT_TIME);
+}
+
+static void
+equalizerwin_auto_pushed(void)
+{
+    cfg.equalizer_autoload = UI_SKINNED_BUTTON(equalizerwin_auto)->inside;
+}
+
+gboolean
+equalizerwin_press(GtkWidget * widget, GdkEventButton * event,
+                   gpointer callback_data)
+{
+    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS
+             && event->y < 14) {
+        equalizerwin_set_shade(!cfg.equalizer_shaded);
+        if (dock_is_moving(GTK_WINDOW(equalizerwin)))
+            dock_move_release(GTK_WINDOW(equalizerwin));
+        return TRUE;
+    }
+    if (event->button == 3) {
+        /*
+         * Pop up the main menu a few pixels down to avoid
+         * anything to be selected initially.
+         */
+       ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), event->x_root,
+                                event->y_root + 2, 3, event->time);
+       return TRUE;
+    }
+
+    return FALSE;
+}
+
+static gboolean
+equalizerwin_keypress(GtkWidget * widget,
+                      GdkEventKey * event,
+                      gpointer data)
+{
+    if (event->keyval == GDK_Tab && event->state & GDK_CONTROL_MASK) {
+        if (cfg.playlist_visible)
+            gtk_window_present(GTK_WINDOW(playlistwin));
+        else if (cfg.player_visible)
+            gtk_window_present(GTK_WINDOW(mainwin));
+        return TRUE;
+    }
+
+    if (!cfg.equalizer_shaded) {
+        gtk_widget_event(mainwin, (GdkEvent *) event);
+        return TRUE;
+    }
+
+    switch (event->keyval) {
+    case GDK_Left:
+    case GDK_KP_Left:
+        mainwin_set_balance_diff(-4);
+        break;
+    case GDK_Right:
+    case GDK_KP_Right:
+        mainwin_set_balance_diff(4);
+        break;
+    default:
+        gtk_widget_event(mainwin, (GdkEvent *) event);
+        break;
+    }
+
+    return FALSE;
+}
+
+static void
+equalizerwin_close_cb(void)
+{
+    equalizerwin_show(FALSE);
+}
+
+static gboolean
+equalizerwin_delete(GtkWidget * widget,
+                    gpointer data)
+{
+    equalizerwin_show(FALSE);
+    return TRUE;
+}
+
+gint
+equalizerwin_volume_frame_cb(gint pos)
+{
+    if (equalizerwin_volume) {
+        gint x;
+        if (pos < 32)
+            x = 1;
+        else if (pos < 63)
+            x = 4;
+        else
+            x = 7;
+
+        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_volume)->knob_nx = x;
+        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_volume)->knob_px = x;
+    }
+    return 1;
+}
+
+static void
+equalizerwin_volume_motion_cb(GtkWidget *widget, gint pos)
+{
+    gint v = (gint) rint(pos * 100 / 94.0);
+    mainwin_adjust_volume_motion(v);
+    mainwin_set_volume_slider(v);
+}
+
+static void
+equalizerwin_volume_release_cb(GtkWidget *widget, gint pos)
+{
+    mainwin_adjust_volume_release();
+}
+
+static gint
+equalizerwin_balance_frame_cb(gint pos)
+{
+    if (equalizerwin_balance) {
+        gint x;
+        if (pos < 13)
+            x = 11;
+        else if (pos < 26)
+            x = 14;
+        else
+            x = 17;
+
+        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_balance)->knob_nx = x;
+        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_balance)->knob_px = x;
+    }
+
+    return 1;
+}
+
+static void
+equalizerwin_balance_motion_cb(GtkWidget *widget, gint pos)
+{
+    gint b;
+    pos = MIN(pos, 38);         /* The skin uses a even number of pixels
+                                   for the balance-slider *sigh* */
+    b = (gint) rint((pos - 19) * 100 / 19.0);
+    mainwin_adjust_balance_motion(b);
+    mainwin_set_balance_slider(b);
+}
+
+static void
+equalizerwin_balance_release_cb(GtkWidget *widget, gint pos)
+{
+    mainwin_adjust_balance_release();
+}
+
+void
+equalizerwin_set_balance_slider(gint percent)
+{
+    ui_skinned_horizontal_slider_set_position(equalizerwin_balance,
+                         (gint) rint((percent * 19 / 100.0) + 19));
+}
+
+void
+equalizerwin_set_volume_slider(gint percent)
+{
+    ui_skinned_horizontal_slider_set_position(equalizerwin_volume,
+                         (gint) rint(percent * 94 / 100.0));
+}
+
+static void
+equalizerwin_create_widgets(void)
+{
+    gint i;
+
+    equalizerwin_on = ui_skinned_button_new();
+    ui_skinned_toggle_button_setup(equalizerwin_on, SKINNED_WINDOW(equalizerwin)->fixed,
+                                   14, 18, 25, 12, 10, 119, 128, 119, 69, 119, 187, 119, SKIN_EQMAIN);
+    g_signal_connect(equalizerwin_on, "clicked", equalizerwin_on_pushed, NULL);
+    equalizerwin_activate(cfg.equalizer_active);
+
+    equalizerwin_auto = ui_skinned_button_new();
+    ui_skinned_toggle_button_setup(equalizerwin_auto, SKINNED_WINDOW(equalizerwin)->fixed,
+                                   39, 18, 33, 12, 35, 119, 153, 119, 94, 119, 212, 119, SKIN_EQMAIN);
+    g_signal_connect(equalizerwin_auto, "clicked", equalizerwin_auto_pushed, NULL);
+    UI_SKINNED_BUTTON(equalizerwin_auto)->inside = cfg.equalizer_autoload;
+
+    equalizerwin_presets = ui_skinned_button_new();
+    ui_skinned_push_button_setup(equalizerwin_presets, SKINNED_WINDOW(equalizerwin)->fixed,
+                                 217, 18, 44, 12, 224, 164, 224, 176, SKIN_EQMAIN);
+    g_signal_connect(equalizerwin_presets, "clicked", equalizerwin_presets_pushed, NULL );
+
+    equalizerwin_close = ui_skinned_button_new();
+    ui_skinned_push_button_setup(equalizerwin_close, SKINNED_WINDOW(equalizerwin)->fixed,
+                                 264, 3, 9, 9, 0, 116, 0, 125, SKIN_EQMAIN);
+    g_signal_connect(equalizerwin_close, "clicked", equalizerwin_close_cb, NULL );
+
+    equalizerwin_shade = ui_skinned_button_new();
+    ui_skinned_push_button_setup(equalizerwin_shade, SKINNED_WINDOW(equalizerwin)->fixed,
+                                 254, 3, 9, 9, 254, 137, 1, 38, SKIN_EQMAIN);
+    ui_skinned_button_set_skin_index2(equalizerwin_shade, SKIN_EQ_EX);
+    g_signal_connect(equalizerwin_shade, "clicked", equalizerwin_shade_toggle, NULL );
+
+    equalizerwin_graph = ui_skinned_equalizer_graph_new(SKINNED_WINDOW(equalizerwin)->fixed, 86, 17);
+
+    equalizerwin_preamp = ui_skinned_equalizer_slider_new(SKINNED_WINDOW(equalizerwin)->fixed, 21, 38);
+    equalizerwin_set_preamp(cfg.equalizer_preamp);
+
+    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++) {
+        equalizerwin_bands[i] =
+            ui_skinned_equalizer_slider_new(SKINNED_WINDOW(equalizerwin)->fixed, 78 + (i * 18), 38);
+        equalizerwin_set_band(i, cfg.equalizer_bands[i]);
+    }
+
+    equalizerwin_volume =
+        ui_skinned_horizontal_slider_new(SKINNED_WINDOW(equalizerwin)->fixed,
+                                         61, 4, 97, 8, 1, 30, 1, 30, 3, 7, 4, 61, 0, 94,
+                                         equalizerwin_volume_frame_cb, SKIN_EQ_EX);
+    g_signal_connect(equalizerwin_volume, "motion", G_CALLBACK(equalizerwin_volume_motion_cb), NULL);
+    g_signal_connect(equalizerwin_volume, "release", G_CALLBACK(equalizerwin_volume_release_cb), NULL);
+
+
+    equalizerwin_balance =
+        ui_skinned_horizontal_slider_new(SKINNED_WINDOW(equalizerwin)->fixed,
+                       164, 4, 42, 8, 11, 30, 11, 30, 3, 7, 4, 164, 0, 39,
+                       equalizerwin_balance_frame_cb, SKIN_EQ_EX);
+    g_signal_connect(equalizerwin_balance, "motion", G_CALLBACK(equalizerwin_balance_motion_cb), NULL);
+    g_signal_connect(equalizerwin_balance, "release", G_CALLBACK(equalizerwin_balance_release_cb), NULL);
+}
+
+
+static void
+equalizerwin_create_window(void)
+{
+    GdkPixbuf *icon;
+    gint width, height;
+
+    width = 275;
+    height = cfg.equalizer_shaded ? 14 : 116;
+
+    equalizerwin = ui_skinned_window_new("equalizer");
+    gtk_window_set_title(GTK_WINDOW(equalizerwin), _("Audacious Equalizer"));
+    gtk_window_set_role(GTK_WINDOW(equalizerwin), "equalizer");
+    gtk_window_set_resizable(GTK_WINDOW(equalizerwin), FALSE);
+
+    if (cfg.scaled && cfg.eq_scaled_linked) {
+        width *= cfg.scale_factor;
+        height *= cfg.scale_factor;
+    }
+
+    gtk_widget_set_size_request(equalizerwin, width, height);
+
+    /* this will hide only mainwin. it's annoying! yaz */
+    gtk_window_set_transient_for(GTK_WINDOW(equalizerwin),
+                                 GTK_WINDOW(mainwin));
+    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(equalizerwin), TRUE);
+
+    icon = gdk_pixbuf_new_from_xpm_data((const gchar **) audacious_eq_icon);
+    gtk_window_set_icon(GTK_WINDOW(equalizerwin), icon);
+    g_object_unref(icon);
+
+    gtk_widget_set_app_paintable(equalizerwin, TRUE);
+
+    if (cfg.equalizer_x != -1 && cfg.save_window_position)
+        gtk_window_move(GTK_WINDOW(equalizerwin),
+                        cfg.equalizer_x, cfg.equalizer_y);
+
+    g_signal_connect(equalizerwin, "delete_event",
+                     G_CALLBACK(equalizerwin_delete), NULL);
+    g_signal_connect(equalizerwin, "button_press_event",
+                     G_CALLBACK(equalizerwin_press), NULL);
+    g_signal_connect(equalizerwin, "key_press_event",
+                     G_CALLBACK(equalizerwin_keypress), NULL);
+}
+
+void
+equalizerwin_create(void)
+{
+    equalizer_presets = equalizer_read_presets("eq.preset");
+    equalizer_auto_presets = equalizer_read_presets("eq.auto_preset");
+
+    equalizerwin_create_window();
+
+    gtk_window_add_accel_group( GTK_WINDOW(equalizerwin) , ui_manager_get_accel_group() );
+
+    equalizerwin_create_widgets();
+}
+
+
+void
+equalizerwin_show(gboolean show)
+{
+    GtkAction *action = gtk_action_group_get_action(
+      toggleaction_group_others , "show equalizer" );
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , show );
+
+    if (show)
+        equalizerwin_real_show();
+    else
+        equalizerwin_real_hide();
+}
+
+void
+equalizerwin_real_show(void)
+{
+    gtk_window_move(GTK_WINDOW(equalizerwin), cfg.equalizer_x, cfg.equalizer_y);
+    if (cfg.scaled && cfg.eq_scaled_linked)
+        gtk_widget_set_size_request(equalizerwin, 275 * cfg.scale_factor,
+                                    ((cfg.equalizer_shaded ? 14 : 116) * cfg.scale_factor));
+    else
+        gtk_widget_set_size_request(equalizerwin, 275,
+                                    (cfg.equalizer_shaded ? 14 : 116));
+    cfg.equalizer_visible = TRUE;
+    UI_SKINNED_BUTTON(mainwin_eq)->inside = TRUE;
+    gtk_widget_show_all(equalizerwin);
+
+    if (!cfg.equalizer_shaded) {
+        gtk_widget_hide(equalizerwin_volume);
+        gtk_widget_hide(equalizerwin_balance);
+    }
+    else {
+        ui_skinned_set_push_button_data(equalizerwin_shade, -1, 3, -1, 47);
+        ui_skinned_button_set_skin_index1(equalizerwin_shade, SKIN_EQ_EX);
+        ui_skinned_set_push_button_data(equalizerwin_close, 11, 38, 11, 47);
+        ui_skinned_button_set_skin_index(equalizerwin_close, SKIN_EQ_EX);
+    }
+
+    gtk_window_present(GTK_WINDOW(equalizerwin));
+}
+
+void
+equalizerwin_real_hide(void)
+{
+    /*
+     * This function should only be called from the
+     * main menu signal handler
+     */
+    gtk_widget_hide(equalizerwin);
+    cfg.equalizer_visible = FALSE;
+    UI_SKINNED_BUTTON(mainwin_eq)->inside = FALSE;
+    gtk_widget_queue_draw(mainwin_eq);
+}
+
+static EqualizerPreset *
+equalizerwin_find_preset(GList * list, const gchar * name)
+{
+    GList *node = list;
+    EqualizerPreset *preset;
+
+    while (node) {
+        preset = node->data;
+        if (!strcasecmp(preset->name, name))
+            return preset;
+        node = g_list_next(node);
+    }
+    return NULL;
+}
+
+static gboolean
+equalizerwin_load_preset(GList * list, const gchar * name)
+{
+    EqualizerPreset *preset;
+    gint i;
+
+    if ((preset = equalizerwin_find_preset(list, name)) != NULL) {
+        equalizerwin_set_preamp(preset->preamp);
+        for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+            equalizerwin_set_band(i, preset->bands[i]);
+
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static GList *
+equalizerwin_save_preset(GList * list, const gchar * name,
+                         const gchar * filename)
+{
+    gint i;
+    EqualizerPreset *preset;
+
+    if (!(preset = equalizerwin_find_preset(list, name))) {
+        preset = g_new0(EqualizerPreset, 1);
+        preset->name = g_strdup(name);
+        list = g_list_append(list, preset);
+    }
+
+    preset->preamp = equalizerwin_get_preamp();
+    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+        preset->bands[i] = equalizerwin_get_band(i);
+
+    equalizer_write_preset_file(list, filename);
+
+    return list;
+}
+
+static GList *
+equalizerwin_delete_preset(GList * list, gchar * name, gchar * filename)
+{
+    EqualizerPreset *preset;
+    GList *node;
+
+    if (!(preset = equalizerwin_find_preset(list, name)))
+        return list;
+
+    if (!(node = g_list_find(list, preset)))
+        return list;
+
+    list = g_list_remove_link(list, node);
+    equalizer_preset_free(preset);
+    g_list_free_1(node);
+
+    equalizer_write_preset_file(list, filename);
+
+    return list;
+}
+
+static void
+equalizerwin_delete_selected_presets(GtkTreeView *view, gchar *filename)
+{
+    gchar *text;
+
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
+    GtkTreeModel *model = gtk_tree_view_get_model(view);
+
+    /*
+     * first we are making a list of the selected rows, then we convert this
+     * list into a list of GtkTreeRowReferences, so that when you delete an
+     * item you can still access the other items
+     * finally we iterate through all GtkTreeRowReferences, convert them to
+     * GtkTreeIters and delete those one after the other
+     */
+
+    GList *list = gtk_tree_selection_get_selected_rows(selection, &model);
+    GList *rrefs = NULL;
+    GList *litr;
+
+    for (litr = list; litr; litr = litr->next)
+    {
+        GtkTreePath *path = litr->data;
+        rrefs = g_list_append(rrefs, gtk_tree_row_reference_new(model, path));
+    }
+
+    for (litr = rrefs; litr; litr = litr->next)
+    {
+        GtkTreeRowReference *ref = litr->data;
+        GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
+        GtkTreeIter iter;
+        gtk_tree_model_get_iter(model, &iter, path);
+
+        gtk_tree_model_get(model, &iter, 0, &text, -1);
+
+        if (!strcmp(filename, "eq.preset"))
+            equalizer_presets = equalizerwin_delete_preset(equalizer_presets, text, filename);
+        else if (!strcmp(filename, "eq.auto_preset"))
+            equalizer_auto_presets = equalizerwin_delete_preset(equalizer_auto_presets, text, filename);
+
+        gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+    }
+}
+
+static void
+free_cb (gpointer data, gpointer user_data)
+{
+    equalizer_preset_free((EqualizerPreset*)data);
+}
+
+static void
+equalizerwin_read_winamp_eqf(VFSFile * file)
+{
+    GList *presets;
+    gint i;
+
+    if ((presets = import_winamp_eqf(file)) == NULL)
+        return;
+
+    /* just get the first preset --asphyx */
+    EqualizerPreset *preset = (EqualizerPreset*)presets->data;
+    equalizerwin_set_preamp(preset->preamp);
+
+    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+        equalizerwin_set_band(i, preset->bands[i]);
+
+    g_list_foreach(presets, free_cb, NULL);
+    g_list_free(presets);
+
+    equalizerwin_eq_changed();
+}
+
+static void
+equalizerwin_read_aud_preset(gchar * filename)
+{
+    EqualizerPreset *preset = equalizer_read_aud_preset(filename);
+    if (preset) {
+        equalizerwin_apply_preset(preset);
+        equalizer_preset_free(preset);
+    }
+}
+
+static void
+equalizerwin_save_ok(GtkWidget * widget, gpointer data)
+{
+    const gchar *text;
+
+    text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_entry));
+    if (strlen(text) != 0)
+        equalizer_presets =
+            equalizerwin_save_preset(equalizer_presets, text, "eq.preset");
+    gtk_widget_destroy(equalizerwin_save_window);
+}
+
+static void
+equalizerwin_save_select(GtkTreeView *treeview, GtkTreePath *path,
+                         GtkTreeViewColumn *col, gpointer data)
+{
+    gchar *text;
+
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+
+    if (selection)
+    {
+        if (gtk_tree_selection_get_selected(selection, &model, &iter))
+        {
+            gtk_tree_model_get(model, &iter, 0, &text, -1);
+            gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_entry), text);
+            equalizerwin_save_ok(NULL, NULL);
+
+            g_free(text);
+        }
+    }
+}
+
+static void
+equalizerwin_load_ok(GtkWidget *widget, gpointer data)
+{
+    gchar *text;
+
+    GtkTreeView* view = GTK_TREE_VIEW(data);
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+
+    if (selection)
+    {
+        if (gtk_tree_selection_get_selected(selection, &model, &iter))
+        {
+            gtk_tree_model_get(model, &iter, 0, &text, -1);
+            equalizerwin_load_preset(equalizer_presets, text);
+
+            g_free(text);
+        }
+    }
+    gtk_widget_destroy(equalizerwin_load_window);
+}
+
+static void
+equalizerwin_load_select(GtkTreeView *treeview, GtkTreePath *path,
+                         GtkTreeViewColumn *col, gpointer data)
+{
+    equalizerwin_load_ok(NULL, treeview);
+}
+
+static void
+equalizerwin_delete_delete(GtkWidget *widget, gpointer data)
+{
+    equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.preset");
+}
+
+static void
+equalizerwin_save_auto_ok(GtkWidget *widget, gpointer data)
+{
+    const gchar *text;
+
+    text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_auto_entry));
+    if (strlen(text) != 0)
+        equalizer_auto_presets =
+            equalizerwin_save_preset(equalizer_auto_presets, text,
+                                     "eq.auto_preset");
+    gtk_widget_destroy(equalizerwin_save_auto_window);
+}
+
+static void
+equalizerwin_save_auto_select(GtkTreeView *treeview, GtkTreePath *path,
+                              GtkTreeViewColumn *col, gpointer data)
+{
+    gchar *text;
+
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+
+    if (selection)
+    {
+        if (gtk_tree_selection_get_selected(selection, &model, &iter))
+        {
+            gtk_tree_model_get(model, &iter, 0, &text, -1);
+            gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_auto_entry), text);
+            equalizerwin_save_auto_ok(NULL, NULL);
+
+            g_free(text);
+        }
+    }
+}
+
+static void
+equalizerwin_load_auto_ok(GtkWidget *widget, gpointer data)
+{
+    gchar *text;
+
+    GtkTreeView *view = GTK_TREE_VIEW(data);
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+
+    if (selection)
+    {
+        if (gtk_tree_selection_get_selected(selection, &model, &iter))
+        {
+            gtk_tree_model_get(model, &iter, 0, &text, -1);
+            equalizerwin_load_preset(equalizer_auto_presets, text);
+
+            g_free(text);
+        }
+    }
+    gtk_widget_destroy(equalizerwin_load_auto_window);
+}
+
+static void
+equalizerwin_load_auto_select(GtkTreeView *treeview, GtkTreePath *path,
+                              GtkTreeViewColumn *col, gpointer data)
+{
+    equalizerwin_load_auto_ok(NULL, treeview);
+}
+
+static void
+equalizerwin_delete_auto_delete(GtkWidget *widget, gpointer data)
+{
+    equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.auto_preset");
+}
+
+static VFSFile *
+open_vfs_file(const gchar *filename, const gchar *mode)
+{
+    VFSFile *file;
+    GtkWidget *dialog;
+
+    if (!(file = vfs_fopen(filename, mode))) {
+        dialog = gtk_message_dialog_new (GTK_WINDOW (mainwin),
+                                         GTK_DIALOG_DESTROY_WITH_PARENT,
+                                         GTK_MESSAGE_ERROR,
+                                         GTK_BUTTONS_CLOSE,
+                                         "Error loading file '%s'",
+                                         filename);
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+    }
+
+    return file;
+}
+
+static void
+load_winamp_file(const gchar * filename)
+{
+    VFSFile *file;
+
+    if (!(file = open_vfs_file(filename, "rb")))
+        return;
+
+    equalizerwin_read_winamp_eqf(file);
+    vfs_fclose(file);
+}
+
+static void
+import_winamp_file(const gchar * filename)
+{
+    VFSFile *file;
+    GList *list;
+
+    if (!(file = open_vfs_file(filename, "rb")) ||
+        !(list = import_winamp_eqf(file)))
+        return;
+
+    equalizer_presets = g_list_concat(equalizer_presets, list);
+    equalizer_write_preset_file(equalizer_presets, "eq.preset");
+
+    vfs_fclose(file);
+}
+
+static void
+save_winamp_file(const gchar * filename)
+{
+    VFSFile *file;
+
+    gchar name[257];
+    gint i;
+    guchar bands[11];
+
+    if (!(file = open_vfs_file(filename, "wb")))
+        return;
+
+    vfs_fwrite("Winamp EQ library file v1.1\x1a!--", 1, 31, file);
+
+    memset(name, 0, 257);
+    g_strlcpy(name, "Entry1", 257);
+    vfs_fwrite(name, 1, 257, file);
+
+    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+        bands[i] = 63 - (((equalizerwin_get_band(i) + EQUALIZER_MAX_GAIN) * 63) / EQUALIZER_MAX_GAIN / 2);
+
+    bands[AUD_EQUALIZER_NBANDS] = 63 - (((equalizerwin_get_preamp() + EQUALIZER_MAX_GAIN) * 63) / EQUALIZER_MAX_GAIN / 2);
+
+    vfs_fwrite(bands, 1, 11, file);
+    vfs_fclose(file);
+}
+
+static GtkWidget *
+equalizerwin_create_list_window(GList *preset_list,
+                                const gchar *title,
+                                GtkWidget **window,
+                                GtkSelectionMode sel_mode,
+                                GtkWidget **entry,
+                                const gchar *action_name,
+                                GCallback action_func,
+                                GCallback select_row_func)
+{
+    GtkWidget *vbox, *scrolled_window, *bbox, *view;
+    GtkWidget *button_cancel, *button_action;
+    GList *node;
+
+    GtkListStore *store;
+    GtkTreeIter iter;
+    GtkTreeModel *model;
+    GtkCellRenderer *renderer;
+    GtkTreeSelection *selection;
+    GtkTreeSortable *sortable;
+
+
+
+    *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title(GTK_WINDOW(*window), title);
+    gtk_window_set_type_hint(GTK_WINDOW(*window), GDK_WINDOW_TYPE_HINT_DIALOG);
+    gtk_window_set_default_size(GTK_WINDOW(*window), 350, 300);
+    gtk_window_set_position(GTK_WINDOW(*window), GTK_WIN_POS_CENTER);
+    gtk_container_set_border_width(GTK_CONTAINER(*window), 10);
+    gtk_window_set_transient_for(GTK_WINDOW(*window),
+                                 GTK_WINDOW(equalizerwin));
+    g_signal_connect(*window, "destroy",
+                     G_CALLBACK(gtk_widget_destroyed), window);
+
+    vbox = gtk_vbox_new(FALSE, 10);
+    gtk_container_add(GTK_CONTAINER(*window), vbox);
+
+    scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+
+
+    /* fill the store with the names of all available presets */
+    store = gtk_list_store_new(1, G_TYPE_STRING);
+    for (node = preset_list; node; node = g_list_next(node))
+    {
+        gtk_list_store_append(store, &iter);
+        gtk_list_store_set(store, &iter,
+                           0, ((EqualizerPreset*)node->data)->name,
+                           -1);
+    }
+    model = GTK_TREE_MODEL(store);
+
+
+    sortable = GTK_TREE_SORTABLE(store);
+    gtk_tree_sortable_set_sort_column_id(sortable, 0, GTK_SORT_ASCENDING);
+
+
+    view = gtk_tree_view_new();
+    renderer = gtk_cell_renderer_text_new();
+    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1,
+                                                _("Presets"), renderer,
+                                                "text", 0, NULL);
+    gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+    g_object_unref(model);
+
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+    gtk_tree_selection_set_mode(selection, sel_mode);
+
+
+
+
+    gtk_container_add(GTK_CONTAINER(scrolled_window), view);
+    gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
+
+    if (entry) {
+        *entry = gtk_entry_new();
+        g_signal_connect(*entry, "activate", action_func, NULL);
+        gtk_box_pack_start(GTK_BOX(vbox), *entry, FALSE, FALSE, 0);
+    }
+
+    bbox = gtk_hbutton_box_new();
+    gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+    gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+    gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+
+    button_cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+    g_signal_connect_swapped(button_cancel, "clicked",
+                             G_CALLBACK(gtk_widget_destroy),
+                             GTK_OBJECT(*window));
+    gtk_box_pack_start(GTK_BOX(bbox), button_cancel, TRUE, TRUE, 0);
+
+    button_action = gtk_button_new_from_stock(action_name);
+    g_signal_connect(button_action, "clicked", G_CALLBACK(action_func), view);
+    GTK_WIDGET_SET_FLAGS(button_action, GTK_CAN_DEFAULT);
+
+    if (select_row_func)
+        g_signal_connect(view, "row-activated", G_CALLBACK(select_row_func), NULL);
+
+        
+    gtk_box_pack_start(GTK_BOX(bbox), button_action, TRUE, TRUE, 0);
+
+    gtk_widget_grab_default(button_action);
+
+
+    gtk_widget_show_all(*window);
+
+    return *window;
+}
+
+void
+equalizerwin_load_auto_preset(const gchar * filename)
+{
+    gchar *presetfilename, *directory;
+
+    g_return_if_fail(filename != NULL);
+
+    if (!cfg.equalizer_autoload)
+        return;
+
+    presetfilename = g_strconcat(filename, ".", cfg.eqpreset_extension, NULL);
+
+    /* First try to find a per file preset file */
+    if (strlen(cfg.eqpreset_extension) > 0) {
+        equalizerwin_read_aud_preset(presetfilename);
+        g_free(presetfilename);
+        return;
+    }
+
+    g_free(presetfilename);
+
+    directory = g_path_get_dirname(filename);
+    presetfilename = g_build_filename(directory, cfg.eqpreset_default_file,
+                                      NULL);
+    g_free(directory);
+
+    /* Try to find a per directory preset file */
+    if (strlen(cfg.eqpreset_default_file) > 0) {
+        equalizerwin_read_aud_preset(presetfilename);
+    }
+    else if (!equalizerwin_load_preset
+             (equalizer_auto_presets, g_basename(filename))) {
+        /* Fall back to the oldstyle auto presets */
+        equalizerwin_load_preset(equalizer_presets, "Default");
+    }
+
+    g_free(presetfilename);
+}
+
+void
+equalizerwin_set_preamp(gfloat preamp)
+{
+    ui_skinned_equalizer_slider_set_position(equalizerwin_preamp, preamp);
+    equalizerwin_eq_changed();
+}
+
+void
+equalizerwin_set_band(gint band, gfloat value)
+{
+    g_return_if_fail(band >= 0 && band < AUD_EQUALIZER_NBANDS);
+    ui_skinned_equalizer_slider_set_position(equalizerwin_bands[band], value);
+    equalizerwin_eq_changed();
+}
+
+gfloat
+equalizerwin_get_preamp(void)
+{
+    return ui_skinned_equalizer_slider_get_position(equalizerwin_preamp);
+}
+
+gfloat
+equalizerwin_get_band(gint band)
+{
+    g_return_val_if_fail(band >= 0 && band < AUD_EQUALIZER_NBANDS, 0.0);
+    return ui_skinned_equalizer_slider_get_position(equalizerwin_bands[band]);
+}
+
+void
+action_equ_load_preset(void)
+{
+    if (equalizerwin_load_window) {
+        gtk_window_present(GTK_WINDOW(equalizerwin_load_window));
+        return;
+    }
+
+    equalizerwin_create_list_window(equalizer_presets,
+                                    Q_("Load preset"),
+                                    &equalizerwin_load_window,
+                                    GTK_SELECTION_SINGLE, NULL,
+                                    GTK_STOCK_OK,
+                                    G_CALLBACK(equalizerwin_load_ok),
+                                    G_CALLBACK(equalizerwin_load_select));
+}
+
+void
+action_equ_load_auto_preset(void)
+{
+    if (equalizerwin_load_auto_window) {
+        gtk_window_present(GTK_WINDOW(equalizerwin_load_auto_window));
+        return;
+    }
+
+    equalizerwin_create_list_window(equalizer_auto_presets,
+                                    Q_("Load auto-preset"),
+                                    &equalizerwin_load_auto_window,
+                                    GTK_SELECTION_SINGLE, NULL,
+                                    GTK_STOCK_OK,
+                                    G_CALLBACK(equalizerwin_load_auto_ok),
+                                    G_CALLBACK(equalizerwin_load_auto_select));
+}
+
+void
+action_equ_load_default_preset(void)
+{
+    equalizerwin_load_preset(equalizer_presets, "Default");
+}
+
+void
+action_equ_zero_preset(void)
+{
+    gint i;
+
+    equalizerwin_set_preamp(0);
+    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+        equalizerwin_set_band(i, 0);
+}
+
+void
+action_equ_load_preset_file(void)
+{
+    GtkWidget *dialog;
+    gchar *file_uri;
+
+    dialog = make_filebrowser(Q_("Load equalizer preset"), FALSE);
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+        EqualizerPreset *preset = load_preset_file(file_uri);
+        equalizerwin_apply_preset(preset);
+        equalizer_preset_free(preset);
+        g_free(file_uri);
+    }
+    gtk_widget_destroy(dialog);
+}
+
+void
+action_equ_load_preset_eqf(void)
+{
+    GtkWidget *dialog;
+    gchar *file_uri;
+
+    dialog = make_filebrowser(Q_("Load equalizer preset"), FALSE);
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+        load_winamp_file(file_uri);
+        g_free(file_uri);
+    }
+    gtk_widget_destroy(dialog);
+}
+
+void
+action_equ_import_winamp_presets(void)
+{
+    GtkWidget *dialog;
+    gchar *file_uri;
+
+    dialog = make_filebrowser(Q_("Load equalizer preset"), FALSE);
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+        import_winamp_file(file_uri);
+        g_free(file_uri);
+    }
+    gtk_widget_destroy(dialog);
+}
+
+void
+action_equ_save_preset(void)
+{
+    if (equalizerwin_save_window) {
+        gtk_window_present(GTK_WINDOW(equalizerwin_save_window));
+        return;
+    }
+     
+    equalizerwin_create_list_window(equalizer_presets,
+                                    Q_("Save preset"),
+                                    &equalizerwin_save_window,
+                                    GTK_SELECTION_SINGLE,
+                                    &equalizerwin_save_entry,
+                                    GTK_STOCK_OK,
+                                    G_CALLBACK(equalizerwin_save_ok),
+                                    G_CALLBACK(equalizerwin_save_select));
+}
+
+void
+action_equ_save_auto_preset(void)
+{
+    gchar *name;
+    Playlist *playlist = playlist_get_active();
+
+    if (equalizerwin_save_auto_window)
+        gtk_window_present(GTK_WINDOW(equalizerwin_save_auto_window));
+    else
+        equalizerwin_create_list_window(equalizer_auto_presets,
+                                        Q_("Save auto-preset"),
+                                        &equalizerwin_save_auto_window,
+                                        GTK_SELECTION_SINGLE,
+                                        &equalizerwin_save_auto_entry,
+                                        GTK_STOCK_OK,
+                                        G_CALLBACK(equalizerwin_save_auto_ok),
+                                        G_CALLBACK(equalizerwin_save_auto_select));
+
+    name = playlist_get_filename(playlist, playlist_get_position(playlist));
+    if (name) {
+        gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_auto_entry),
+                           g_basename(name));
+        g_free(name);
+    }
+}
+
+void
+action_equ_save_default_preset(void)
+{
+    equalizer_presets =
+        equalizerwin_save_preset(equalizer_presets, Q_("Default"), "eq.preset");
+}
+
+void
+action_equ_save_preset_file(void)
+{
+    GtkWidget *dialog;
+    gchar *file_uri;
+    gchar *songname;
+    Playlist *playlist = playlist_get_active();
+    int i;
+
+    dialog = make_filebrowser(Q_("Save equalizer preset"), TRUE);
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+        EqualizerPreset *preset = g_new0(EqualizerPreset, 1);
+        preset->name = g_strdup(file_uri);
+        preset->preamp = equalizerwin_get_preamp();
+        for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
+            preset->bands[i] = equalizerwin_get_band(i);
+        save_preset_file(preset, file_uri);
+        equalizer_preset_free(preset);
+        g_free(file_uri);
+    }
+
+    songname = playlist_get_filename(playlist, playlist_get_position(playlist));
+    if (songname) {
+        gchar *eqname = g_strdup_printf("%s.%s", songname,
+                                        cfg.eqpreset_extension);
+        g_free(songname);
+        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
+                                      eqname);
+        g_free(eqname);
+    }
+
+    gtk_widget_destroy(dialog);
+}
+
+void
+action_equ_save_preset_eqf(void)
+{
+    GtkWidget *dialog;
+    gchar *file_uri;
+
+    dialog = make_filebrowser(Q_("Save equalizer preset"), TRUE);
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
+        save_winamp_file(file_uri);
+        g_free(file_uri);
+    }
+    gtk_widget_destroy(dialog);
+}
+
+void
+action_equ_delete_preset(void)
+{
+    if (equalizerwin_delete_window) {
+        gtk_window_present(GTK_WINDOW(equalizerwin_delete_window));
+        return;
+    }
+    
+    equalizerwin_create_list_window(equalizer_presets,
+                                    Q_("Delete preset"),
+                                    &equalizerwin_delete_window,
+                                    GTK_SELECTION_EXTENDED, NULL,
+                                    GTK_STOCK_DELETE,
+                                    G_CALLBACK(equalizerwin_delete_delete),
+                                    NULL);
+}
+
+void
+action_equ_delete_auto_preset(void)
+{
+    if (equalizerwin_delete_auto_window) {
+        gtk_window_present(GTK_WINDOW(equalizerwin_delete_auto_window));
+        return;
+    }
+    
+    equalizerwin_create_list_window(equalizer_auto_presets,
+                                    Q_("Delete auto-preset"),
+                                    &equalizerwin_delete_auto_window,
+                                    GTK_SELECTION_EXTENDED, NULL,
+                                    GTK_STOCK_DELETE,
+                                    G_CALLBACK(equalizerwin_delete_auto_delete),
+                                    NULL);
+}
+
+void
+equalizerwin_activate(gboolean active)
+{
+    cfg.equalizer_active = active;
+    UI_SKINNED_BUTTON(equalizerwin_on)->inside = active;
+    gtk_widget_queue_draw(equalizerwin_on);
+    equalizerwin_eq_changed();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_equalizer.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,68 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  Based on BMP:
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_EQUALIZER_H
+#define AUDACIOUS_UI_EQUALIZER_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#define EQUALIZER_SCALED     (cfg.scaled && cfg.eq_scaled_linked)
+#define EQUALIZER_SCALE_FACTOR (EQUALIZER_SCALED ? cfg.scale_factor : 1)
+
+#define EQUALIZER_HEIGHT         ((cfg.equalizer_shaded ? 14 : 116) * (EQUALIZER_SCALE_FACTOR))
+#define EQUALIZER_WIDTH          (275 * EQUALIZER_SCALE_FACTOR)
+
+#define EQUALIZER_DEFAULT_POS_X  20
+#define EQUALIZER_DEFAULT_POS_Y  136
+
+#define EQUALIZER_DEFAULT_DIR_PRESET "dir_default.preset"
+#define EQUALIZER_DEFAULT_PRESET_EXT "preset"
+
+void equalizerwin_set_scaled(gboolean ds);
+void equalizerwin_set_shade_menu_cb(gboolean shaded);
+void draw_equalizer_window(gboolean force);
+void equalizerwin_create(void);
+void equalizerwin_show(gboolean show);
+void equalizerwin_real_show(void);
+void equalizerwin_real_hide(void);
+void equalizerwin_load_auto_preset(const gchar * filename);
+void equalizerwin_set_volume_slider(gint percent);
+void equalizerwin_set_balance_slider(gint percent);
+void equalizerwin_eq_changed(void);
+void equalizerwin_set_preamp(gfloat preamp);
+void equalizerwin_set_band(gint band, gfloat value);
+gfloat equalizerwin_get_preamp(void);
+gfloat equalizerwin_get_band(gint band);
+
+gboolean equalizerwin_has_focus(void);
+
+extern GtkWidget *equalizerwin;
+extern GtkWidget *equalizerwin_graph;
+extern gboolean equalizerwin_focus;
+
+void equalizerwin_activate(gboolean active);
+
+#endif /* AUDACIOUS_UI_EQUALIZER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_hints.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,59 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team
+ *
+ *  Based on BMP:
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_hints.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "ui_playlist.h"
+
+#include "platform/smartinclude.h"
+
+void
+hint_set_always(gboolean always)
+{
+    gtk_window_set_keep_above(GTK_WINDOW(mainwin), always);
+    gtk_window_set_keep_above(GTK_WINDOW(equalizerwin), always);
+    gtk_window_set_keep_above(GTK_WINDOW(playlistwin), always);
+}
+
+void
+hint_set_sticky(gboolean sticky)
+{
+    if (sticky) {
+        gtk_window_stick(GTK_WINDOW(mainwin));
+        gtk_window_stick(GTK_WINDOW(equalizerwin));
+        gtk_window_stick(GTK_WINDOW(playlistwin));
+    }
+    else {
+        gtk_window_unstick(GTK_WINDOW(mainwin));
+        gtk_window_unstick(GTK_WINDOW(equalizerwin));
+        gtk_window_unstick(GTK_WINDOW(playlistwin));
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_hints.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,35 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team
+ *
+ *  Based on BMP:
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_HINTS_H
+#define AUDACIOUS_UI_HINTS_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+void hint_set_always(gboolean always);
+void hint_set_sticky(gboolean sticky);
+
+#endif /* AUDACIOUS_UI_HINTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_main.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,2805 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2006  Audacious development team.
+ *
+ *  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkmessagedialog.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+/* GDK including */
+#include "platform/smartinclude.h"
+
+#if defined(USE_REGEX_ONIGURUMA)
+#include <onigposix.h>
+#elif defined(USE_REGEX_PCRE)
+#include <pcreposix.h>
+#else
+#include <regex.h>
+#endif
+
+#include "ui_main.h"
+#include "icons-stock.h"
+
+#include "actions-mainwin.h"
+#include "configdb.h"
+#include "dnd.h"
+#include "input.h"
+#include "main.h"
+#include "playback.h"
+#include "playlist.h"
+#include "pluginenum.h"
+#include "strings.h"
+#include "ui_credits.h"
+#include "ui_dock.h"
+#include "ui_equalizer.h"
+#include "ui_fileinfo.h"
+#include "ui_fileopener.h"
+#include "ui_hints.h"
+#include "ui_jumptotrack.h"
+#include "ui_main_evlisteners.h"
+#include "ui_manager.h"
+#include "ui_playlist.h"
+#include "ui_preferences.h"
+#include "ui_skinselector.h"
+#include "util.h"
+#include "visualization.h"
+
+#include "ui_skinned_window.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_textbox.h"
+#include "ui_skinned_number.h"
+#include "ui_skinned_horizontal_slider.h"
+#include "ui_skinned_menurow.h"
+#include "ui_skinned_playstatus.h"
+#include "ui_skinned_monostereo.h"
+#include "ui_skinned_playlist.h"
+
+static GTimeVal cb_time; 
+static const int TRISTATE_THRESHOLD = 200;
+
+enum {
+    MAINWIN_SEEK_REV = -1,
+    MAINWIN_SEEK_NIL,
+    MAINWIN_SEEK_FWD
+};
+
+GtkWidget *mainwin = NULL;
+
+static gint balance;
+
+static GtkWidget *mainwin_jtt = NULL;
+
+static gint seek_state = MAINWIN_SEEK_NIL;
+static gint seek_initial_pos = 0;
+
+static GtkWidget *mainwin_menubtn;
+static GtkWidget *mainwin_minimize, *mainwin_shade, *mainwin_close;
+
+static GtkWidget *mainwin_rew, *mainwin_fwd;
+static GtkWidget *mainwin_eject;
+static GtkWidget *mainwin_play, *mainwin_pause, *mainwin_stop;
+
+static GtkWidget *mainwin_shuffle, *mainwin_repeat;
+GtkWidget *mainwin_eq, *mainwin_pl;
+
+GtkWidget *mainwin_info;
+GtkWidget *mainwin_stime_min, *mainwin_stime_sec;
+
+static GtkWidget *mainwin_rate_text, *mainwin_freq_text, *mainwin_othertext;
+
+GtkWidget *mainwin_playstatus;
+
+GtkWidget *mainwin_minus_num, *mainwin_10min_num, *mainwin_min_num;
+GtkWidget *mainwin_10sec_num, *mainwin_sec_num;
+
+GtkWidget *mainwin_vis;
+GtkWidget *mainwin_svis;
+
+GtkWidget *mainwin_sposition = NULL;
+
+static GtkWidget *mainwin_menurow;
+static GtkWidget *mainwin_volume, *mainwin_balance;
+GtkWidget *mainwin_position;
+
+static GtkWidget *mainwin_monostereo;
+static GtkWidget *mainwin_srew, *mainwin_splay, *mainwin_spause;
+static GtkWidget *mainwin_sstop, *mainwin_sfwd, *mainwin_seject, *mainwin_about;
+
+static gint mainwin_timeout_id;
+
+static gboolean mainwin_info_text_locked = FALSE;
+static guint mainwin_volume_release_timeout = 0;
+
+static int ab_position_a = -1;
+static int ab_position_b = -1;
+
+static void mainwin_refresh_visible(void);
+static gint mainwin_idle_func(gpointer data);
+
+static void set_timer_mode_menu_cb(TimerMode mode);
+static void set_timer_mode(TimerMode mode);
+static void change_timer_mode(void);
+
+static void mainwin_position_motion_cb(GtkWidget *widget, gint pos);
+static void mainwin_position_release_cb(GtkWidget *widget, gint pos);
+
+static void set_scaled(gboolean scaled);
+static void mainwin_eq_pushed(gboolean toggled);
+static void mainwin_pl_pushed(gboolean toggled);
+
+static void
+mainwin_set_title_scroll(gboolean scroll)
+{
+    cfg.autoscroll = scroll;
+    ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll);
+}
+
+
+void
+mainwin_set_always_on_top(gboolean always)
+{
+    GtkAction *action = gtk_action_group_get_action(toggleaction_group_others,
+                                                    "view always on top");
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , always );
+}
+
+static void
+mainwin_set_shade(gboolean shaded)
+{
+    GtkAction *action = gtk_action_group_get_action(toggleaction_group_others,
+                                                    "roll up player");
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded );
+}
+
+static void
+mainwin_set_shade_menu_cb(gboolean shaded)
+{
+    cfg.player_shaded = shaded;
+
+    if (shaded) {
+        dock_shade(get_dock_window_list(), GTK_WINDOW(mainwin),
+                   MAINWIN_SHADED_HEIGHT * MAINWIN_SCALE_FACTOR);
+    } else {
+        gint height = !aud_active_skin->properties.mainwin_height ? MAINWIN_HEIGHT :
+            aud_active_skin->properties.mainwin_height;
+
+        dock_shade(get_dock_window_list(), GTK_WINDOW(mainwin), height * MAINWIN_SCALE_FACTOR);
+    }
+
+    mainwin_refresh_hints();
+    ui_skinned_set_push_button_data(mainwin_shade, 0, cfg.player_shaded ? 27 : 18, 9, cfg.player_shaded ? 27 : 18);
+    gtk_widget_shape_combine_mask(mainwin, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
+}
+
+static void
+mainwin_vis_set_refresh(RefreshRate rate)
+{
+    cfg.vis_refresh = rate;
+}
+
+static void
+mainwin_vis_set_afalloff(FalloffSpeed speed)
+{
+    cfg.analyzer_falloff = speed;
+}
+
+static void
+mainwin_vis_set_pfalloff(FalloffSpeed speed)
+{
+    cfg.peaks_falloff = speed;
+}
+
+static void
+mainwin_vis_set_analyzer_mode(AnalyzerMode mode)
+{
+    cfg.analyzer_mode = mode;
+}
+
+static void
+mainwin_vis_set_analyzer_type(AnalyzerType mode)
+{
+    cfg.analyzer_type = mode;
+}
+
+void
+mainwin_vis_set_type(VisType mode)
+{
+    GtkAction *action;
+
+    switch ( mode )
+    {
+        case VIS_ANALYZER:
+            action = gtk_action_group_get_action(radioaction_group_vismode,
+                                                 "vismode analyzer");
+            break;
+        case VIS_SCOPE:
+            action = gtk_action_group_get_action(radioaction_group_vismode,
+                                                 "vismode scope");
+            break;
+        case VIS_VOICEPRINT:
+            action = gtk_action_group_get_action(radioaction_group_vismode,
+                                                 "vismode voiceprint");
+            break;
+        case VIS_OFF:
+        default:
+            action = gtk_action_group_get_action(radioaction_group_vismode,
+                                                 "vismode off");
+            break;
+    }
+
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , TRUE );
+}
+
+static void
+mainwin_vis_set_type_menu_cb(VisType mode)
+{
+    cfg.vis_type = mode;
+
+    if (mode == VIS_OFF) {
+        if (cfg.player_shaded) {
+            ui_svis_set_visible(mainwin_svis, FALSE);
+            ui_vis_set_visible(mainwin_vis, TRUE);
+        } else {
+            ui_svis_set_visible(mainwin_svis, TRUE);
+            ui_vis_set_visible(mainwin_vis, FALSE);
+        }
+    }
+    if (mode == VIS_ANALYZER || mode == VIS_SCOPE || mode == VIS_VOICEPRINT) {
+        if (cfg.player_shaded) {
+            ui_svis_clear_data(mainwin_svis);
+            ui_svis_set_visible(mainwin_svis, TRUE);
+            ui_vis_clear_data(mainwin_vis);
+            ui_vis_set_visible(mainwin_vis, FALSE);
+        } else {
+            ui_svis_clear_data(mainwin_svis);
+            ui_svis_set_visible(mainwin_svis, FALSE);
+            ui_vis_clear_data(mainwin_vis);
+            ui_vis_set_visible(mainwin_vis, TRUE);
+        }
+    }
+}
+
+static void
+mainwin_menubtn_cb(void)
+{
+    gint x, y;
+    gtk_window_get_position(GTK_WINDOW(mainwin), &x, &y);
+    ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu),
+                               x + 6 * MAINWIN_SCALE_FACTOR ,
+                               y + MAINWIN_SHADED_HEIGHT * MAINWIN_SCALE_FACTOR,
+                               1, GDK_CURRENT_TIME);
+}
+
+void
+mainwin_minimize_cb(void)
+{
+    if (!mainwin)
+        return;
+
+    gtk_window_iconify(GTK_WINDOW(mainwin));
+}
+
+static void
+mainwin_shade_toggle(void)
+{
+    mainwin_set_shade(!cfg.player_shaded);
+}
+
+void
+mainwin_quit_cb(void)
+{
+    if (mainwin_timeout_id)
+        g_source_remove(mainwin_timeout_id);
+
+    aud_quit();
+}
+
+gboolean
+mainwin_vis_cb(GtkWidget *widget, GdkEventButton *event)
+{
+    if (event->button == 1) {
+        cfg.vis_type++;
+
+        if (cfg.vis_type > VIS_OFF)
+            cfg.vis_type = VIS_ANALYZER;
+
+        mainwin_vis_set_type(cfg.vis_type);
+    } else if (event->button == 3) {
+        ui_manager_popup_menu_show(GTK_MENU(mainwin_visualization_menu),
+                                   event->x_root, event->y_root, 3,
+                                   event->time);
+    }
+    return TRUE;
+}
+
+static void
+mainwin_destroy(GtkWidget * widget, gpointer data)
+{
+    mainwin_quit_cb();
+}
+
+static gchar *mainwin_tb_old_text = NULL;
+
+void
+mainwin_lock_info_text(const gchar * text)
+{
+    if (mainwin_info_text_locked != TRUE)
+        mainwin_tb_old_text = g_strdup(aud_active_skin->properties.mainwin_othertext_is_status ?
+                                       UI_SKINNED_TEXTBOX(mainwin_othertext)->text : UI_SKINNED_TEXTBOX(mainwin_info)->text);
+
+    mainwin_info_text_locked = TRUE;
+    if (aud_active_skin->properties.mainwin_othertext_is_status)
+        ui_skinned_textbox_set_text(mainwin_othertext, text);
+    else
+        ui_skinned_textbox_set_text(mainwin_info, text);
+}
+
+void
+mainwin_release_info_text(void)
+{
+    mainwin_info_text_locked = FALSE;
+
+    if (mainwin_tb_old_text != NULL)
+    {
+        if (aud_active_skin->properties.mainwin_othertext_is_status)
+            ui_skinned_textbox_set_text(mainwin_othertext, mainwin_tb_old_text);
+        else
+            ui_skinned_textbox_set_text(mainwin_info, mainwin_tb_old_text);
+        g_free(mainwin_tb_old_text);
+        mainwin_tb_old_text = NULL;
+    }
+}
+
+
+static gchar *
+make_mainwin_title(const gchar * title)
+{
+    if (title)
+        return g_strdup_printf(_("%s - Audacious"), title);
+    else
+        return g_strdup(_("Audacious"));
+}
+
+void
+mainwin_set_song_title(const gchar * title)
+{
+    gchar *mainwin_title_text = make_mainwin_title(title);
+    gtk_window_set_title(GTK_WINDOW(mainwin), mainwin_title_text);
+    g_free(mainwin_title_text);
+}
+
+static void
+mainwin_refresh_visible(void)
+{
+    if (!aud_active_skin || !cfg.player_visible)
+        return;
+
+    gtk_widget_show_all(mainwin);
+
+    if (!aud_active_skin->properties.mainwin_text_visible)
+        gtk_widget_hide(mainwin_info);
+
+    if (!aud_active_skin->properties.mainwin_vis_visible)
+        gtk_widget_hide(mainwin_vis);
+
+    if (!aud_active_skin->properties.mainwin_menurow_visible)
+        gtk_widget_hide(mainwin_menurow);
+
+    if (aud_active_skin->properties.mainwin_othertext) {
+        gtk_widget_hide(mainwin_rate_text);
+        gtk_widget_hide(mainwin_freq_text);
+        gtk_widget_hide(mainwin_monostereo);
+
+        if (!aud_active_skin->properties.mainwin_othertext_visible)
+            gtk_widget_hide(mainwin_othertext);
+    } else {
+        gtk_widget_hide(mainwin_othertext);
+    }
+
+    if (!aud_active_skin->properties.mainwin_vis_visible)
+        gtk_widget_hide(mainwin_vis);
+
+    if (!playback_get_playing()) {
+        gtk_widget_hide(mainwin_minus_num);
+        gtk_widget_hide(mainwin_10min_num);
+        gtk_widget_hide(mainwin_min_num);
+        gtk_widget_hide(mainwin_10sec_num);
+        gtk_widget_hide(mainwin_sec_num);
+
+        gtk_widget_hide(mainwin_stime_min);
+        gtk_widget_hide(mainwin_stime_sec);
+
+        gtk_widget_hide(mainwin_position);
+        gtk_widget_hide(mainwin_sposition);
+    }
+
+    if (cfg.player_shaded) {
+        ui_svis_clear_data(mainwin_svis);
+        if (cfg.vis_type != VIS_OFF)
+            ui_svis_set_visible(mainwin_svis, TRUE);
+        else
+            ui_svis_set_visible(mainwin_svis, FALSE);
+
+        ui_skinned_textbox_set_scroll(mainwin_info, FALSE);
+        if (!playback_get_playing()) {
+            gtk_widget_hide(mainwin_sposition);
+            gtk_widget_hide(mainwin_stime_min);
+            gtk_widget_hide(mainwin_stime_sec);
+        }
+    } else {
+        gtk_widget_hide(mainwin_srew);
+        gtk_widget_hide(mainwin_splay);
+        gtk_widget_hide(mainwin_spause);
+        gtk_widget_hide(mainwin_sstop);
+        gtk_widget_hide(mainwin_sfwd);
+        gtk_widget_hide(mainwin_seject);
+        gtk_widget_hide(mainwin_stime_min);
+        gtk_widget_hide(mainwin_stime_sec);
+        gtk_widget_hide(mainwin_svis);
+        gtk_widget_hide(mainwin_sposition);
+        ui_vis_clear_data(mainwin_vis);
+        if (cfg.vis_type != VIS_OFF)
+            ui_vis_set_visible(mainwin_vis, TRUE);
+        else
+            ui_vis_set_visible(mainwin_vis, FALSE);
+
+        ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll);
+    }
+}
+
+void
+mainwin_refresh_hints(void)
+{
+    /* positioning and size attributes */
+    if (aud_active_skin->properties.mainwin_vis_x && aud_active_skin->properties.mainwin_vis_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_vis), aud_active_skin->properties.mainwin_vis_x,
+                       aud_active_skin->properties.mainwin_vis_y);
+
+    if (aud_active_skin->properties.mainwin_vis_width)
+        gtk_widget_set_size_request(mainwin_vis, aud_active_skin->properties.mainwin_vis_width * MAINWIN_SCALE_FACTOR,
+                                    UI_VIS(mainwin_vis)->height* MAINWIN_SCALE_FACTOR);
+
+    if (aud_active_skin->properties.mainwin_text_x && aud_active_skin->properties.mainwin_text_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_info), aud_active_skin->properties.mainwin_text_x,
+                       aud_active_skin->properties.mainwin_text_y);
+
+    if (aud_active_skin->properties.mainwin_text_width) {
+        UI_SKINNED_TEXTBOX(mainwin_info)->width = aud_active_skin->properties.mainwin_text_width;
+        gtk_widget_set_size_request(mainwin_info, aud_active_skin->properties.mainwin_text_width * MAINWIN_SCALE_FACTOR,
+                                    UI_SKINNED_TEXTBOX(mainwin_info)->height * MAINWIN_SCALE_FACTOR );
+    }
+
+    if (aud_active_skin->properties.mainwin_infobar_x && aud_active_skin->properties.mainwin_infobar_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_othertext), aud_active_skin->properties.mainwin_infobar_x,
+                       aud_active_skin->properties.mainwin_infobar_y);
+
+    if (aud_active_skin->properties.mainwin_number_0_x && aud_active_skin->properties.mainwin_number_0_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_minus_num), aud_active_skin->properties.mainwin_number_0_x,
+                       aud_active_skin->properties.mainwin_number_0_y);
+
+    if (aud_active_skin->properties.mainwin_number_1_x && aud_active_skin->properties.mainwin_number_1_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_10min_num), aud_active_skin->properties.mainwin_number_1_x,
+                       aud_active_skin->properties.mainwin_number_1_y);
+
+    if (aud_active_skin->properties.mainwin_number_2_x && aud_active_skin->properties.mainwin_number_2_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_min_num), aud_active_skin->properties.mainwin_number_2_x,
+                       aud_active_skin->properties.mainwin_number_2_y);
+
+    if (aud_active_skin->properties.mainwin_number_3_x && aud_active_skin->properties.mainwin_number_3_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_10sec_num), aud_active_skin->properties.mainwin_number_3_x,
+                       aud_active_skin->properties.mainwin_number_3_y);
+
+    if (aud_active_skin->properties.mainwin_number_4_x && aud_active_skin->properties.mainwin_number_4_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_sec_num), aud_active_skin->properties.mainwin_number_4_x,
+                       aud_active_skin->properties.mainwin_number_4_y);
+
+    if (aud_active_skin->properties.mainwin_playstatus_x && aud_active_skin->properties.mainwin_playstatus_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_playstatus, aud_active_skin->properties.mainwin_playstatus_x,
+                       aud_active_skin->properties.mainwin_playstatus_y);
+
+    if (aud_active_skin->properties.mainwin_volume_x && aud_active_skin->properties.mainwin_volume_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_volume), aud_active_skin->properties.mainwin_volume_x,
+                       aud_active_skin->properties.mainwin_volume_y);
+
+    if (aud_active_skin->properties.mainwin_balance_x && aud_active_skin->properties.mainwin_balance_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_balance), aud_active_skin->properties.mainwin_balance_x,
+                       aud_active_skin->properties.mainwin_balance_y);
+
+    if (aud_active_skin->properties.mainwin_position_x && aud_active_skin->properties.mainwin_position_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_position), aud_active_skin->properties.mainwin_position_x,
+                       aud_active_skin->properties.mainwin_position_y);
+
+    if (aud_active_skin->properties.mainwin_previous_x && aud_active_skin->properties.mainwin_previous_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_rew, aud_active_skin->properties.mainwin_previous_x,
+                       aud_active_skin->properties.mainwin_previous_y);
+
+    if (aud_active_skin->properties.mainwin_play_x && aud_active_skin->properties.mainwin_play_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_play), aud_active_skin->properties.mainwin_play_x,
+                       aud_active_skin->properties.mainwin_play_y);
+
+    if (aud_active_skin->properties.mainwin_pause_x && aud_active_skin->properties.mainwin_pause_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_pause), aud_active_skin->properties.mainwin_pause_x,
+                       aud_active_skin->properties.mainwin_pause_y);
+
+    if (aud_active_skin->properties.mainwin_stop_x && aud_active_skin->properties.mainwin_stop_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_stop), aud_active_skin->properties.mainwin_stop_x,
+                       aud_active_skin->properties.mainwin_stop_y);
+
+    if (aud_active_skin->properties.mainwin_next_x && aud_active_skin->properties.mainwin_next_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_fwd), aud_active_skin->properties.mainwin_next_x,
+                       aud_active_skin->properties.mainwin_next_y);
+
+    if (aud_active_skin->properties.mainwin_eject_x && aud_active_skin->properties.mainwin_eject_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_eject), aud_active_skin->properties.mainwin_eject_x,
+                       aud_active_skin->properties.mainwin_eject_y);
+
+    if (aud_active_skin->properties.mainwin_eqbutton_x && aud_active_skin->properties.mainwin_eqbutton_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_eq), aud_active_skin->properties.mainwin_eqbutton_x,
+                       aud_active_skin->properties.mainwin_eqbutton_y);
+
+    if (aud_active_skin->properties.mainwin_plbutton_x && aud_active_skin->properties.mainwin_plbutton_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_pl), aud_active_skin->properties.mainwin_plbutton_x,
+                       aud_active_skin->properties.mainwin_plbutton_y);
+
+    if (aud_active_skin->properties.mainwin_shuffle_x && aud_active_skin->properties.mainwin_shuffle_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_shuffle), aud_active_skin->properties.mainwin_shuffle_x,
+                       aud_active_skin->properties.mainwin_shuffle_y);
+
+    if (aud_active_skin->properties.mainwin_repeat_x && aud_active_skin->properties.mainwin_repeat_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_repeat), aud_active_skin->properties.mainwin_repeat_x,
+                       aud_active_skin->properties.mainwin_repeat_y);
+
+    if (aud_active_skin->properties.mainwin_about_x && aud_active_skin->properties.mainwin_about_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_about), aud_active_skin->properties.mainwin_about_x,
+                       aud_active_skin->properties.mainwin_about_y);
+
+    if (aud_active_skin->properties.mainwin_minimize_x && aud_active_skin->properties.mainwin_minimize_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_minimize), cfg.player_shaded ? 244 : aud_active_skin->properties.mainwin_minimize_x,
+                       cfg.player_shaded ? 3 : aud_active_skin->properties.mainwin_minimize_y);
+
+    if (aud_active_skin->properties.mainwin_shade_x && aud_active_skin->properties.mainwin_shade_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_shade), cfg.player_shaded ? 254 : aud_active_skin->properties.mainwin_shade_x,
+                       cfg.player_shaded ? 3 : aud_active_skin->properties.mainwin_shade_y);
+
+    if (aud_active_skin->properties.mainwin_close_x && aud_active_skin->properties.mainwin_close_y)
+        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_close), cfg.player_shaded ? 264 : aud_active_skin->properties.mainwin_close_x,
+                       cfg.player_shaded ? 3 : aud_active_skin->properties.mainwin_close_y);
+
+    mainwin_refresh_visible();
+
+    /* window size, mainwinWidth && mainwinHeight properties */
+    if (aud_active_skin->properties.mainwin_height && aud_active_skin->properties.mainwin_width)
+    {
+        dock_window_resize(GTK_WINDOW(mainwin), cfg.player_shaded ? MAINWIN_SHADED_WIDTH * MAINWIN_SCALE_FACTOR : aud_active_skin->properties.mainwin_width * MAINWIN_SCALE_FACTOR,
+                           cfg.player_shaded ? MAINWIN_SHADED_HEIGHT * MAINWIN_SCALE_FACTOR : aud_active_skin->properties.mainwin_height * MAINWIN_SCALE_FACTOR,
+                           aud_active_skin->properties.mainwin_width * MAINWIN_SCALE_FACTOR,
+                           aud_active_skin->properties.mainwin_height * MAINWIN_SCALE_FACTOR);
+
+        gdk_flush();
+    }
+}
+
+void
+mainwin_set_song_info(gint bitrate,
+                      gint frequency,
+                      gint n_channels)
+{
+    gchar *text;
+    gchar *title;
+    Playlist *playlist = playlist_get_active();
+
+    GDK_THREADS_ENTER();
+    if (bitrate != -1) {
+        bitrate /= 1000;
+
+        if (bitrate < 1000) {
+            /* Show bitrate in 1000s */
+            text = g_strdup_printf("%3d", bitrate);
+        }
+        else {
+            /* Show bitrate in 100,000s */
+            text = g_strdup_printf("%2dH", bitrate / 100);
+        }
+        ui_skinned_textbox_set_text(mainwin_rate_text, text);
+        g_free(text);
+    }
+    else
+        ui_skinned_textbox_set_text(mainwin_rate_text, _("VBR"));
+
+    /* Show sampling frequency in kHz */
+    text = g_strdup_printf("%2d", frequency / 1000);
+    ui_skinned_textbox_set_text(mainwin_freq_text, text);
+    g_free(text);
+
+    ui_skinned_monostereo_set_num_channels(mainwin_monostereo, n_channels);
+
+    if (!playback_get_paused() && mainwin_playstatus != NULL)
+        ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
+
+    if (aud_active_skin && aud_active_skin->properties.mainwin_othertext)
+    {
+        if (bitrate != -1)
+            text = g_strdup_printf("%d kbps, %0.1f kHz, %s",
+                                   bitrate,
+                                   (gfloat) frequency / 1000,
+                                   (n_channels > 1) ? _("stereo") : _("mono"));
+        else
+            text = g_strdup_printf("VBR, %0.1f kHz, %s",
+                                   (gfloat) frequency / 1000,
+                                   (n_channels > 1) ? _("stereo") : _("mono"));
+
+        ui_skinned_textbox_set_text(mainwin_othertext, text);
+        g_free(text);
+    }
+
+    title = playlist_get_info_text(playlist);
+    mainwin_set_song_title(title);
+    g_free(title);
+    GDK_THREADS_LEAVE();
+}
+
+void
+mainwin_clear_song_info(void)
+{
+    if (!mainwin)
+        return;
+
+    /* clear title */
+    mainwin_set_song_title(NULL);
+
+    /* clear sampling parameters */
+    playback_set_sample_params(0, 0, 0);
+
+    UI_SKINNED_HORIZONTAL_SLIDER(mainwin_position)->pressed = FALSE;
+    UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->pressed = FALSE;
+
+    /* clear sampling parameter displays */
+    ui_skinned_textbox_set_text(mainwin_rate_text, "   ");
+    ui_skinned_textbox_set_text(mainwin_freq_text, "  ");
+    ui_skinned_monostereo_set_num_channels(mainwin_monostereo, 0);
+
+    if (mainwin_playstatus != NULL)
+        ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_STOP);
+
+    mainwin_refresh_visible();
+
+    playlistwin_hide_timer();
+    ui_vis_clear_data(mainwin_vis);
+    ui_svis_clear_data(mainwin_svis);
+}
+
+void
+mainwin_disable_seekbar(void)
+{
+    if (!mainwin)
+        return;
+
+    gtk_widget_hide(mainwin_position);
+    gtk_widget_hide(mainwin_sposition);
+}
+
+static gboolean
+mainwin_mouse_button_release(GtkWidget * widget,
+                             GdkEventButton * event,
+                             gpointer callback_data)
+{
+    if (dock_is_moving(GTK_WINDOW(mainwin))) {
+        dock_move_release(GTK_WINDOW(mainwin));
+    }
+
+    return FALSE;
+}
+
+void
+mainwin_scrolled(GtkWidget *widget, GdkEventScroll *event,
+                 gpointer callback_data)
+{
+    Playlist *playlist = playlist_get_active();
+
+    switch (event->direction) {
+        case GDK_SCROLL_UP:
+            mainwin_set_volume_diff(cfg.mouse_change);
+            break;
+        case GDK_SCROLL_DOWN:
+            mainwin_set_volume_diff(-cfg.mouse_change);
+            break;
+        case GDK_SCROLL_LEFT:
+            if (playlist_get_current_length(playlist) != -1)
+                playback_seek(CLAMP(playback_get_time() - 1000,
+                                    0, playlist_get_current_length(playlist)) / 1000);
+            break;
+        case GDK_SCROLL_RIGHT:
+            if (playlist_get_current_length(playlist) != -1)
+                playback_seek(CLAMP(playback_get_time() + 1000,
+                                    0, playlist_get_current_length(playlist)) / 1000);
+            break;
+    }
+}
+
+static gboolean
+mainwin_widget_contained(GdkEventButton *event, int x, int y, int w, int h)
+{
+    if ((event->x > x && event->y > y) &&
+        (event->x < x+w && event->y < y+h))
+        return TRUE;
+
+    return FALSE;
+}
+
+static gboolean
+mainwin_mouse_button_press(GtkWidget * widget,
+                           GdkEventButton * event,
+                           gpointer callback_data)
+{
+    if (cfg.scaled) {
+        /*
+         * A hack to make scaling transparent to callbacks.
+         * We should make a copy of this data instead of
+         * tampering with the data we get from gtk+
+         */
+        event->x /= cfg.scale_factor;
+        event->y /= cfg.scale_factor;
+    }
+
+    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS && event->y < 14) {
+        mainwin_set_shade(!cfg.player_shaded);
+        if (dock_is_moving(GTK_WINDOW(mainwin)))
+            dock_move_release(GTK_WINDOW(mainwin));
+        return TRUE;
+    }
+
+    if (event->button == 3) {
+        /* Pop up playback menu if right clicked over playback-control widgets,
+         * otherwise popup general menu
+         */
+        if (mainwin_widget_contained(event, aud_active_skin->properties.mainwin_position_x,
+                                     aud_active_skin->properties.mainwin_position_y, 248, 10) ||
+            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_previous_x,
+                                     aud_active_skin->properties.mainwin_previous_y, 23, 18) ||
+            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_play_x,
+                                     aud_active_skin->properties.mainwin_play_y, 23, 18) ||
+            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_pause_x,
+                                     aud_active_skin->properties.mainwin_pause_y, 23, 18) ||
+            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_stop_x,
+                                     aud_active_skin->properties.mainwin_stop_y, 23, 18) ||
+            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_next_x,
+                                     aud_active_skin->properties.mainwin_next_y, 23, 18))
+        {
+
+            ui_manager_popup_menu_show(GTK_MENU(mainwin_playback_menu),
+                                       event->x_root,
+                                       event->y_root, 3, event->time);
+        } else {
+            /*
+             * Pop up the main menu a few pixels down.
+             * This will avoid that anything is selected
+             * if one right-clicks to focus the window
+             * without raising it.
+             *
+             ***MD I think the above is stupid, people don't expect this
+             *
+             */
+            ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu),
+                                       event->x_root,
+                                       event->y_root, 3, event->time);
+        }
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static gboolean
+mainwin_keypress(GtkWidget * grab_widget,
+                 GdkEventKey * event,
+                 gpointer data)
+{
+    Playlist *playlist = playlist_get_active();
+
+    switch (event->keyval) {
+
+        case GDK_Up:
+        case GDK_KP_Up:
+        case GDK_KP_8:
+            mainwin_set_volume_diff(2);
+            break;
+        case GDK_Down:
+        case GDK_KP_Down:
+        case GDK_KP_2:
+            mainwin_set_volume_diff(-2);
+            break;
+        case GDK_Left:
+        case GDK_KP_Left:
+        case GDK_KP_7:
+            if (playlist_get_current_length(playlist) != -1)
+                playback_seek(CLAMP
+                              (playback_get_time() - 5000, 0,
+                               playlist_get_current_length(playlist)) / 1000);
+            break;
+        case GDK_Right:
+        case GDK_KP_Right:
+        case GDK_KP_9:
+            if (playlist_get_current_length(playlist) != -1)
+                playback_seek(CLAMP
+                              (playback_get_time() + 5000, 0,
+                               playlist_get_current_length(playlist)) / 1000);
+            break;
+        case GDK_KP_4:
+            playlist_prev(playlist);
+            break;
+        case GDK_KP_6:
+            playlist_next(playlist);
+            break;
+        case GDK_KP_Insert:
+            ui_jump_to_track();
+            break;
+        case GDK_Return:
+        case GDK_KP_Enter:
+        case GDK_KP_5:
+            mainwin_play_pushed();
+            break;
+        case GDK_space:
+            playback_pause();
+            break;
+        case GDK_Escape:
+            mainwin_minimize_cb();
+            break;
+        case GDK_Tab:
+            if (event->state & GDK_CONTROL_MASK) {
+                if (cfg.equalizer_visible)
+                    gtk_window_present(GTK_WINDOW(equalizerwin));
+                else if (cfg.playlist_visible)
+                    gtk_window_present(GTK_WINDOW(playlistwin));
+            }
+            break;
+        case GDK_c:
+            if (event->state & GDK_CONTROL_MASK) {
+                Playlist *playlist = playlist_get_active();
+                gint pos = playlist_get_position(playlist);
+                gchar *title = playlist_get_songtitle(playlist, pos);
+
+                if (title != NULL) {
+                    GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+                    gtk_clipboard_set_text(clip, title, -1);
+                    gtk_clipboard_store(clip);
+                }
+
+                return TRUE;
+            }
+            return FALSE;
+        default:
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void
+mainwin_jump_to_time_cb(GtkWidget * widget,
+                        GtkWidget * entry)
+{
+    guint min = 0, sec = 0, params;
+    gint time;
+    Playlist *playlist = playlist_get_active();
+
+    params = sscanf(gtk_entry_get_text(GTK_ENTRY(entry)), "%u:%u",
+                    &min, &sec);
+    if (params == 2)
+        time = (min * 60) + sec;
+    else if (params == 1)
+        time = min;
+    else
+        return;
+
+    if (playlist_get_current_length(playlist) > -1 &&
+        time <= (playlist_get_current_length(playlist) / 1000))
+    {
+        playback_seek(time);
+        gtk_widget_destroy(mainwin_jtt);
+    }
+}
+
+
+void
+mainwin_jump_to_time(void)
+{
+    GtkWidget *vbox, *hbox_new, *hbox_total;
+    GtkWidget *time_entry, *label, *bbox, *jump, *cancel;
+    GtkWidget *dialog;
+    guint tindex;
+    gchar time_str[10];
+
+    if (!playback_get_playing()) {
+        dialog =
+            gtk_message_dialog_new (GTK_WINDOW (mainwin),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_ERROR,
+                                    GTK_BUTTONS_CLOSE,
+                                    _("Can't jump to time when no track is being played.\n"));
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+        return;
+    }
+
+    if (mainwin_jtt) {
+        gtk_window_present(GTK_WINDOW(mainwin_jtt));
+        return;
+    }
+
+    mainwin_jtt = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_type_hint(GTK_WINDOW(mainwin_jtt),
+                             GDK_WINDOW_TYPE_HINT_DIALOG);
+
+    gtk_window_set_title(GTK_WINDOW(mainwin_jtt), _("Jump to Time"));
+    gtk_window_set_position(GTK_WINDOW(mainwin_jtt), GTK_WIN_POS_CENTER);
+    gtk_window_set_transient_for(GTK_WINDOW(mainwin_jtt),
+                                 GTK_WINDOW(mainwin));
+
+    g_signal_connect(mainwin_jtt, "destroy",
+                     G_CALLBACK(gtk_widget_destroyed), &mainwin_jtt);
+    gtk_container_border_width(GTK_CONTAINER(mainwin_jtt), 10);
+
+    vbox = gtk_vbox_new(FALSE, 5);
+    gtk_container_add(GTK_CONTAINER(mainwin_jtt), vbox);
+
+    hbox_new = gtk_hbox_new(FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(vbox), hbox_new, TRUE, TRUE, 5);
+
+    time_entry = gtk_entry_new();
+    gtk_box_pack_start(GTK_BOX(hbox_new), time_entry, FALSE, FALSE, 5);
+    g_signal_connect(time_entry, "activate",
+                     G_CALLBACK(mainwin_jump_to_time_cb), time_entry);
+
+    gtk_widget_set_size_request(time_entry, 70, -1);
+    label = gtk_label_new(_("minutes:seconds"));
+    gtk_box_pack_start(GTK_BOX(hbox_new), label, FALSE, FALSE, 5);
+
+    hbox_total = gtk_hbox_new(FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(vbox), hbox_total, TRUE, TRUE, 5);
+    gtk_widget_show(hbox_total);
+
+    /* FIXME: Disable display of current track length. It's not
+       updated when track changes */
+#if 0
+    label = gtk_label_new(_("Track length:"));
+    gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 5);
+
+    len = playlist_get_current_length() / 1000;
+    g_snprintf(time_str, sizeof(time_str), "%u:%2.2u", len / 60, len % 60);
+    label = gtk_label_new(time_str);
+
+    gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 10);
+#endif
+
+    bbox = gtk_hbutton_box_new();
+    gtk_box_pack_start(GTK_BOX(vbox), bbox, TRUE, TRUE, 0);
+    gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+    gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+
+    cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+    GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
+    gtk_container_add(GTK_CONTAINER(bbox), cancel);
+    g_signal_connect_swapped(cancel, "clicked",
+                             G_CALLBACK(gtk_widget_destroy), mainwin_jtt);
+
+    jump = gtk_button_new_from_stock(GTK_STOCK_JUMP_TO);
+    GTK_WIDGET_SET_FLAGS(jump, GTK_CAN_DEFAULT);
+    gtk_container_add(GTK_CONTAINER(bbox), jump);
+    g_signal_connect(jump, "clicked",
+                     G_CALLBACK(mainwin_jump_to_time_cb), time_entry);
+
+    tindex = playback_get_time() / 1000;
+    g_snprintf(time_str, sizeof(time_str), "%u:%2.2u", tindex / 60,
+               tindex % 60);
+    gtk_entry_set_text(GTK_ENTRY(time_entry), time_str);
+
+    gtk_entry_select_region(GTK_ENTRY(time_entry), 0, strlen(time_str));
+
+    gtk_widget_show_all(mainwin_jtt);
+
+    gtk_widget_grab_focus(time_entry);
+    gtk_widget_grab_default(jump);
+}
+
+/*
+ * Rewritten 09/13/06:
+ *
+ * Remove all of this flaky iter/sourcelist/strsplit stuff.
+ * All we care about is the filepath.
+ *
+ * We can figure this out and easily pass it to g_filename_from_uri().
+ *   - nenolod
+ */
+void
+mainwin_drag_data_received(GtkWidget * widget,
+                           GdkDragContext * context,
+                           gint x,
+                           gint y,
+                           GtkSelectionData * selection_data,
+                           guint info,
+                           guint time,
+                           gpointer user_data)
+{
+    Playlist *playlist = playlist_get_active();
+
+    g_return_if_fail(selection_data != NULL);
+    g_return_if_fail(selection_data->data != NULL);
+
+    if (str_has_prefix_nocase((gchar *) selection_data->data, "fonts:///"))
+    {
+        gchar *path = (gchar *) selection_data->data;
+        gchar *decoded = g_filename_from_uri(path, NULL, NULL);
+
+        if (decoded == NULL)
+            return;
+
+        cfg.playlist_font = g_strconcat(decoded, strrchr(cfg.playlist_font, ' '), NULL);
+        ui_skinned_playlist_set_font(cfg.playlist_font);
+        playlistwin_update_list(playlist);
+
+        g_free(decoded);
+
+        return;
+    }
+#if 0
+    /* perhaps make suffix check case-insensitive -- desowin */
+    if (str_has_prefix_nocase((char*)selection_data->data, "file:///")) {
+        if (str_has_suffix_nocase((char*)selection_data->data, ".wsz\r\n") ||
+            str_has_suffix_nocase((char*)selection_data->data, ".zip\r\n")) {
+            on_skin_view_drag_data_received(GTK_WIDGET(user_data), context, x, y, selection_data, info, time, NULL);
+            return;
+        }
+    }
+#endif
+    playlist_clear(playlist);
+    playlist_add_url(playlist, (gchar *) selection_data->data);
+    playback_initiate();
+}
+
+static void
+on_visibility_warning_toggle(GtkToggleButton *tbt, gpointer unused)
+{
+    cfg.warn_about_win_visibility = !gtk_toggle_button_get_active(tbt);
+}
+
+static void
+on_visibility_warning_response(GtkDialog *dlg, gint r_id, gpointer unused)
+{
+    switch (r_id)
+    {
+        case GTK_RESPONSE_OK:
+            mainwin_show(TRUE);
+            break;
+        case GTK_RESPONSE_CANCEL:
+        default:
+            break;
+    }
+    gtk_widget_destroy(GTK_WIDGET(dlg));
+}
+
+void
+mainwin_show_visibility_warning(void)
+{
+    if (cfg.warn_about_win_visibility)
+    {
+        GtkWidget *label, *checkbt, *vbox;
+        GtkWidget *warning_dlg =
+            gtk_dialog_new_with_buttons( _("Audacious - visibility warning") ,
+                                         GTK_WINDOW(mainwin) ,
+                                         GTK_DIALOG_DESTROY_WITH_PARENT ,
+                                         _("Show main player window") ,
+                                         GTK_RESPONSE_OK , _("Ignore") ,
+                                         GTK_RESPONSE_CANCEL , NULL );
+
+        vbox = gtk_vbox_new( FALSE , 4 );
+        gtk_container_set_border_width( GTK_CONTAINER(vbox) , 4 );
+        gtk_box_pack_start( GTK_BOX(GTK_DIALOG(warning_dlg)->vbox) , vbox , TRUE , TRUE , 0 );
+        label = gtk_label_new( _("Audacious has been started with all of its windows hidden.\n"
+                                 "You may want to show the player window again to control Audacious; "
+                                 "otherwise, you'll have to control it remotely via audtool or "
+                                 "enabled plugins (such as the statusicon plugin).") );
+        gtk_label_set_line_wrap( GTK_LABEL(label) , TRUE );
+        gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
+        checkbt = gtk_check_button_new_with_label( _("Always ignore, show/hide is controlled remotely") );
+        gtk_box_pack_start( GTK_BOX(vbox) , label , TRUE , TRUE , 0 );
+        gtk_box_pack_start( GTK_BOX(vbox) , checkbt , TRUE , TRUE , 0 );
+        g_signal_connect( G_OBJECT(checkbt) , "toggled" ,
+                          G_CALLBACK(on_visibility_warning_toggle) , NULL );
+        g_signal_connect( G_OBJECT(warning_dlg) , "response" ,
+                          G_CALLBACK(on_visibility_warning_response) , NULL );
+        gtk_widget_show_all(warning_dlg);
+    }
+}
+
+static void
+on_broken_gtk_engine_warning_toggle(GtkToggleButton *tbt, gpointer unused)
+{
+    cfg.warn_about_broken_gtk_engines = !gtk_toggle_button_get_active(tbt);
+}
+
+void
+ui_main_check_theme_engine(void)
+{
+    GtkSettings *settings;
+    GtkWidget *widget;
+    gchar *theme = NULL;
+
+    widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_widget_ensure_style(widget);
+
+    settings = gtk_settings_get_default();
+    g_object_get(G_OBJECT(settings), "gtk-theme-name", &theme, NULL);
+    gtk_widget_destroy(widget);
+
+    if (theme == NULL)
+        return;
+
+    if (g_ascii_strcasecmp(theme, "Qt"))
+    {
+        g_free(theme);
+        return;
+    }
+
+    if (cfg.warn_about_broken_gtk_engines)
+    {
+        gchar *msg;
+        GtkWidget *label, *checkbt, *vbox;
+        GtkWidget *warning_dlg =
+            gtk_dialog_new_with_buttons( _("Audacious - broken GTK engine usage warning") ,
+                                         GTK_WINDOW(mainwin) , GTK_DIALOG_DESTROY_WITH_PARENT ,
+                                         GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL );
+        vbox = gtk_vbox_new( FALSE , 4 );
+        gtk_container_set_border_width( GTK_CONTAINER(vbox) , 4 );
+        gtk_box_pack_start( GTK_BOX(GTK_DIALOG(warning_dlg)->vbox) , vbox ,
+                            TRUE , TRUE , 0 );
+
+        msg = g_strdup_printf(_("<big><b>Broken GTK engine in use</b></big>\n\n"
+                                "Audacious has detected that you are using a broken GTK engine.\n\n"
+                                "The theme engine you are using, <i>%s</i>, is incompatible with some of the features "
+                                "used by modern skins. The incompatible features have been disabled for this session.\n\n"
+                                "To use these features, please consider using a different GTK theme engine."), theme);
+        label = gtk_label_new(msg);
+        gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
+        g_free(msg);
+
+        gtk_label_set_line_wrap( GTK_LABEL(label) , TRUE );
+        gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
+        checkbt = gtk_check_button_new_with_label( _("Do not display this warning again") );
+        gtk_box_pack_start( GTK_BOX(vbox) , label , TRUE , TRUE , 0 );
+        gtk_box_pack_start( GTK_BOX(vbox) , checkbt , TRUE , TRUE , 0 );
+        g_signal_connect( G_OBJECT(checkbt) , "toggled" ,
+                          G_CALLBACK(on_broken_gtk_engine_warning_toggle) , NULL );
+        g_signal_connect( G_OBJECT(warning_dlg) , "response" ,
+                          G_CALLBACK(gtk_widget_destroy) , NULL );        
+        gtk_widget_show_all(warning_dlg);
+        gtk_window_stick(GTK_WINDOW(warning_dlg));
+    }
+
+    cfg.disable_inline_gtk = TRUE;
+
+    g_free(theme);
+}
+
+static void
+check_set( GtkActionGroup * action_group ,
+           const gchar * action_name ,
+           gboolean is_on )
+{
+    /* check_set noew uses gtkaction */
+    GtkAction *action = gtk_action_group_get_action( action_group , action_name );
+    if ( action != NULL )
+        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , is_on );
+    return;
+}
+
+void
+mainwin_eject_pushed(void)
+{
+    run_filebrowser(TRUE);
+}
+
+void
+mainwin_rev_pushed(void)
+{
+    g_get_current_time(&cb_time);
+
+    seek_initial_pos = ui_skinned_horizontal_slider_get_position(mainwin_position);
+    seek_state = MAINWIN_SEEK_REV;
+    mainwin_timeout_id = g_timeout_add(MAINWIN_UPDATE_INTERVAL,
+                                       (GSourceFunc) mainwin_idle_func, NULL);
+}
+
+void
+mainwin_rev_release(void)
+{
+    GTimeVal now_time;
+    GTimeVal delta_time;
+    gulong now_dur;
+
+    g_get_current_time(&now_time);
+
+    delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec;
+    delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec;
+
+    now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000));
+
+    if ( now_dur <= TRISTATE_THRESHOLD )
+    {
+        /* interpret as 'skip to previous song' */
+        playlist_prev(playlist_get_active());
+    }
+    else
+    {
+        /* interpret as 'seek' */
+        mainwin_position_release_cb( mainwin_position, ui_skinned_horizontal_slider_get_position(mainwin_position) );
+    }
+
+    seek_state = MAINWIN_SEEK_NIL;
+
+    g_source_remove(mainwin_timeout_id);
+    mainwin_timeout_id = 0;
+}
+
+void
+mainwin_fwd_pushed(void)
+{
+    g_get_current_time(&cb_time);
+
+    seek_initial_pos = ui_skinned_horizontal_slider_get_position(mainwin_position);
+    seek_state = MAINWIN_SEEK_FWD;
+    mainwin_timeout_id = g_timeout_add(MAINWIN_UPDATE_INTERVAL,
+                                       (GSourceFunc) mainwin_idle_func, NULL);
+}
+
+void
+mainwin_fwd_release(void)
+{
+    GTimeVal now_time;
+    GTimeVal delta_time;
+    gulong now_dur;
+
+    g_get_current_time(&now_time);
+
+    delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec;
+    delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec;
+
+    now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000));
+
+    if ( now_dur <= TRISTATE_THRESHOLD )
+    {
+        /* interpret as 'skip to next song' */
+        playlist_next(playlist_get_active());
+    }
+    else
+    {
+        /* interpret as 'seek' */
+        mainwin_position_release_cb( mainwin_position, ui_skinned_horizontal_slider_get_position(mainwin_position) );
+    }
+
+    seek_state = MAINWIN_SEEK_NIL;
+
+    g_source_remove(mainwin_timeout_id);
+    mainwin_timeout_id = 0;
+}
+
+void
+mainwin_play_pushed(void)
+{
+    if (ab_position_a != -1)
+        playback_seek(ab_position_a / 1000);
+    if (playback_get_paused()) {
+        playback_pause();
+        return;
+    }
+
+    if (playlist_get_length(playlist_get_active()))
+        playback_initiate();
+    else
+        mainwin_eject_pushed();
+}
+
+void
+mainwin_stop_pushed(void)
+{
+    ip_data.stop = TRUE;
+    playback_stop();
+    mainwin_clear_song_info();
+    ab_position_a = ab_position_b = -1;
+    ip_data.stop = FALSE;
+}
+
+void
+mainwin_shuffle_pushed(gboolean toggled)
+{
+    check_set( toggleaction_group_others , "playback shuffle" , toggled );
+}
+
+void mainwin_shuffle_pushed_cb(void) {
+    mainwin_shuffle_pushed(UI_SKINNED_BUTTON(mainwin_shuffle)->inside);
+}
+
+void
+mainwin_repeat_pushed(gboolean toggled)
+{
+    check_set( toggleaction_group_others , "playback repeat" , toggled );
+}
+
+void mainwin_repeat_pushed_cb(void) {
+    mainwin_repeat_pushed(UI_SKINNED_BUTTON(mainwin_repeat)->inside);
+}
+
+void mainwin_equalizer_pushed_cb(void) {
+    mainwin_eq_pushed(UI_SKINNED_BUTTON(mainwin_eq)->inside);
+}
+
+void mainwin_playlist_pushed_cb(void) {
+    mainwin_pl_pushed(UI_SKINNED_BUTTON(mainwin_pl)->inside);
+}
+
+void
+mainwin_eq_pushed(gboolean toggled)
+{
+    equalizerwin_show(toggled);
+}
+
+void
+mainwin_pl_pushed(gboolean toggled)
+{
+    if (toggled)
+        playlistwin_show();
+    else
+        playlistwin_hide();
+}
+
+gint
+mainwin_spos_frame_cb(gint pos)
+{
+    if (mainwin_sposition) {
+        gint x = 0;
+        if (pos < 6)
+            x = 17;
+        else if (pos < 9)
+            x = 20;
+        else
+            x = 23;
+
+        UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->knob_nx = x;
+        UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->knob_px = x;
+    }
+    return 1;
+}
+
+void
+mainwin_spos_motion_cb(GtkWidget *widget, gint pos)
+{
+    gint time;
+    gchar *time_msg;
+    Playlist *playlist = playlist_get_active();
+
+    pos--;
+
+    time = ((playlist_get_current_length(playlist) / 1000) * pos) / 12;
+
+    if (cfg.timer_mode == TIMER_REMAINING) {
+        time = (playlist_get_current_length(playlist) / 1000) - time;
+        time_msg = g_strdup_printf("-%2.2d", time / 60);
+        ui_skinned_textbox_set_text(mainwin_stime_min, time_msg);
+        g_free(time_msg);
+    }
+    else {
+        time_msg = g_strdup_printf(" %2.2d", time / 60);
+        ui_skinned_textbox_set_text(mainwin_stime_min, time_msg);
+        g_free(time_msg);
+    }
+
+    time_msg = g_strdup_printf("%2.2d", time % 60);
+    ui_skinned_textbox_set_text(mainwin_stime_sec, time_msg);
+    g_free(time_msg);
+}
+
+void
+mainwin_spos_release_cb(GtkWidget *widget, gint pos)
+{
+    playback_seek(((playlist_get_current_length(playlist_get_active()) / 1000) *
+                   (pos - 1)) / 12);
+}
+
+void
+mainwin_position_motion_cb(GtkWidget *widget, gint pos)
+{
+    gint length, time;
+    gchar *seek_msg;
+
+    length = playlist_get_current_length(playlist_get_active()) / 1000;
+    time = (length * pos) / 219;
+    seek_msg = g_strdup_printf(_("Seek to: %d:%-2.2d/%d:%-2.2d (%d%%)"),
+                               time / 60, time % 60,
+                               length / 60, length % 60,
+                               (length != 0) ? (time * 100) / length : 0);
+    mainwin_lock_info_text(seek_msg);
+    g_free(seek_msg);
+}
+
+void
+mainwin_position_release_cb(GtkWidget *widget, gint pos)
+{
+    gint length, time;
+
+    length = playlist_get_current_length(playlist_get_active()) / 1000;
+    time = (length * pos) / 219;
+    playback_seek(time);
+    mainwin_release_info_text();
+}
+
+gint
+mainwin_volume_frame_cb(gint pos)
+{
+    return (gint) rint((pos / 52.0) * 28);
+}
+
+void
+mainwin_adjust_volume_motion(gint v)
+{
+    gchar *volume_msg;
+
+    volume_msg = g_strdup_printf(_("Volume: %d%%"), v);
+    mainwin_lock_info_text(volume_msg);
+    g_free(volume_msg);
+
+    if (balance < 0)
+        input_set_volume(v, (v * (100 - abs(balance))) / 100);
+    else if (balance > 0)
+        input_set_volume((v * (100 - abs(balance))) / 100, v);
+    else
+        input_set_volume(v, v);
+}
+
+void
+mainwin_adjust_volume_release(void)
+{
+    mainwin_release_info_text();
+}
+
+void
+mainwin_adjust_balance_motion(gint b)
+{
+    gchar *balance_msg;
+    gint v, pvl, pvr;
+
+    balance = b;
+    input_get_volume(&pvl, &pvr);
+    v = MAX(pvl, pvr);
+    if (b < 0) {
+        balance_msg = g_strdup_printf(_("Balance: %d%% left"), -b);
+        input_set_volume(v, (gint) rint(((100 + b) / 100.0) * v));
+    }
+    else if (b == 0) {
+        balance_msg = g_strdup_printf(_("Balance: center"));
+        input_set_volume(v, v);
+    }
+    else {                      /* b > 0 */
+        balance_msg = g_strdup_printf(_("Balance: %d%% right"), b);
+        input_set_volume((gint) rint(((100 - b) / 100.0) * v), v);
+    }
+    mainwin_lock_info_text(balance_msg);
+    g_free(balance_msg);
+}
+
+void
+mainwin_adjust_balance_release(void)
+{
+    mainwin_release_info_text();
+}
+
+void
+mainwin_set_volume_slider(gint percent)
+{
+    ui_skinned_horizontal_slider_set_position(mainwin_volume, (gint) rint((percent * 51) / 100.0));
+}
+
+void
+mainwin_set_balance_slider(gint percent)
+{
+    ui_skinned_horizontal_slider_set_position(mainwin_balance, (gint) rint(((percent * 12) / 100.0) + 12));
+}
+
+void
+mainwin_volume_motion_cb(GtkWidget *widget, gint pos)
+{
+    gint vol = (pos * 100) / 51;
+    mainwin_adjust_volume_motion(vol);
+    equalizerwin_set_volume_slider(vol);
+}
+
+gboolean
+mainwin_volume_release_cb(GtkWidget *widget, gint pos)
+{
+    mainwin_adjust_volume_release();
+    return FALSE;
+}
+
+gint
+mainwin_balance_frame_cb(gint pos)
+{
+    return ((abs(pos - 12) * 28) / 13);
+}
+
+void
+mainwin_balance_motion_cb(GtkWidget *widget, gint pos)
+{
+    gint bal = ((pos - 12) * 100) / 12;
+    mainwin_adjust_balance_motion(bal);
+    equalizerwin_set_balance_slider(bal);
+}
+
+void
+mainwin_balance_release_cb(GtkWidget *widget, gint pos)
+{
+    mainwin_adjust_volume_release();
+}
+
+void
+mainwin_set_volume_diff(gint diff)
+{
+    gint vl, vr, vol;
+
+    input_get_volume(&vl, &vr);
+    vol = MAX(vl, vr);
+    vol = CLAMP(vol + diff, 0, 100);
+
+    mainwin_adjust_volume_motion(vol);
+    mainwin_set_volume_slider(vol);
+    equalizerwin_set_volume_slider(vol);
+
+    if (mainwin_volume_release_timeout)
+        g_source_remove(mainwin_volume_release_timeout);
+    mainwin_volume_release_timeout =
+        g_timeout_add(700, (GSourceFunc)(mainwin_volume_release_cb), NULL);
+}
+
+void
+mainwin_set_balance_diff(gint diff)
+{
+    gint b;
+    b = CLAMP(balance + diff, -100, 100);
+    mainwin_adjust_balance_motion(b);
+    mainwin_set_balance_slider(b);
+    equalizerwin_set_balance_slider(b);
+}
+
+void
+mainwin_show(gboolean show)
+{
+    if (show)
+        mainwin_real_show();
+    else
+        mainwin_real_hide();
+}
+
+void
+mainwin_real_show(void)
+{
+    cfg.player_visible = TRUE;
+
+    check_set( toggleaction_group_others , "show player" , TRUE );
+
+    if (cfg.player_shaded)
+        ui_vis_clear_data(mainwin_vis);
+
+    if (cfg.show_wm_decorations) {
+        if (cfg.player_x != -1 && cfg.save_window_position)
+            gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y);
+
+        gtk_widget_show(mainwin);
+        return;
+    }
+
+    if (cfg.player_x != -1 && cfg.save_window_position)
+        gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y);
+
+    mainwin_refresh_hints();
+    gtk_window_present(GTK_WINDOW(mainwin));
+}
+
+void
+mainwin_real_hide(void)
+{
+    check_set( toggleaction_group_others , "show player", FALSE);
+
+    if (cfg.player_shaded)
+        ui_svis_clear_data(mainwin_svis);
+
+    gtk_widget_hide(mainwin);
+
+    cfg.player_visible = FALSE;
+}
+
+
+void
+mainwin_set_stopaftersong(gboolean stop)
+{
+    cfg.stopaftersong = stop;
+    check_set(toggleaction_group_others, "stop after current song", cfg.stopaftersong);
+}
+
+void
+mainwin_set_noplaylistadvance(gboolean no_advance)
+{
+    cfg.no_playlist_advance = no_advance;
+    check_set(toggleaction_group_others, "playback no playlist advance", cfg.no_playlist_advance);
+}
+
+static void
+mainwin_set_scaled(gboolean scaled)
+{
+    gint height;
+
+    if (cfg.player_shaded)
+        height = MAINWIN_SHADED_HEIGHT;
+    else
+        height = aud_active_skin->properties.mainwin_height;
+
+    dock_window_resize(GTK_WINDOW(mainwin), cfg.player_shaded ? MAINWIN_SHADED_WIDTH : aud_active_skin->properties.mainwin_width,
+                       cfg.player_shaded ? MAINWIN_SHADED_HEIGHT : aud_active_skin->properties.mainwin_height,
+                       aud_active_skin->properties.mainwin_width * cfg.scale_factor , aud_active_skin->properties.mainwin_height * cfg.scale_factor);
+
+    GList *iter;
+    for (iter = GTK_FIXED (SKINNED_WINDOW(mainwin)->fixed)->children; iter; iter = g_list_next (iter)) {
+        GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
+        GtkWidget *child = child_data->widget;
+        g_signal_emit_by_name(child, "toggle-scaled");
+    }
+
+    mainwin_refresh_hints();
+    gtk_widget_shape_combine_mask(mainwin, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
+}
+
+void
+set_scaled(gboolean scaled)
+{
+    cfg.scaled = scaled;
+
+    mainwin_set_scaled(scaled);
+
+    if (cfg.eq_scaled_linked)
+        equalizerwin_set_scaled(scaled);
+}
+
+
+
+void
+mainwin_general_menu_callback(gpointer data,
+                              guint action,
+                              GtkWidget * item)
+{
+    Playlist *playlist = playlist_get_active();
+
+    switch (action) {
+        case MAINWIN_GENERAL_PREFS:
+            show_prefs_window();
+            break;
+        case MAINWIN_GENERAL_ABOUT:
+            show_about_window();
+            break;
+        case MAINWIN_GENERAL_PLAYFILE:
+            run_filebrowser(FALSE);
+            break;
+        case MAINWIN_GENERAL_PLAYLOCATION:
+            hook_call("urlopener show", NULL);
+            break;
+        case MAINWIN_GENERAL_FILEINFO:
+            ui_fileinfo_show_current(playlist);
+            break;
+        case MAINWIN_GENERAL_FOCUSPLWIN:
+            gtk_window_present(GTK_WINDOW(playlistwin));
+            break;
+        case MAINWIN_GENERAL_SHOWMWIN:
+            mainwin_show(GTK_CHECK_MENU_ITEM(item)->active);
+            break;
+        case MAINWIN_GENERAL_SHOWPLWIN:
+            if (GTK_CHECK_MENU_ITEM(item)->active)
+                playlistwin_show();
+            else
+                playlistwin_hide();
+            break;
+        case MAINWIN_GENERAL_SHOWEQWIN:
+            if (GTK_CHECK_MENU_ITEM(item)->active)
+                equalizerwin_real_show();
+            else
+                equalizerwin_real_hide();
+            break;
+        case MAINWIN_GENERAL_PREV:
+            playlist_prev(playlist);
+            break;
+        case MAINWIN_GENERAL_PLAY:
+            mainwin_play_pushed();
+            break;
+        case MAINWIN_GENERAL_PAUSE:
+            playback_pause();
+            break;
+        case MAINWIN_GENERAL_STOP:
+            mainwin_stop_pushed();
+            break;
+        case MAINWIN_GENERAL_NEXT:
+            playlist_next(playlist);
+            break;
+        case MAINWIN_GENERAL_BACK5SEC:
+            if (playback_get_playing()
+                && playlist_get_current_length(playlist) != -1)
+                playback_seek_relative(-5);
+            break;
+        case MAINWIN_GENERAL_FWD5SEC:
+            if (playback_get_playing()
+                && playlist_get_current_length(playlist) != -1)
+                playback_seek_relative(5);
+            break;
+        case MAINWIN_GENERAL_START:
+            playlist_set_position(playlist, 0);
+            break;
+        case MAINWIN_GENERAL_JTT:
+            mainwin_jump_to_time();
+            break;
+        case MAINWIN_GENERAL_JTF:
+            ui_jump_to_track();
+            break;
+        case MAINWIN_GENERAL_EXIT:
+            mainwin_quit_cb();
+            break;
+        case MAINWIN_GENERAL_SETAB:
+            if (playlist_get_current_length(playlist) != -1) {
+                if (ab_position_a == -1) {
+                    ab_position_a = playback_get_time();
+                    ab_position_b = -1;
+                    mainwin_lock_info_text("'Loop-Point A Position' set.");
+                } else if (ab_position_b == -1) {
+                    int time = playback_get_time();
+                    if (time > ab_position_a)
+                        ab_position_b = time;
+                    mainwin_release_info_text();
+                } else {
+                    ab_position_a = playback_get_time();
+                    ab_position_b = -1;
+                    mainwin_lock_info_text("'Loop-Point A Position' reset.");
+                }
+            }
+            break;
+        case MAINWIN_GENERAL_CLEARAB:
+            if (playlist_get_current_length(playlist) != -1) {
+                ab_position_a = ab_position_b = -1;
+                mainwin_release_info_text();
+            }
+            break;
+        case MAINWIN_GENERAL_NEW_PL:
+            {
+                Playlist *new_pl = playlist_new();
+                playlist_add_playlist(new_pl);
+                playlist_select_playlist(new_pl);
+            }
+            break;
+        case MAINWIN_GENERAL_PREV_PL:
+            playlist_select_prev();
+            break;
+        case MAINWIN_GENERAL_NEXT_PL:
+            playlist_select_next();
+            break;
+    }
+}
+
+static void
+mainwin_mr_change(GtkWidget *widget, MenuRowItem i)
+{
+    switch (i) {
+        case MENUROW_OPTIONS:
+            mainwin_lock_info_text(_("Options Menu"));
+            break;
+        case MENUROW_ALWAYS:
+            if (UI_SKINNED_MENUROW(mainwin_menurow)->always_selected)
+                mainwin_lock_info_text(_("Disable 'Always On Top'"));
+            else
+                mainwin_lock_info_text(_("Enable 'Always On Top'"));
+            break;
+        case MENUROW_FILEINFOBOX:
+            mainwin_lock_info_text(_("File Info Box"));
+            break;
+        case MENUROW_SCALE:
+            if (UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected)
+                mainwin_lock_info_text(_("Disable 'GUI Scaling'"));
+            else
+                mainwin_lock_info_text(_("Enable 'GUI Scaling'"));
+            break;
+        case MENUROW_VISUALIZATION:
+            mainwin_lock_info_text(_("Visualization Menu"));
+            break;
+        case MENUROW_NONE:
+            break;
+    }
+}
+
+static void
+mainwin_mr_release(GtkWidget *widget, MenuRowItem i, GdkEventButton *event)
+{
+    switch (i) {
+        case MENUROW_OPTIONS:
+            ui_manager_popup_menu_show(GTK_MENU(mainwin_view_menu),
+                                       event->x_root, event->y_root, 1,
+                                       event->time);
+            break;
+        case MENUROW_ALWAYS:
+            gtk_toggle_action_set_active(
+                                         GTK_TOGGLE_ACTION(gtk_action_group_get_action(
+                                                                                       toggleaction_group_others , "view always on top" )) ,
+                                         UI_SKINNED_MENUROW(mainwin_menurow)->always_selected );
+            break;
+        case MENUROW_FILEINFOBOX:
+            ui_fileinfo_show_current(playlist_get_active());
+            break;
+        case MENUROW_SCALE:
+            gtk_toggle_action_set_active(
+                                         GTK_TOGGLE_ACTION(gtk_action_group_get_action(
+                                                                                       toggleaction_group_others , "view scaled" )) ,
+                                         UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected );
+            break;
+        case MENUROW_VISUALIZATION:
+            ui_manager_popup_menu_show(GTK_MENU(mainwin_visualization_menu),
+                                       event->x_root, event->y_root, 1,
+                                       event->time);
+            break;
+        case MENUROW_NONE:
+            break;
+    }
+    mainwin_release_info_text();
+}
+
+void
+run_no_output_device_dialog(gpointer hook_data, gpointer user_data)
+{
+    const gchar *markup =
+        N_("<b><big>Couldn't open audio.</big></b>\n\n"
+           "Please check that:\n"
+           "1. You have the correct output plugin selected.\n"
+           "2. No other programs is blocking the soundcard.\n"
+           "3. Your soundcard is configured properly.\n");
+
+    GDK_THREADS_ENTER();
+    GtkWidget *dialog =
+        gtk_message_dialog_new_with_markup(GTK_WINDOW(mainwin),
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_OK,
+                                           _(markup));
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+    GDK_THREADS_LEAVE();
+}
+
+static void
+set_timer_mode(TimerMode mode)
+{
+    if (mode == TIMER_ELAPSED)
+        check_set(radioaction_group_viewtime, "view time elapsed", TRUE);
+    else
+        check_set(radioaction_group_viewtime, "view time remaining", TRUE);
+}
+
+static void
+set_timer_mode_menu_cb(TimerMode mode)
+{
+    cfg.timer_mode = mode;
+}
+
+gboolean
+change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event)
+{
+    if (event->button == 1) {
+        change_timer_mode();
+    } else if (event->button == 3)
+        return FALSE;
+
+    return TRUE;
+}
+
+static void change_timer_mode(void) {
+    if (cfg.timer_mode == TIMER_ELAPSED)
+        set_timer_mode(TIMER_REMAINING);
+    else
+        set_timer_mode(TIMER_ELAPSED);
+    if (playback_get_playing())
+        mainwin_update_song_info();
+}
+
+static void
+mainwin_playlist_prev(void)
+{
+    playlist_prev(playlist_get_active());
+}
+
+static void
+mainwin_playlist_next(void)
+{
+    playlist_next(playlist_get_active());
+}
+
+void
+mainwin_setup_menus(void)
+{
+    set_timer_mode(cfg.timer_mode);
+
+    /* View menu */
+
+    check_set(toggleaction_group_others, "view always on top", cfg.always_on_top);
+    check_set(toggleaction_group_others, "view put on all workspaces", cfg.sticky);
+    check_set(toggleaction_group_others, "roll up player", cfg.player_shaded);
+    check_set(toggleaction_group_others, "roll up playlist editor", cfg.playlist_shaded);
+    check_set(toggleaction_group_others, "roll up equalizer", cfg.equalizer_shaded);
+    check_set(toggleaction_group_others, "view easy move", cfg.easy_move);
+    check_set(toggleaction_group_others, "view scaled", cfg.scaled);
+
+    /* Songname menu */
+
+    check_set(toggleaction_group_others, "autoscroll songname", cfg.autoscroll);
+    check_set(toggleaction_group_others, "stop after current song", cfg.stopaftersong);
+
+    /* Playback menu */
+
+    check_set(toggleaction_group_others, "playback repeat", cfg.repeat);
+    check_set(toggleaction_group_others, "playback shuffle", cfg.shuffle);
+    check_set(toggleaction_group_others, "playback no playlist advance", cfg.no_playlist_advance);
+
+    /* Visualization menu */
+
+    switch ( cfg.vis_type )
+    {
+        case VIS_ANALYZER:
+            check_set(radioaction_group_vismode, "vismode analyzer", TRUE);
+            break;
+        case VIS_SCOPE:
+            check_set(radioaction_group_vismode, "vismode scope", TRUE);
+            break;
+        case VIS_VOICEPRINT:
+            check_set(radioaction_group_vismode, "vismode voiceprint", TRUE);
+            break;
+        case VIS_OFF:
+        default:
+            check_set(radioaction_group_vismode, "vismode off", TRUE);
+            break;
+    }
+
+    switch ( cfg.analyzer_mode )
+    {
+        case ANALYZER_FIRE:
+            check_set(radioaction_group_anamode, "anamode fire", TRUE);
+            break;
+        case ANALYZER_VLINES:
+            check_set(radioaction_group_anamode, "anamode vertical lines", TRUE);
+            break;
+        case ANALYZER_NORMAL:
+        default:
+            check_set(radioaction_group_anamode, "anamode normal", TRUE);
+            break;
+    }
+
+    switch ( cfg.analyzer_type )
+    {
+        case ANALYZER_BARS:
+            check_set(radioaction_group_anatype, "anatype bars", TRUE);
+            break;
+        case ANALYZER_LINES:
+        default:
+            check_set(radioaction_group_anatype, "anatype lines", TRUE);
+            break;
+    }
+
+    check_set(toggleaction_group_others, "anamode peaks", cfg.analyzer_peaks );
+
+    switch ( cfg.scope_mode )
+    {
+        case SCOPE_LINE:
+            check_set(radioaction_group_scomode, "scomode line", TRUE);
+            break;
+        case SCOPE_SOLID:
+            check_set(radioaction_group_scomode, "scomode solid", TRUE);
+            break;
+        case SCOPE_DOT:
+        default:
+            check_set(radioaction_group_scomode, "scomode dot", TRUE);
+            break;
+    }
+
+    switch ( cfg.voiceprint_mode )
+    {
+        case VOICEPRINT_FIRE:
+            check_set(radioaction_group_vprmode, "vprmode fire", TRUE);
+            break;
+        case VOICEPRINT_ICE:
+            check_set(radioaction_group_vprmode, "vprmode ice", TRUE);
+            break;
+        case VOICEPRINT_NORMAL:
+        default:
+            check_set(radioaction_group_vprmode, "vprmode normal", TRUE);
+            break;
+    }
+
+    switch ( cfg.vu_mode )
+    {
+        case VU_SMOOTH:
+            check_set(radioaction_group_wshmode, "wshmode smooth", TRUE);
+            break;
+        case VU_NORMAL:
+        default:
+            check_set(radioaction_group_wshmode, "wshmode normal", TRUE);
+            break;
+    }
+
+    switch ( cfg.vis_refresh )
+    {
+        case REFRESH_HALF:
+            check_set(radioaction_group_refrate, "refrate half", TRUE);
+            break;
+        case REFRESH_QUARTER:
+            check_set(radioaction_group_refrate, "refrate quarter", TRUE);
+            break;
+        case REFRESH_EIGTH:
+            check_set(radioaction_group_refrate, "refrate eighth", TRUE);
+            break;
+        case REFRESH_FULL:
+        default:
+            check_set(radioaction_group_refrate, "refrate full", TRUE);
+            break;
+    }
+
+    switch ( cfg.analyzer_falloff )
+    {
+        case FALLOFF_SLOW:
+            check_set(radioaction_group_anafoff, "anafoff slow", TRUE);
+            break;
+        case FALLOFF_MEDIUM:
+            check_set(radioaction_group_anafoff, "anafoff medium", TRUE);
+            break;
+        case FALLOFF_FAST:
+            check_set(radioaction_group_anafoff, "anafoff fast", TRUE);
+            break;
+        case FALLOFF_FASTEST:
+            check_set(radioaction_group_anafoff, "anafoff fastest", TRUE);
+            break;
+        case FALLOFF_SLOWEST:
+        default:
+            check_set(radioaction_group_anafoff, "anafoff slowest", TRUE);
+            break;
+    }
+
+    switch ( cfg.peaks_falloff )
+    {
+        case FALLOFF_SLOW:
+            check_set(radioaction_group_peafoff, "peafoff slow", TRUE);
+            break;
+        case FALLOFF_MEDIUM:
+            check_set(radioaction_group_peafoff, "peafoff medium", TRUE);
+            break;
+        case FALLOFF_FAST:
+            check_set(radioaction_group_peafoff, "peafoff fast", TRUE);
+            break;
+        case FALLOFF_FASTEST:
+            check_set(radioaction_group_peafoff, "peafoff fastest", TRUE);
+            break;
+        case FALLOFF_SLOWEST:
+        default:
+            check_set(radioaction_group_peafoff, "peafoff slowest", TRUE);
+            break;
+    }
+
+}
+
+static void mainwin_info_double_clicked_cb(void) {
+    ui_fileinfo_show_current(playlist_get_active());
+}
+
+static void
+mainwin_info_right_clicked_cb(GtkWidget *widget, GdkEventButton *event)
+{
+    ui_manager_popup_menu_show(GTK_MENU(mainwin_songname_menu),
+                               event->x_root, event->y_root, 3, event->time);
+}
+
+static void
+mainwin_create_widgets(void)
+{
+    mainwin_menubtn = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_menubtn, SKINNED_WINDOW(mainwin)->fixed,
+                                 6, 3, 9, 9, 0, 0, 0, 9, SKIN_TITLEBAR);
+    g_signal_connect(mainwin_menubtn, "clicked", mainwin_menubtn_cb, NULL );
+
+    mainwin_minimize = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_minimize, SKINNED_WINDOW(mainwin)->fixed,
+                                 244, 3, 9, 9, 9, 0, 9, 9, SKIN_TITLEBAR);
+    g_signal_connect(mainwin_minimize, "clicked", mainwin_minimize_cb, NULL );
+
+    mainwin_shade = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_shade, SKINNED_WINDOW(mainwin)->fixed,
+                                 254, 3, 9, 9, 0,
+                                 cfg.player_shaded ? 27 : 18, 9, cfg.player_shaded ? 27 : 18, SKIN_TITLEBAR);
+    g_signal_connect(mainwin_shade, "clicked", mainwin_shade_toggle, NULL );
+
+    mainwin_close = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_close, SKINNED_WINDOW(mainwin)->fixed,
+                                 264, 3, 9, 9, 18, 0, 18, 9, SKIN_TITLEBAR);
+    g_signal_connect(mainwin_close, "clicked", mainwin_quit_cb, NULL );
+
+    mainwin_rew = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_rew, SKINNED_WINDOW(mainwin)->fixed,
+                                 16, 88, 23, 18, 0, 0, 0, 18, SKIN_CBUTTONS);
+    g_signal_connect(mainwin_rew, "pressed", mainwin_rev_pushed, NULL);
+    g_signal_connect(mainwin_rew, "released", mainwin_rev_release, NULL);
+
+    mainwin_fwd = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_fwd, SKINNED_WINDOW(mainwin)->fixed,
+                                 108, 88, 22, 18, 92, 0, 92, 18, SKIN_CBUTTONS);
+    g_signal_connect(mainwin_fwd, "pressed", mainwin_fwd_pushed, NULL);
+    g_signal_connect(mainwin_fwd, "released", mainwin_fwd_release, NULL);
+
+    mainwin_play = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_play, SKINNED_WINDOW(mainwin)->fixed,
+                                 39, 88, 23, 18, 23, 0, 23, 18, SKIN_CBUTTONS);
+    g_signal_connect(mainwin_play, "clicked", mainwin_play_pushed, NULL );
+
+    mainwin_pause = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_pause, SKINNED_WINDOW(mainwin)->fixed,
+                                 62, 88, 23, 18, 46, 0, 46, 18, SKIN_CBUTTONS);
+    g_signal_connect(mainwin_pause, "clicked", playback_pause, NULL );
+
+    mainwin_stop = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_stop, SKINNED_WINDOW(mainwin)->fixed,
+                                 85, 88, 23, 18, 69, 0, 69, 18, SKIN_CBUTTONS);
+    g_signal_connect(mainwin_stop, "clicked", mainwin_stop_pushed, NULL );
+
+    mainwin_eject = ui_skinned_button_new();
+    ui_skinned_push_button_setup(mainwin_eject, SKINNED_WINDOW(mainwin)->fixed,
+                                 136, 89, 22, 16, 114, 0, 114, 16, SKIN_CBUTTONS);
+    g_signal_connect(mainwin_eject, "clicked", mainwin_eject_pushed, NULL);
+
+    mainwin_srew = ui_skinned_button_new();
+    ui_skinned_small_button_setup(mainwin_srew, SKINNED_WINDOW(mainwin)->fixed, 169, 4, 8, 7);
+    g_signal_connect(mainwin_srew, "clicked", mainwin_playlist_prev, NULL);
+
+    mainwin_splay = ui_skinned_button_new();
+    ui_skinned_small_button_setup(mainwin_splay, SKINNED_WINDOW(mainwin)->fixed, 177, 4, 10, 7);
+    g_signal_connect(mainwin_splay, "clicked", mainwin_play_pushed, NULL);
+
+    mainwin_spause = ui_skinned_button_new();
+    ui_skinned_small_button_setup(mainwin_spause, SKINNED_WINDOW(mainwin)->fixed, 187, 4, 10, 7);
+    g_signal_connect(mainwin_spause, "clicked", playback_pause, NULL);
+
+    mainwin_sstop = ui_skinned_button_new();
+    ui_skinned_small_button_setup(mainwin_sstop, SKINNED_WINDOW(mainwin)->fixed, 197, 4, 9, 7);
+    g_signal_connect(mainwin_sstop, "clicked", mainwin_stop_pushed, NULL);
+
+    mainwin_sfwd = ui_skinned_button_new();
+    ui_skinned_small_button_setup(mainwin_sfwd, SKINNED_WINDOW(mainwin)->fixed, 206, 4, 8, 7);
+    g_signal_connect(mainwin_sfwd, "clicked", mainwin_playlist_next, NULL);
+
+    mainwin_seject = ui_skinned_button_new();
+    ui_skinned_small_button_setup(mainwin_seject, SKINNED_WINDOW(mainwin)->fixed, 216, 4, 9, 7);
+    g_signal_connect(mainwin_seject, "clicked", mainwin_eject_pushed, NULL);
+
+    mainwin_shuffle = ui_skinned_button_new();
+    ui_skinned_toggle_button_setup(mainwin_shuffle, SKINNED_WINDOW(mainwin)->fixed,
+                                   164, 89, 46, 15, 28, 0, 28, 15, 28, 30, 28, 45, SKIN_SHUFREP);
+    g_signal_connect(mainwin_shuffle, "clicked", mainwin_shuffle_pushed_cb, NULL);
+
+    mainwin_repeat = ui_skinned_button_new();
+    ui_skinned_toggle_button_setup(mainwin_repeat, SKINNED_WINDOW(mainwin)->fixed,
+                                   210, 89, 28, 15, 0, 0, 0, 15, 0, 30, 0, 45, SKIN_SHUFREP);
+    g_signal_connect(mainwin_repeat, "clicked", mainwin_repeat_pushed_cb, NULL);
+
+    mainwin_eq = ui_skinned_button_new();
+    ui_skinned_toggle_button_setup(mainwin_eq, SKINNED_WINDOW(mainwin)->fixed,
+                                   219, 58, 23, 12, 0, 61, 46, 61, 0, 73, 46, 73, SKIN_SHUFREP);
+    g_signal_connect(mainwin_eq, "clicked", mainwin_equalizer_pushed_cb, NULL);
+    UI_SKINNED_BUTTON(mainwin_eq)->inside = cfg.equalizer_visible;
+
+    mainwin_pl = ui_skinned_button_new();
+    ui_skinned_toggle_button_setup(mainwin_pl, SKINNED_WINDOW(mainwin)->fixed,
+                                   242, 58, 23, 12, 23, 61, 69, 61, 23, 73, 69, 73, SKIN_SHUFREP);
+    g_signal_connect(mainwin_pl, "clicked", mainwin_playlist_pushed_cb, NULL);
+    UI_SKINNED_BUTTON(mainwin_pl)->inside = cfg.playlist_visible;
+
+    mainwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 112, 27, 153, 1, SKIN_TEXT);
+    ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll);
+    ui_skinned_textbox_set_xfont(mainwin_info, !cfg.mainwin_use_bitmapfont, cfg.mainwin_font);
+    g_signal_connect(mainwin_info, "double-clicked", mainwin_info_double_clicked_cb, NULL);
+    g_signal_connect(mainwin_info, "right-clicked", G_CALLBACK(mainwin_info_right_clicked_cb), NULL);
+
+    mainwin_othertext = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 112, 43, 153, 1, SKIN_TEXT);
+
+    mainwin_rate_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 111, 43, 15, 0, SKIN_TEXT);
+
+    mainwin_freq_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 156, 43, 10, 0, SKIN_TEXT);
+
+    mainwin_menurow = ui_skinned_menurow_new(SKINNED_WINDOW(mainwin)->fixed, 10, 22, 304, 0, 304, 44,  SKIN_TITLEBAR);
+    g_signal_connect(mainwin_menurow, "change", G_CALLBACK(mainwin_mr_change), NULL);
+    g_signal_connect(mainwin_menurow, "release", G_CALLBACK(mainwin_mr_release), NULL);
+
+    mainwin_volume = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 107, 57, 68,
+                                                      13, 15, 422, 0, 422, 14, 11, 15, 0, 0, 51,
+                                                      mainwin_volume_frame_cb, SKIN_VOLUME);
+    g_signal_connect(mainwin_volume, "motion", G_CALLBACK(mainwin_volume_motion_cb), NULL);
+    g_signal_connect(mainwin_volume, "release", G_CALLBACK(mainwin_volume_release_cb), NULL);
+
+    mainwin_balance = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 177, 57, 38,
+                                                       13, 15, 422, 0, 422, 14, 11, 15, 9, 0, 24,
+                                                       mainwin_balance_frame_cb, SKIN_BALANCE);
+    g_signal_connect(mainwin_balance, "motion", G_CALLBACK(mainwin_balance_motion_cb), NULL);
+    g_signal_connect(mainwin_balance, "release", G_CALLBACK(mainwin_balance_release_cb), NULL);
+
+    mainwin_monostereo = ui_skinned_monostereo_new(SKINNED_WINDOW(mainwin)->fixed, 212, 41, SKIN_MONOSTEREO);
+
+    mainwin_playstatus = ui_skinned_playstatus_new(SKINNED_WINDOW(mainwin)->fixed, 24, 28);
+
+    mainwin_minus_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 36, 26, SKIN_NUMBERS);
+    g_signal_connect(mainwin_minus_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    mainwin_10min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 48, 26, SKIN_NUMBERS);
+    g_signal_connect(mainwin_10min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    mainwin_min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 60, 26, SKIN_NUMBERS);
+    g_signal_connect(mainwin_min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    mainwin_10sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 78, 26, SKIN_NUMBERS);
+    g_signal_connect(mainwin_10sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    mainwin_sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 90, 26, SKIN_NUMBERS);
+    g_signal_connect(mainwin_sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    mainwin_about = ui_skinned_button_new();
+    ui_skinned_small_button_setup(mainwin_about, SKINNED_WINDOW(mainwin)->fixed, 247, 83, 20, 25);
+    g_signal_connect(mainwin_about, "clicked", show_about_window, NULL);
+
+    mainwin_vis = ui_vis_new(SKINNED_WINDOW(mainwin)->fixed, 24, 43, 76);
+    g_signal_connect(mainwin_vis, "button-press-event", G_CALLBACK(mainwin_vis_cb), NULL);
+    mainwin_svis = ui_svis_new(SKINNED_WINDOW(mainwin)->fixed, 79, 5);
+    g_signal_connect(mainwin_svis, "button-press-event", G_CALLBACK(mainwin_vis_cb), NULL);
+
+    mainwin_position = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 16, 72, 248,
+                                                        10, 248, 0, 278, 0, 29, 10, 10, 0, 0, 219,
+                                                        NULL, SKIN_POSBAR);
+    g_signal_connect(mainwin_position, "motion", G_CALLBACK(mainwin_position_motion_cb), NULL);
+    g_signal_connect(mainwin_position, "release", G_CALLBACK(mainwin_position_release_cb), NULL);
+
+    mainwin_sposition = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 226, 4, 17,
+                                                         7, 17, 36, 17, 36, 3, 7, 36, 0, 1, 13,
+                                                         mainwin_spos_frame_cb, SKIN_TITLEBAR);
+    g_signal_connect(mainwin_sposition, "motion", G_CALLBACK(mainwin_spos_motion_cb), NULL);
+    g_signal_connect(mainwin_sposition, "release", G_CALLBACK(mainwin_spos_release_cb), NULL);
+
+    mainwin_stime_min = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 130, 4, 15, FALSE, SKIN_TEXT);
+    g_signal_connect(mainwin_stime_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    mainwin_stime_sec = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 147, 4, 10, FALSE, SKIN_TEXT);
+    g_signal_connect(mainwin_stime_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+
+    hook_associate("playback audio error", (void *) mainwin_stop_pushed, NULL);
+    hook_associate("playback audio error", (void *) run_no_output_device_dialog, NULL);
+
+    hook_associate("playback seek", (HookFunction) mainwin_update_song_info, NULL);
+}
+
+static void
+mainwin_create_window(void)
+{
+    gint width, height;
+
+    mainwin = ui_skinned_window_new("player");
+    gtk_window_set_title(GTK_WINDOW(mainwin), _("Audacious"));
+    gtk_window_set_role(GTK_WINDOW(mainwin), "player");
+    gtk_window_set_resizable(GTK_WINDOW(mainwin), FALSE);
+
+    width = cfg.player_shaded ? MAINWIN_SHADED_WIDTH : aud_active_skin->properties.mainwin_width;
+    height = cfg.player_shaded ? MAINWIN_SHADED_HEIGHT : aud_active_skin->properties.mainwin_height;
+
+    if (cfg.scaled) {
+        width *= cfg.scale_factor;
+        height *= cfg.scale_factor;
+    }
+
+    gtk_widget_set_size_request(mainwin, width, height);
+
+    if (cfg.player_x != -1 && cfg.save_window_position)
+        gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y);
+
+    g_signal_connect(mainwin, "destroy", G_CALLBACK(mainwin_destroy), NULL);
+    g_signal_connect(mainwin, "button_press_event",
+                     G_CALLBACK(mainwin_mouse_button_press), NULL);
+    g_signal_connect(mainwin, "scroll_event",
+                     G_CALLBACK(mainwin_scrolled), NULL);
+    g_signal_connect(mainwin, "button_release_event",
+                     G_CALLBACK(mainwin_mouse_button_release), NULL);
+
+    aud_drag_dest_set(mainwin);
+
+    g_signal_connect(mainwin, "key_press_event",
+                     G_CALLBACK(mainwin_keypress), NULL);
+
+    ui_main_evlistener_init();
+}
+
+void
+mainwin_create(void)
+{
+    mainwin_create_window();
+
+    gtk_window_add_accel_group( GTK_WINDOW(mainwin) , ui_manager_get_accel_group() );
+
+    mainwin_create_widgets();
+}
+
+gboolean
+mainwin_update_song_info(void)
+{
+    if (!playback_get_playing())
+        return FALSE;
+
+    gint time = playback_get_time();
+    gint length = playback_get_length();
+    gint t;
+    gchar stime_prefix;
+
+    if (ab_position_a != -1 && ab_position_b != -1 && time > ab_position_b)
+        playback_seek(ab_position_a/1000);
+
+    if (length == -1 && cfg.timer_mode == TIMER_REMAINING)
+        cfg.timer_mode = TIMER_ELAPSED;
+
+    playlistwin_set_time(time, length, cfg.timer_mode);
+
+    if (cfg.timer_mode == TIMER_REMAINING) {
+        if (length != -1) {
+            ui_skinned_number_set_number(mainwin_minus_num, 11);
+            t = length - time;
+            stime_prefix = '-';
+        }
+        else {
+            ui_skinned_number_set_number(mainwin_minus_num, 10);
+            t = time;
+            stime_prefix = ' ';
+        }
+    }
+    else {
+        ui_skinned_number_set_number(mainwin_minus_num, 10);
+        t = time;
+        stime_prefix = ' ';
+    }
+    t /= 1000;
+
+    /* Show the time in the format HH:MM when we have more than 100
+     * minutes. */
+    if (t >= 100 * 60)
+        t /= 60;
+    ui_skinned_number_set_number(mainwin_10min_num, t / 600);
+    ui_skinned_number_set_number(mainwin_min_num, (t / 60) % 10);
+    ui_skinned_number_set_number(mainwin_10sec_num, (t / 10) % 6);
+    ui_skinned_number_set_number(mainwin_sec_num, t % 10);
+
+    if (!UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->pressed) {
+        gchar *time_str;
+
+        time_str = g_strdup_printf("%c%2.2d", stime_prefix, t / 60);
+        ui_skinned_textbox_set_text(mainwin_stime_min, time_str);
+        g_free(time_str);
+
+        time_str = g_strdup_printf("%2.2d", t % 60);
+        ui_skinned_textbox_set_text(mainwin_stime_sec, time_str);
+        g_free(time_str);
+    }
+
+    time /= 1000;
+    length /= 1000;
+    if (length > 0) {
+        if (time > length) {
+            ui_skinned_horizontal_slider_set_position(mainwin_position, 219);
+            ui_skinned_horizontal_slider_set_position(mainwin_sposition, 13);
+        }
+        /* update the slider position ONLY if there is not a seek in progress */
+        else if (seek_state == MAINWIN_SEEK_NIL)  {
+            ui_skinned_horizontal_slider_set_position(mainwin_position, (time * 219) / length);
+            ui_skinned_horizontal_slider_set_position(mainwin_sposition,
+                                                      ((time * 12) / length) + 1);
+        }
+    }
+    else {
+        ui_skinned_horizontal_slider_set_position(mainwin_position, 0);
+        ui_skinned_horizontal_slider_set_position(mainwin_sposition, 1);
+    }
+
+    return TRUE;
+}
+
+static gboolean
+mainwin_idle_func(gpointer data)
+{
+    GDK_THREADS_ENTER();
+
+    /* tristate buttons seek */
+    if ( seek_state != MAINWIN_SEEK_NIL )
+    {
+        GTimeVal now_time;
+        GTimeVal delta_time;
+        gulong now_dur;
+        g_get_current_time(&now_time);
+
+        delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec;
+        delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec;
+
+        now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000));
+
+        if ( now_dur > TRISTATE_THRESHOLD )
+        {
+            gint np;
+            if (seek_state == MAINWIN_SEEK_REV)
+                np = seek_initial_pos - labs((gulong)(now_dur/100)); /* seek back */
+            else
+                np = seek_initial_pos + labs((gulong)(now_dur/100)); /* seek forward */
+
+            /* boundaries check */
+            if (np < 0 )
+                np = 0;
+            else if ( np > 219 )
+                np = 219;
+
+            ui_skinned_horizontal_slider_set_position( mainwin_position , np );
+            mainwin_position_motion_cb( mainwin_position, np );
+        }
+    }
+
+    GDK_THREADS_LEAVE();
+    return TRUE;
+}
+
+
+/* toggleactionentries actions */
+
+void
+action_anamode_peaks( GtkToggleAction * action )
+{
+    cfg.analyzer_peaks = gtk_toggle_action_get_active( action );
+}
+
+void
+action_autoscroll_songname( GtkToggleAction * action )
+{
+    mainwin_set_title_scroll(gtk_toggle_action_get_active(action));
+    playlistwin_set_sinfo_scroll(cfg.autoscroll); /* propagate scroll setting to playlistwin_sinfo */
+}
+
+void
+action_playback_noplaylistadvance( GtkToggleAction * action )
+{
+    cfg.no_playlist_advance = gtk_toggle_action_get_active( action );
+}
+
+void
+action_playback_repeat( GtkToggleAction * action )
+{
+    cfg.repeat = gtk_toggle_action_get_active( action );
+    UI_SKINNED_BUTTON(mainwin_repeat)->inside = cfg.repeat;
+    gtk_widget_queue_draw(mainwin_repeat);
+}
+
+void
+action_playback_shuffle( GtkToggleAction * action )
+{
+    cfg.shuffle = gtk_toggle_action_get_active( action );
+    playlist_set_shuffle(cfg.shuffle);
+    UI_SKINNED_BUTTON(mainwin_shuffle)->inside = cfg.shuffle;
+    gtk_widget_queue_draw(mainwin_shuffle);
+}
+
+void
+action_stop_after_current_song( GtkToggleAction * action )
+{
+    cfg.stopaftersong = gtk_toggle_action_get_active( action );
+}
+
+void
+action_view_always_on_top( GtkToggleAction * action )
+{
+    UI_SKINNED_MENUROW(mainwin_menurow)->always_selected = gtk_toggle_action_get_active( action );
+    cfg.always_on_top = UI_SKINNED_MENUROW(mainwin_menurow)->always_selected;
+    gtk_widget_queue_draw(mainwin_menurow);
+    hint_set_always(cfg.always_on_top);
+}
+
+void
+action_view_scaled( GtkToggleAction * action )
+{
+    UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected = gtk_toggle_action_get_active( action );
+    gtk_widget_queue_draw(mainwin_menurow);
+    set_scaled(UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected);
+    gdk_flush();
+}
+
+void
+action_view_easymove( GtkToggleAction * action )
+{
+    cfg.easy_move = gtk_toggle_action_get_active( action );
+}
+
+void
+action_view_on_all_workspaces( GtkToggleAction * action )
+{
+    cfg.sticky = gtk_toggle_action_get_active( action );
+    hint_set_sticky(cfg.sticky);
+}
+
+void
+action_roll_up_equalizer( GtkToggleAction * action )
+{
+    equalizerwin_set_shade_menu_cb(gtk_toggle_action_get_active(action));
+}
+
+void
+action_roll_up_player( GtkToggleAction * action )
+{
+    mainwin_set_shade_menu_cb(gtk_toggle_action_get_active(action));
+}
+
+void
+action_roll_up_playlist_editor( GtkToggleAction * action )
+{
+    playlistwin_set_shade(gtk_toggle_action_get_active(action));
+}
+
+void
+action_show_equalizer( GtkToggleAction * action )
+{
+    if (gtk_toggle_action_get_active(action))
+        equalizerwin_real_show();
+    else
+        equalizerwin_real_hide();
+}
+
+void
+action_show_playlist_editor( GtkToggleAction * action )
+{
+    if (gtk_toggle_action_get_active(action))
+        playlistwin_show();
+    else
+        playlistwin_hide();
+}
+
+void
+action_show_player( GtkToggleAction * action )
+{
+    mainwin_show(gtk_toggle_action_get_active(action));
+}
+
+
+/* radioactionentries actions (one callback for each radio group) */
+
+void
+action_anafoff( GtkAction *action, GtkRadioAction *current )
+{
+    mainwin_vis_set_afalloff(gtk_radio_action_get_current_value(current));
+}
+
+void
+action_anamode( GtkAction *action, GtkRadioAction *current )
+{
+    mainwin_vis_set_analyzer_mode(gtk_radio_action_get_current_value(current));
+}
+
+void
+action_anatype( GtkAction *action, GtkRadioAction *current )
+{
+    mainwin_vis_set_analyzer_type(gtk_radio_action_get_current_value(current));
+}
+
+void
+action_peafoff( GtkAction *action, GtkRadioAction *current )
+{
+    mainwin_vis_set_pfalloff(gtk_radio_action_get_current_value(current));
+}
+
+void
+action_refrate( GtkAction *action, GtkRadioAction *current )
+{
+    mainwin_vis_set_refresh(gtk_radio_action_get_current_value(current));
+}
+
+void
+action_scomode( GtkAction *action, GtkRadioAction *current )
+{
+    cfg.scope_mode = gtk_radio_action_get_current_value(current);
+}
+
+void
+action_vismode( GtkAction *action, GtkRadioAction *current )
+{
+    mainwin_vis_set_type_menu_cb(gtk_radio_action_get_current_value(current));
+}
+
+void
+action_vprmode( GtkAction *action, GtkRadioAction *current )
+{
+    cfg.voiceprint_mode = gtk_radio_action_get_current_value(current);
+}
+
+void
+action_wshmode( GtkAction *action, GtkRadioAction *current )
+{
+    cfg.vu_mode = gtk_radio_action_get_current_value(current);
+}
+
+void
+action_viewtime( GtkAction *action, GtkRadioAction *current )
+{
+    set_timer_mode_menu_cb(gtk_radio_action_get_current_value(current));
+}
+
+
+/* actionentries actions */
+
+void
+action_about_audacious( void )
+{
+    show_about_window();
+}
+
+void
+action_play_file( void )
+{
+    run_filebrowser(TRUE);
+}
+
+void
+action_play_location( void )
+{
+    hook_call("urlopener show", NULL);
+}
+
+void
+action_ab_set( void )
+{
+    Playlist *playlist = playlist_get_active();
+    if (playlist_get_current_length(playlist) != -1)
+    {
+        if (ab_position_a == -1)
+        {
+            ab_position_a = playback_get_time();
+            ab_position_b = -1;
+            mainwin_lock_info_text("LOOP-POINT A POSITION SET.");
+        }
+        else if (ab_position_b == -1)
+        {
+            int time = playback_get_time();
+            if (time > ab_position_a)
+                ab_position_b = time;
+            mainwin_release_info_text();
+        }
+        else
+        {
+            ab_position_a = playback_get_time();
+            ab_position_b = -1;
+            mainwin_lock_info_text("LOOP-POINT A POSITION RESET.");
+        }
+    }
+}
+
+void
+action_ab_clear( void )
+{
+    Playlist *playlist = playlist_get_active();
+    if (playlist_get_current_length(playlist) != -1)
+    {
+        ab_position_a = ab_position_b = -1;
+        mainwin_release_info_text();
+    }
+}
+
+void
+action_current_track_info( void )
+{
+    ui_fileinfo_show_current(playlist_get_active());
+}
+
+void
+action_jump_to_file( void )
+{
+    ui_jump_to_track();
+}
+
+void
+action_jump_to_playlist_start( void )
+{
+    Playlist *playlist = playlist_get_active();
+    playlist_set_position(playlist, 0);
+}
+
+void
+action_jump_to_time( void )
+{
+    mainwin_jump_to_time();
+}
+
+void
+action_playback_next( void )
+{
+    Playlist *playlist = playlist_get_active();
+    playlist_next(playlist);
+}
+
+void
+action_playback_previous( void )
+{
+    Playlist *playlist = playlist_get_active();
+    playlist_prev(playlist);
+}
+
+void
+action_playback_play( void )
+{
+    mainwin_play_pushed();
+}
+
+void
+action_playback_pause( void )
+{
+    playback_pause();
+}
+
+void
+action_playback_stop( void )
+{
+    mainwin_stop_pushed();
+}
+
+void
+action_preferences( void )
+{
+    show_prefs_window();
+}
+
+void
+action_quit( void )
+{
+    mainwin_quit_cb();
+}
+
+void
+util_menu_main_show( gint x , gint y , guint button , guint time )
+{
+    /* convenience function that shows the main popup menu wherever requested */
+    ui_manager_popup_menu_show( GTK_MENU(mainwin_general_menu),
+                                x , y , button , time );
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_main.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,192 @@
+/*  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_MAIN_H
+#define AUDACIOUS_UI_MAIN_H
+
+#include <gtk/gtk.h>
+
+#include "ui_vis.h"
+#include "ui_svis.h"
+
+/* yes, main window size is fixed */
+#define MAINWIN_WIDTH            (gint)275
+#define MAINWIN_HEIGHT           (gint)116
+#define MAINWIN_TITLEBAR_HEIGHT  (gint)14
+#define MAINWIN_SHADED_WIDTH     MAINWIN_WIDTH
+#define MAINWIN_SHADED_HEIGHT    MAINWIN_TITLEBAR_HEIGHT
+#define MAINWIN_SCALE_FACTOR     (cfg.scaled ? cfg.scale_factor : 1)
+
+#define MAINWIN_UPDATE_INTERVAL  100
+
+#define MAINWIN_DEFAULT_POS_X    20
+#define MAINWIN_DEFAULT_POS_Y    20
+
+#define MAINWIN_DEFAULT_FONT     "Sans Bold 9"
+
+
+typedef enum {
+    TIMER_ELAPSED,
+    TIMER_REMAINING
+} TimerMode;
+
+enum {
+    MAINWIN_GENERAL_ABOUT,
+    
+    MAINWIN_GENERAL_PLAYFILE,
+    MAINWIN_GENERAL_PLAYLOCATION,
+
+    MAINWIN_GENERAL_FILEINFO,
+    MAINWIN_GENERAL_PREFS,
+
+    MAINWIN_GENERAL_SHOWMWIN,
+    MAINWIN_GENERAL_SHOWPLWIN,
+
+    MAINWIN_GENERAL_FOCUSMWIN,
+    MAINWIN_GENERAL_FOCUSPLWIN,
+
+    MAINWIN_GENERAL_SHOWEQWIN,
+    MAINWIN_GENERAL_EXIT,
+
+    MAINWIN_GENERAL_PREV,
+    MAINWIN_GENERAL_PLAY,
+    MAINWIN_GENERAL_PAUSE,
+    MAINWIN_GENERAL_STOP,
+    MAINWIN_GENERAL_NEXT,
+    MAINWIN_GENERAL_STOPFADE,
+    MAINWIN_GENERAL_BACK5SEC,
+    MAINWIN_GENERAL_FWD5SEC,
+    MAINWIN_GENERAL_START,
+    MAINWIN_GENERAL_BACK10,
+    MAINWIN_GENERAL_FWD10,
+    MAINWIN_GENERAL_JTT,
+    MAINWIN_GENERAL_JTF,
+    MAINWIN_GENERAL_QUEUE,
+    MAINWIN_GENERAL_CQUEUE,
+    MAINWIN_GENERAL_VOLUP,
+    MAINWIN_GENERAL_VOLDOWN,
+    MAINWIN_GENERAL_SETAB,
+    MAINWIN_GENERAL_CLEARAB,
+
+    MAINWIN_GENERAL_NEXT_PL,
+    MAINWIN_GENERAL_PREV_PL,
+    MAINWIN_GENERAL_NEW_PL
+};
+
+extern GtkWidget *mainwin;
+extern GtkWidget *err;
+
+extern gboolean mainwin_moving;
+extern gboolean mainwin_focus;
+
+extern GtkWidget *mainwin_jtf;
+extern GtkWidget *mainwin_eq, *mainwin_pl;
+extern GtkWidget *mainwin_info;
+
+extern GtkWidget *mainwin_stime_min, *mainwin_stime_sec;
+
+extern GtkWidget *mainwin_vis;
+extern GtkWidget *mainwin_svis;
+
+extern GtkWidget *mainwin_playstatus;
+
+extern GtkWidget *mainwin_minus_num, *mainwin_10min_num, *mainwin_min_num;
+extern GtkWidget *mainwin_10sec_num, *mainwin_sec_num;
+
+extern GtkWidget *mainwin_position, *mainwin_sposition;
+
+void mainwin_create(void);
+
+void mainwin_lock_info_text(const gchar * text);
+void mainwin_release_info_text(void);
+void mainwin_play_pushed(void);
+void mainwin_stop_pushed(void);
+void mainwin_eject_pushed(void);
+
+void mainwin_rev_pushed(void);
+void mainwin_rev_release(void);
+void mainwin_fwd_pushed(void);
+void mainwin_fwd_release(void);
+
+void mainwin_adjust_volume_motion(gint v);
+void mainwin_adjust_volume_release(void);
+void mainwin_adjust_balance_motion(gint b);
+void mainwin_adjust_balance_release(void);
+void mainwin_set_volume_slider(gint percent);
+void mainwin_set_balance_slider(gint percent);
+
+void mainwin_vis_set_type(VisType mode);
+
+void mainwin_refresh_hints(void);
+void mainwin_set_info_text(void);
+void mainwin_set_song_info(gint rate, gint freq, gint nch);
+void mainwin_clear_song_info(void);
+void mainwin_set_stopaftersong(gboolean stop);
+void mainwin_set_noplaylistadvance(gboolean no_advance);
+
+void mainwin_set_always_on_top(gboolean always);
+void mainwin_set_volume_diff(gint diff);
+void mainwin_set_balance_diff(gint diff);
+
+void mainwin_show(gboolean);
+void mainwin_real_show(void);
+void mainwin_real_hide(void);
+void mainwin_move(gint x, gint y);
+void mainwin_shuffle_pushed(gboolean toggled);
+void mainwin_repeat_pushed(gboolean toggled);
+void mainwin_disable_seekbar(void);
+void mainwin_set_title(const gchar * text);
+void mainwin_minimize_cb(void);
+void mainwin_general_menu_callback(gpointer cb_data,
+                                   guint action,
+                                   GtkWidget * widget);
+
+gboolean mainwin_update_song_info(void);
+void mainwin_drag_data_received(GtkWidget * widget,
+                                GdkDragContext * context,
+                                gint x,
+                                gint y,
+                                GtkSelectionData * selection_data,
+                                guint info,
+                                guint time,
+                                gpointer user_data);
+
+void mainwin_setup_menus(void);
+gboolean change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event);
+
+void mainwin_jump_to_file(void);
+void mainwin_jump_to_time(void);
+
+void mainwin_ewmh_activate(void);
+
+void mainwin_show_visibility_warning(void);
+
+/* FIXME: placed here for now */
+void playback_get_sample_params(gint * bitrate,
+                                gint * frequency,
+                                gint * numchannels);
+
+void ui_main_check_theme_engine(void);
+
+void util_menu_main_show( gint x , gint y , guint button , guint time );
+
+#endif /* AUDACIOUS_UI_MAIN_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_main_evlisteners.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,482 @@
+/*
+ * Audacious
+ * Copyright (c) 2006-2007 Audacious development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_playlist_evlisteners.h"
+
+#include <glib.h>
+#include <math.h>
+
+#include "hook.h"
+#include "playback.h"
+#include "playlist.h"
+#include "playlist_evmessages.h"
+#include "visualization.h"
+
+#include "ui_credits.h"
+#include "ui_equalizer.h"
+#include "ui_fileopener.h"
+#include "ui_urlopener.h"
+#include "ui_jumptotrack.h"
+#include "ui_main.h"
+#include "ui_playlist.h"
+#include "ui_preferences.h"
+#include "ui_skinned_playstatus.h"
+#include "ui_skinned_textbox.h"
+#include "ui_skinned_window.h"
+
+static gint song_info_timeout_source = 0;
+static gint update_vis_timeout_source = 0;
+
+/* XXX: there has to be a better way than polling here! */
+/* also: where should this function go? should it stay here? --mf0102 */
+static gboolean
+update_vis_func(gpointer unused)
+{
+    if (!playback_get_playing())
+        return FALSE;
+
+    input_update_vis(playback_get_time());
+
+    return TRUE;
+}
+
+static void
+ui_main_evlistener_title_change(gpointer hook_data, gpointer user_data)
+{
+    gchar *text = (gchar *) hook_data;
+
+    ui_skinned_textbox_set_text(mainwin_info, text);
+    playlistwin_update_list(playlist_get_active());
+}
+
+static void
+ui_main_evlistener_hide_seekbar(gpointer hook_data, gpointer user_data)
+{
+    mainwin_disable_seekbar();
+}
+
+static void
+ui_main_evlistener_volume_change(gpointer hook_data, gpointer user_data)
+{
+    gint *h_vol = (gint *) hook_data;
+    gint vl, vr, b, v;
+
+    vl = CLAMP(h_vol[0], 0, 100);
+    vr = CLAMP(h_vol[1], 0, 100);
+    v = MAX(vl, vr);
+    if (vl > vr)
+        b = (gint) rint(((gdouble) vr / vl) * 100) - 100;
+    else if (vl < vr)
+        b = 100 - (gint) rint(((gdouble) vl / vr) * 100);
+    else
+        b = 0;
+
+    mainwin_set_volume_slider(v);
+    equalizerwin_set_volume_slider(v);
+    mainwin_set_balance_slider(b);
+    equalizerwin_set_balance_slider(b);
+}
+
+static void
+ui_main_evlistener_playback_initiate(gpointer hook_data, gpointer user_data)
+{
+    playback_initiate();
+}
+
+static void
+ui_main_evlistener_playback_begin(gpointer hook_data, gpointer user_data)
+{
+    PlaylistEntry *entry = (PlaylistEntry*)hook_data;
+    g_return_if_fail(entry != NULL);
+
+    equalizerwin_load_auto_preset(entry->filename);
+    hook_call("equalizer changed", NULL);
+
+    ui_vis_clear_data(mainwin_vis);
+    ui_svis_clear_data(mainwin_svis);
+    mainwin_disable_seekbar();
+    mainwin_update_song_info();
+
+    if (cfg.player_shaded) {
+        gtk_widget_show(mainwin_stime_min);
+        gtk_widget_show(mainwin_stime_sec);
+        gtk_widget_show(mainwin_sposition);
+    } else {
+        gtk_widget_show(mainwin_minus_num);
+        gtk_widget_show(mainwin_10min_num);
+        gtk_widget_show(mainwin_min_num);
+        gtk_widget_show(mainwin_10sec_num);
+        gtk_widget_show(mainwin_sec_num);
+        gtk_widget_show(mainwin_position);
+    }
+
+    song_info_timeout_source = 
+        g_timeout_add_seconds(1, (GSourceFunc) mainwin_update_song_info, NULL);
+
+    update_vis_timeout_source =
+        g_timeout_add(10, (GSourceFunc) update_vis_func, NULL);
+
+    vis_playback_start();
+
+    ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
+}
+
+static void
+ui_main_evlistener_playback_stop(gpointer hook_data, gpointer user_data)
+{
+    if (song_info_timeout_source)
+        g_source_remove(song_info_timeout_source);
+
+    vis_playback_stop();
+    free_vis_data();
+
+    ui_skinned_playstatus_set_buffering(mainwin_playstatus, FALSE);
+}
+
+static void
+ui_main_evlistener_playback_pause(gpointer hook_data, gpointer user_data)
+{
+    ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PAUSE);
+}
+
+static void
+ui_main_evlistener_playback_unpause(gpointer hook_data, gpointer user_data)
+{
+    ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
+}
+
+static void
+ui_main_evlistener_playback_seek(gpointer hook_data, gpointer user_data)
+{
+    free_vis_data();
+}
+
+static void
+ui_main_evlistener_playback_play_file(gpointer hook_data, gpointer user_data)
+{
+    if (cfg.random_skin_on_play)
+        skin_set_random_skin();
+}
+
+static void
+ui_main_evlistener_playlist_end_reached(gpointer hook_data, gpointer user_data)
+{
+    mainwin_clear_song_info();
+
+    if (cfg.stopaftersong)
+        mainwin_set_stopaftersong(FALSE);
+}
+
+static void
+ui_main_evlistener_playlist_info_change(gpointer hook_data, gpointer user_data)
+{
+    PlaylistEventInfoChange *msg = (PlaylistEventInfoChange *) hook_data;
+
+    mainwin_set_song_info(msg->bitrate, msg->samplerate, msg->channels);
+}
+
+static void
+ui_main_evlistener_mainwin_set_always_on_top(gpointer hook_data, gpointer user_data)
+{
+    gboolean *ontop = (gboolean*)hook_data;
+    mainwin_set_always_on_top(*ontop);
+}
+
+static void
+ui_main_evlistener_mainwin_show(gpointer hook_data, gpointer user_data)
+{
+    gboolean *show = (gboolean*)hook_data;
+    mainwin_show(*show);
+}
+
+static void
+ui_main_evlistener_equalizerwin_show(gpointer hook_data, gpointer user_data)
+{
+    gboolean *show = (gboolean*)hook_data;
+    equalizerwin_show(*show);
+}
+
+static void
+ui_main_evlistener_prefswin_show(gpointer hook_data, gpointer user_data)
+{
+    gboolean *show = (gboolean*)hook_data;
+    if (*show == TRUE)
+        show_prefs_window();
+    else
+        hide_prefs_window();
+}
+
+static void
+ui_main_evlistener_aboutwin_show(gpointer hook_data, gpointer user_data)
+{
+    gboolean *show = (gboolean*)hook_data;
+    if (*show == TRUE)
+        show_about_window();
+    else
+        hide_about_window();
+}
+
+
+static void
+ui_main_evlistener_ui_jump_to_track_show(gpointer hook_data, gpointer user_data)
+{
+    gboolean *show = (gboolean*)hook_data;
+    if (*show == TRUE)
+        ui_jump_to_track();
+    else
+        ui_jump_to_track_hide();
+}
+
+static void
+ui_main_evlistener_filebrowser_show(gpointer hook_data, gpointer user_data)
+{
+    gboolean *play_button = (gboolean*)hook_data;
+    run_filebrowser(*play_button);
+}
+
+static void
+ui_main_evlistener_filebrowser_hide(gpointer hook_data, gpointer user_data)
+{
+    hide_filebrowser();
+}
+
+static void
+ui_main_evlistener_visualization_timeout(gpointer hook_data, gpointer user_data)
+{
+    if (hook_data == NULL) {
+        if (cfg.player_shaded && cfg.player_visible)
+            ui_svis_timeout_func(mainwin_svis, NULL);
+        else
+            ui_vis_timeout_func(mainwin_vis, NULL);
+        return;
+    }
+
+    VisNode *vis = (VisNode*) hook_data;
+
+    guint8 intern_vis_data[512];
+    gint16 mono_freq[2][256];
+    gboolean mono_freq_calced = FALSE;
+    gint16 mono_pcm[2][512], stereo_pcm[2][512];
+    gboolean mono_pcm_calced = FALSE, stereo_pcm_calced = FALSE;
+    gint i;
+
+    if (cfg.vis_type == VIS_OFF)
+        return;
+
+    if (cfg.vis_type == VIS_ANALYZER) {
+            /* Spectrum analyzer */
+            /* 76 values */
+            const gint long_xscale[] =
+                { 0, 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, 61, 66, 71, 76, 81, 87, 93,
+                100, 107,
+                114, 122, 131, 140, 150, 161, 172, 184, 255
+            };
+            /* 20 values */
+            const int short_xscale[] =
+                { 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 15, 20, 27,
+                36, 47, 62, 82, 107, 141, 184, 255
+            };
+            const double y_scale = 3.60673760222;   /* 20.0 / log(256) */
+            const int *xscale;
+            gint j, y, max;
+
+            if (!mono_freq_calced)
+                calc_mono_freq(mono_freq, vis->data, vis->nch);
+
+            memset(intern_vis_data, 0, 75);
+
+            if (cfg.analyzer_type == ANALYZER_BARS) {
+                if (cfg.player_shaded) {
+                    max = 13;
+                }
+                else {
+                    max = 19;
+                }
+                xscale = short_xscale;
+            }
+            else {
+                if (cfg.player_shaded) {
+                    max = 37;
+                }
+                else {
+                    max = 75;
+                }
+                xscale = long_xscale;
+            }
+
+            for (i = 0; i < max; i++) {
+                for (j = xscale[i], y = 0; j < xscale[i + 1]; j++) {
+                    if (mono_freq[0][j] > y)
+                        y = mono_freq[0][j];
+                }
+                y >>= 7;
+                if (y != 0) {
+                    intern_vis_data[i] = log(y) * y_scale;
+                    if (intern_vis_data[i] > 15)
+                        intern_vis_data[i] = 15;
+                }
+                else
+                    intern_vis_data[i] = 0;
+            }
+        
+    }
+    else if(cfg.vis_type == VIS_VOICEPRINT){
+        if (cfg.player_shaded && cfg.player_visible) {
+            /* VU */
+            gint vu, val;
+
+            if (!stereo_pcm_calced)
+                calc_stereo_pcm(stereo_pcm, vis->data, vis->nch);
+            vu = 0;
+            for (i = 0; i < 512; i++) {
+                val = abs(stereo_pcm[0][i]);
+                if (val > vu)
+                    vu = val;
+            }
+            intern_vis_data[0] = (vu * 37) >> 15;
+            if (intern_vis_data[0] > 37)
+                intern_vis_data[0] = 37;
+            if (vis->nch == 2) {
+                vu = 0;
+                for (i = 0; i < 512; i++) {
+                    val = abs(stereo_pcm[1][i]);
+                    if (val > vu)
+                        vu = val;
+                }
+                intern_vis_data[1] = (vu * 37) >> 15;
+                if (intern_vis_data[1] > 37)
+                    intern_vis_data[1] = 37;
+            }
+            else
+                intern_vis_data[1] = intern_vis_data[0];
+        }
+        else { /*Voiceprint*/
+            if (!mono_freq_calced)
+                calc_mono_freq(mono_freq, vis->data, vis->nch);
+            memset(intern_vis_data, 0, 256);
+
+            /* For the values [0-16] we use the frequency that's 3/2 as much.
+               If we assume the 512 values calculated by calc_mono_freq to
+               cover 0-22kHz linearly we get a range of
+               [0-16] * 3/2 * 22000/512 = [0-1,031] Hz.
+               Most stuff above that is harmonics and we want to utilize the
+               16 samples we have to the max[tm]
+               */
+            for (i = 0; i < 50 ; i+=3){
+                intern_vis_data[i/3] += (mono_freq[0][i/2] >> 5);
+
+                /*Boost frequencies above 257Hz a little*/
+                //if(i > 4 * 3)
+                //  intern_vis_data[i/3] += 8;
+            }
+        }
+    }
+    else { /* (cfg.vis_type == VIS_SCOPE) */
+
+        /* Oscilloscope */
+        gint pos, step;
+
+        if (!mono_pcm_calced)
+            calc_mono_pcm(mono_pcm, vis->data, vis->nch);
+
+        step = (vis->length << 8) / 74;
+        for (i = 0, pos = 0; i < 75; i++, pos += step) {
+            intern_vis_data[i] = ((mono_pcm[0][pos >> 8]) >> 12) + 7;
+            if (intern_vis_data[i] == 255)
+                intern_vis_data[i] = 0;
+            else if (intern_vis_data[i] > 12)
+                intern_vis_data[i] = 12;
+            /* Do not see the point of that? (comparison always false) -larne.
+               if (intern_vis_data[i] < 0)
+               intern_vis_data[i] = 0; */
+        }
+    }
+
+    if (cfg.player_shaded && cfg.player_visible)
+        ui_svis_timeout_func(mainwin_svis, intern_vis_data);
+    else
+        ui_vis_timeout_func(mainwin_vis, intern_vis_data);
+}
+
+static void
+ui_main_evlistener_config_save(gpointer hook_data, gpointer user_data)
+{
+    ConfigDb *db = (ConfigDb *) hook_data;
+
+    if (SKINNED_WINDOW(mainwin)->x != -1 &&
+        SKINNED_WINDOW(mainwin)->y != -1 )
+    {
+        cfg_db_set_int(db, NULL, "player_x", SKINNED_WINDOW(mainwin)->x);
+        cfg_db_set_int(db, NULL, "player_y", SKINNED_WINDOW(mainwin)->y);
+    }
+
+    cfg_db_set_bool(db, NULL, "mainwin_use_bitmapfont",
+                    cfg.mainwin_use_bitmapfont);
+}
+
+static void
+ui_main_evlistener_equalizer_changed(gpointer hook_data, gpointer user_data)
+{
+    output_set_eq(cfg.equalizer_active, cfg.equalizer_preamp,
+                  cfg.equalizer_bands);
+}
+
+static void
+ui_main_evlistener_urlopener_show(gpointer hook_data, gpointer user_data)
+{
+    show_add_url_window();
+}
+
+void
+ui_main_evlistener_init(void)
+{
+    hook_associate("title change", ui_main_evlistener_title_change, NULL);
+    hook_associate("hide seekbar", ui_main_evlistener_hide_seekbar, NULL);
+    hook_associate("volume set", ui_main_evlistener_volume_change, NULL);
+    hook_associate("playback initiate", ui_main_evlistener_playback_initiate, NULL);
+    hook_associate("playback begin", ui_main_evlistener_playback_begin, NULL);
+    hook_associate("playback stop", ui_main_evlistener_playback_stop, NULL);
+    hook_associate("playback pause", ui_main_evlistener_playback_pause, NULL);
+    hook_associate("playback unpause", ui_main_evlistener_playback_unpause, NULL);
+    hook_associate("playback seek", ui_main_evlistener_playback_seek, NULL);
+    hook_associate("playback play file", ui_main_evlistener_playback_play_file, NULL);
+    hook_associate("playlist end reached", ui_main_evlistener_playlist_end_reached, NULL);
+    hook_associate("playlist info change", ui_main_evlistener_playlist_info_change, NULL);
+    hook_associate("mainwin set always on top", ui_main_evlistener_mainwin_set_always_on_top, NULL);
+    hook_associate("mainwin show", ui_main_evlistener_mainwin_show, NULL);
+    hook_associate("equalizerwin show", ui_main_evlistener_equalizerwin_show, NULL);
+    hook_associate("prefswin show", ui_main_evlistener_prefswin_show, NULL);
+    hook_associate("aboutwin show", ui_main_evlistener_aboutwin_show, NULL);
+    hook_associate("ui jump to track show", ui_main_evlistener_ui_jump_to_track_show, NULL);
+    hook_associate("filebrowser show", ui_main_evlistener_filebrowser_show, NULL);
+    hook_associate("filebrowser hide", ui_main_evlistener_filebrowser_hide, NULL);
+    hook_associate("visualization timeout", ui_main_evlistener_visualization_timeout, NULL);
+    hook_associate("config save", ui_main_evlistener_config_save, NULL);
+    hook_associate("urlopener show", ui_main_evlistener_urlopener_show, NULL);
+
+    hook_associate("equalizer changed", ui_main_evlistener_equalizer_changed, NULL);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_main_evlisteners.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,28 @@
+/*
+ * Audacious
+ * Copyright (c) 2006-2007 Audacious development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include <glib.h>
+
+#ifndef AUDACIOUS_UI_MAIN_EVLISTENERS_H
+#define AUDACIOUS_UI_MAIN_EVLISTENERS_H
+
+void ui_main_evlistener_init(void);
+
+#endif /* AUDACIOUS_UI_MAIN_EVLISTENERS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_manager.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,872 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "ui_manager.h"
+#include "actions-mainwin.h"
+#include "actions-playlist.h"
+#include "actions-equalizer.h"
+
+/* this header contains prototypes for plugin-available menu functions */
+#include "ui_plugin_menu.h"
+
+/* TODO ui_main.h is only included because ui_manager.c needs the values of
+   TimerMode enum; move that enum elsewhere so we can get rid of this include */
+#include "ui_main.h"
+
+#include "icons-stock.h"
+
+#include "sync-menu.h"
+
+static GtkUIManager *ui_manager = NULL;
+static gboolean menu_created = FALSE;
+
+
+/* toggle action entries */
+
+static GtkToggleActionEntry toggleaction_entries_others[] = {
+
+	{ "autoscroll songname", NULL , N_("Autoscroll Songname"), NULL,
+	  N_("Autoscroll Songname"), G_CALLBACK(action_autoscroll_songname) , FALSE },
+
+	{ "stop after current song", NULL , N_("Stop after Current Song"), "<Ctrl>M",
+	  N_("Stop after Current Song"), G_CALLBACK(action_stop_after_current_song) , FALSE },
+
+	{ "anamode peaks", NULL , N_("Peaks"), NULL,
+	  N_("Peaks"), G_CALLBACK(action_anamode_peaks) , FALSE },
+
+	{ "playback repeat", NULL , N_("Repeat"), "R",
+	  N_("Repeat"), G_CALLBACK(action_playback_repeat) , FALSE },
+
+	{ "playback shuffle", NULL , N_("Shuffle"), "S",
+	  N_("Shuffle"), G_CALLBACK(action_playback_shuffle) , FALSE },
+
+	{ "playback no playlist advance", NULL , N_("No Playlist Advance"), "<Ctrl>N",
+	  N_("No Playlist Advance"), G_CALLBACK(action_playback_noplaylistadvance) , FALSE },
+
+	{ "show player", NULL , N_("Show Player"), "<Alt>M",
+	  N_("Show Player"), G_CALLBACK(action_show_player) , FALSE },
+
+	{ "show playlist editor", NULL , N_("Show Playlist Editor"), "<Alt>E",
+	  N_("Show Playlist Editor"), G_CALLBACK(action_show_playlist_editor) , FALSE },
+
+	{ "show equalizer", NULL , N_("Show Equalizer"), "<Alt>G",
+	  N_("Show Equalizer"), G_CALLBACK(action_show_equalizer) , FALSE },
+
+	{ "view always on top", NULL , N_("Always on Top"), "<Ctrl>O",
+	  N_("Always on Top"), G_CALLBACK(action_view_always_on_top) , FALSE },
+
+	{ "view put on all workspaces", NULL , N_("Put on All Workspaces"), "<Ctrl>S",
+	  N_("Put on All Workspaces"), G_CALLBACK(action_view_on_all_workspaces) , FALSE },
+
+	{ "roll up player", NULL , N_("Roll up Player"), "<Ctrl>W",
+	  N_("Roll up Player"), G_CALLBACK(action_roll_up_player) , FALSE },
+
+	{ "roll up playlist editor", NULL , N_("Roll up Playlist Editor"), "<Shift><Ctrl>W",
+	  N_("Roll up Playlist Editor"), G_CALLBACK(action_roll_up_playlist_editor) , FALSE },
+
+	{ "roll up equalizer", NULL , N_("Roll up Equalizer"), "<Ctrl><Alt>W",
+	  N_("Roll up Equalizer"), G_CALLBACK(action_roll_up_equalizer) , FALSE },
+
+	{ "view scaled", NULL , N_("Scale"), "<Ctrl>D",
+	  N_("DoubleSize"), G_CALLBACK(action_view_scaled) , FALSE },
+
+	{ "view easy move", NULL , N_("Easy Move"), "<Ctrl>E",
+	  N_("Easy Move"), G_CALLBACK(action_view_easymove) , FALSE }
+};
+
+
+
+/* radio action entries */
+
+static GtkRadioActionEntry radioaction_entries_vismode[] = {
+	{ "vismode analyzer", NULL , N_("Analyzer"), NULL, N_("Analyzer"), VIS_ANALYZER },
+	{ "vismode scope", NULL , N_("Scope"), NULL, N_("Scope"), VIS_SCOPE },
+	{ "vismode voiceprint", NULL , N_("Voiceprint"), NULL, N_("Voiceprint"), VIS_VOICEPRINT },
+	{ "vismode off", NULL , N_("Off"), NULL, N_("Off"), VIS_OFF }
+};
+
+static GtkRadioActionEntry radioaction_entries_anamode[] = {
+	{ "anamode normal", NULL , N_("Normal"), NULL, N_("Normal"), ANALYZER_NORMAL },
+	{ "anamode fire", NULL , N_("Fire"), NULL, N_("Fire"), ANALYZER_FIRE },
+	{ "anamode vertical lines", NULL , N_("Vertical Lines"), NULL, N_("Vertical Lines"), ANALYZER_VLINES }
+};
+
+static GtkRadioActionEntry radioaction_entries_anatype[] = {
+	{ "anatype lines", NULL , N_("Lines"), NULL, N_("Lines"), ANALYZER_LINES },
+	{ "anatype bars", NULL , N_("Bars"), NULL, N_("Bars"), ANALYZER_BARS }
+};
+
+static GtkRadioActionEntry radioaction_entries_scomode[] = {
+	{ "scomode dot", NULL , N_("Dot Scope"), NULL, N_("Dot Scope"), SCOPE_DOT },
+	{ "scomode line", NULL , N_("Line Scope"), NULL, N_("Line Scope"), SCOPE_LINE },
+	{ "scomode solid", NULL , N_("Solid Scope"), NULL, N_("Solid Scope"), SCOPE_SOLID }
+};
+
+static GtkRadioActionEntry radioaction_entries_vprmode[] = {
+	{ "vprmode normal", NULL , N_("Normal"), NULL, N_("Normal"), VOICEPRINT_NORMAL },
+	{ "vprmode fire", NULL , N_("Fire"), NULL, N_("Fire"), VOICEPRINT_FIRE },
+	{ "vprmode ice", NULL , N_("Ice"), NULL, N_("Ice"), VOICEPRINT_ICE }
+};
+
+static GtkRadioActionEntry radioaction_entries_wshmode[] = {
+	{ "wshmode normal", NULL , N_("Normal"), NULL, N_("Normal"), VU_NORMAL },
+	{ "wshmode smooth", NULL , N_("Smooth"), NULL, N_("Smooth"), VU_SMOOTH }
+};
+
+static GtkRadioActionEntry radioaction_entries_refrate[] = {
+	{ "refrate full", NULL , N_("Full (~50 fps)"), NULL, N_("Full (~50 fps)"), REFRESH_FULL },
+	{ "refrate half", NULL , N_("Half (~25 fps)"), NULL, N_("Half (~25 fps)"), REFRESH_HALF },
+	{ "refrate quarter", NULL , N_("Quarter (~13 fps)"), NULL, N_("Quarter (~13 fps)"), REFRESH_QUARTER },
+	{ "refrate eighth", NULL , N_("Eighth (~6 fps)"), NULL, N_("Eighth (~6 fps)"), REFRESH_EIGTH }
+};
+
+static GtkRadioActionEntry radioaction_entries_anafoff[] = {
+	{ "anafoff slowest", NULL , N_("Slowest"), NULL, N_("Slowest"), FALLOFF_SLOWEST },
+	{ "anafoff slow", NULL , N_("Slow"), NULL, N_("Slow"), FALLOFF_SLOW },
+	{ "anafoff medium", NULL , N_("Medium"), NULL, N_("Medium"), FALLOFF_MEDIUM },
+	{ "anafoff fast", NULL , N_("Fast"), NULL, N_("Fast"), FALLOFF_FAST },
+	{ "anafoff fastest", NULL , N_("Fastest"), NULL, N_("Fastest"), FALLOFF_FASTEST }
+};
+
+static GtkRadioActionEntry radioaction_entries_peafoff[] = {
+	{ "peafoff slowest", NULL , N_("Slowest"), NULL, N_("Slowest"), FALLOFF_SLOWEST },
+	{ "peafoff slow", NULL , N_("Slow"), NULL, N_("Slow"), FALLOFF_SLOW },
+	{ "peafoff medium", NULL , N_("Medium"), NULL, N_("Medium"), FALLOFF_MEDIUM },
+	{ "peafoff fast", NULL , N_("Fast"), NULL, N_("Fast"), FALLOFF_FAST },
+	{ "peafoff fastest", NULL , N_("Fastest"), NULL, N_("Fastest"), FALLOFF_FASTEST }
+};
+
+static GtkRadioActionEntry radioaction_entries_viewtime[] = {
+	{ "view time elapsed", NULL , N_("Time Elapsed"), "<Ctrl>E", N_("Time Elapsed"), TIMER_ELAPSED },
+	{ "view time remaining", NULL , N_("Time Remaining"), "<Ctrl>R", N_("Time Remaining"), TIMER_REMAINING }
+};
+
+
+
+/* normal actions */
+
+static GtkActionEntry action_entries_playback[] = {
+
+	{ "playback", NULL, N_("Playback") },
+	
+	{ "playback play", GTK_STOCK_MEDIA_PLAY , N_("Play"), "X",
+	  N_("Play"), G_CALLBACK(action_playback_play) },
+
+	{ "playback pause", GTK_STOCK_MEDIA_PAUSE , N_("Pause"), "C",
+	  N_("Pause"), G_CALLBACK(action_playback_pause) },
+
+	{ "playback stop", GTK_STOCK_MEDIA_STOP , N_("Stop"), "V",
+	  N_("Stop"), G_CALLBACK(action_playback_stop) },
+
+	{ "playback previous", GTK_STOCK_MEDIA_PREVIOUS , N_("Previous"), "Z",
+	  N_("Previous"), G_CALLBACK(action_playback_previous) },
+
+	{ "playback next", GTK_STOCK_MEDIA_NEXT , N_("Next"), "B",
+	  N_("Next"), G_CALLBACK(action_playback_next) }
+};
+
+
+static GtkActionEntry action_entries_visualization[] = {
+	{ "visualization", NULL, N_("Visualization") },
+	{ "vismode", NULL, N_("Visualization Mode") },
+	{ "anamode", NULL, N_("Analyzer Mode") },
+	{ "scomode", NULL, N_("Scope Mode") },
+	{ "vprmode", NULL, N_("Voiceprint Mode") },
+	{ "wshmode", NULL, N_("WindowShade VU Mode") },
+	{ "refrate", NULL, N_("Refresh Rate") },
+	{ "anafoff", NULL, N_("Analyzer Falloff") },
+	{ "peafoff", NULL, N_("Peaks Falloff") }
+};
+
+static GtkActionEntry action_entries_playlist[] = {
+
+	{ "playlist", NULL, N_("Playlist") },
+
+	{ "playlist new", GTK_STOCK_NEW , N_("New Playlist"), "<Shift>N",
+	  N_("New Playlist"), G_CALLBACK(action_playlist_new) },
+
+	{ "playlist select next", GTK_STOCK_MEDIA_NEXT, N_("Select Next Playlist"), "<Shift>P",
+	  N_("Select Next Playlist"), G_CALLBACK(action_playlist_next) },
+
+	{ "playlist select previous", GTK_STOCK_MEDIA_PREVIOUS, N_("Select Previous Playlist"), "<Shift><Ctrl>P",
+	  N_("Select Previous Playlist"), G_CALLBACK(action_playlist_prev) },
+
+	{ "playlist delete", GTK_STOCK_DELETE , N_("Delete Playlist"), "<Shift>D",
+	  N_("Delete Playlist"), G_CALLBACK(action_playlist_delete) },
+
+        { "playlist load", GTK_STOCK_OPEN, N_("Load List"), "O",
+          N_("Loads a playlist file into the selected playlist."), G_CALLBACK(action_playlist_load_list) },
+
+        { "playlist save", GTK_STOCK_SAVE, N_("Save List"), "<Shift>S",
+          N_("Saves the selected playlist."), G_CALLBACK(action_playlist_save_list) },
+
+        { "playlist save default", GTK_STOCK_SAVE, N_("Save Default List"), "<Alt>S",
+          N_("Saves the selected playlist to the default location."),
+          G_CALLBACK(action_playlist_save_default_list) },
+
+        { "playlist refresh", GTK_STOCK_REFRESH, N_("Refresh List"), "F5",
+          N_("Refreshes metadata associated with a playlist entry."),
+          G_CALLBACK(action_playlist_refresh_list) },
+
+        { "playlist manager", AUD_STOCK_PLAYLIST , N_("List Manager"), "P",
+          N_("Opens the playlist manager."),
+          G_CALLBACK(action_open_list_manager) }
+};
+
+static GtkActionEntry action_entries_view[] = {
+
+	{ "view", NULL, N_("View") }
+};
+
+static GtkActionEntry action_entries_playlist_add[] = {
+        { "playlist add url", GTK_STOCK_NETWORK, N_("Add Internet Address..."), "<Ctrl>H",
+          N_("Adds a remote track to the playlist."),
+          G_CALLBACK(action_playlist_add_url) },
+
+        { "playlist add files", GTK_STOCK_ADD, N_("Add Files..."), "F",
+          N_("Adds files to the playlist."),
+          G_CALLBACK(action_playlist_add_files) },
+};
+
+static GtkActionEntry action_entries_playlist_select[] = {
+        { "playlist search and select", GTK_STOCK_FIND, N_("Search and Select"), "<Ctrl>F",
+          N_("Searches the playlist and selects playlist entries based on specific criteria."),
+          G_CALLBACK(action_playlist_search_and_select) },
+
+        { "playlist invert selection", NULL , N_("Invert Selection"), NULL,
+          N_("Inverts the selected and unselected entries."),
+          G_CALLBACK(action_playlist_invert_selection) },
+
+        { "playlist select all", NULL , N_("Select All"), "<Ctrl>A",
+          N_("Selects all of the playlist entries."),
+          G_CALLBACK(action_playlist_select_all) },
+
+        { "playlist select none", NULL , N_("Select None"), "<Shift><Ctrl>A",
+          N_("Deselects all of the playlist entries."),
+          G_CALLBACK(action_playlist_select_none) },
+};
+
+static GtkActionEntry action_entries_playlist_delete[] = {
+	{ "playlist remove all", GTK_STOCK_CLEAR, N_("Remove All"), NULL, 
+	  N_("Removes all entries from the playlist."),
+	  G_CALLBACK(action_playlist_remove_all) },
+
+	{ "playlist clear queue", GTK_STOCK_CLEAR, N_("Clear Queue"), "<Shift>Q",
+	  N_("Clears the queue associated with this playlist."),
+	  G_CALLBACK(action_playlist_clear_queue) },
+
+	{ "playlist remove unavailable", GTK_STOCK_DIALOG_ERROR , N_("Remove Unavailable Files"), NULL,
+	  N_("Removes unavailable files from the playlist."),
+	  G_CALLBACK(action_playlist_remove_unavailable) },
+
+	{ "playlist remove dups menu", NULL , N_("Remove Duplicates") },
+
+	{ "playlist remove dups by title", NULL , N_("By Title"), NULL,
+	  N_("Removes duplicate entries from the playlist by title."),
+	  G_CALLBACK(action_playlist_remove_dupes_by_title) },
+
+	{ "playlist remove dups by filename", NULL , N_("By Filename"), NULL, 
+	  N_("Removes duplicate entries from the playlist by filename."),
+	  G_CALLBACK(action_playlist_remove_dupes_by_filename) },
+
+	{ "playlist remove dups by full path", NULL , N_("By Path + Filename"), NULL, 
+	  N_("Removes duplicate entries from the playlist by their full path."),
+	  G_CALLBACK(action_playlist_remove_dupes_by_full_path) },
+
+	{ "playlist remove unselected", GTK_STOCK_REMOVE, N_("Remove Unselected"), NULL,
+	  N_("Remove unselected entries from the playlist."),
+	  G_CALLBACK(action_playlist_remove_unselected) },
+
+	{ "playlist remove selected", GTK_STOCK_REMOVE, N_("Remove Selected"), "Delete", 
+	  N_("Remove selected entries from the playlist."),
+	  G_CALLBACK(action_playlist_remove_selected) },
+};
+
+static GtkActionEntry action_entries_playlist_sort[] = {
+	{ "playlist randomize list", AUD_STOCK_RANDOMIZEPL , N_("Randomize List"), "<Ctrl><Shift>R",
+	  N_("Randomizes the playlist."),
+	  G_CALLBACK(action_playlist_randomize_list) },
+
+	{ "playlist reverse list", GTK_STOCK_GO_UP , N_("Reverse List"), NULL,
+	  N_("Reverses the playlist."),
+	  G_CALLBACK(action_playlist_reverse_list) },
+
+	{ "playlist sort menu", GTK_STOCK_GO_DOWN , N_("Sort List") },
+
+	{ "playlist sort by title", NULL , N_("By Title"), NULL,
+	  N_("Sorts the list by title."),
+	  G_CALLBACK(action_playlist_sort_by_title) },
+
+	{ "playlist sort by artist", NULL , N_("By Artist"), NULL,
+	  N_("Sorts the list by artist."),
+	  G_CALLBACK(action_playlist_sort_by_artist) },
+
+	{ "playlist sort by filename", NULL , N_("By Filename"), NULL,
+	  N_("Sorts the list by filename."),
+	  G_CALLBACK(action_playlist_sort_by_filename) },
+
+	{ "playlist sort by full path", NULL , N_("By Path + Filename"), NULL,
+	  N_("Sorts the list by full pathname."),
+	  G_CALLBACK(action_playlist_sort_by_full_path) },
+
+	{ "playlist sort by date", NULL , N_("By Date"), NULL,
+	  N_("Sorts the list by modification time."),
+	  G_CALLBACK(action_playlist_sort_by_date) },
+
+	{ "playlist sort by track number", NULL , N_("By Track Number"), NULL,
+	  N_("Sorts the list by track number."),
+	  G_CALLBACK(action_playlist_sort_by_track_number) },
+
+	{ "playlist sort by playlist entry", NULL , N_("By Playlist Entry"), NULL,
+	  N_("Sorts the list by playlist entry."),
+	  G_CALLBACK(action_playlist_sort_by_playlist_entry) },
+
+	{ "playlist sort selected menu", GTK_STOCK_GO_DOWN , N_("Sort Selected") },
+
+	{ "playlist sort selected by title", NULL , N_("By Title"), NULL,
+	  N_("Sorts the list by title."),
+	  G_CALLBACK(action_playlist_sort_selected_by_title) },
+
+	{ "playlist sort selected by artist", NULL, N_("By Artist"), NULL,
+	  N_("Sorts the list by artist."),
+	  G_CALLBACK(action_playlist_sort_selected_by_artist) },
+
+	{ "playlist sort selected by filename", NULL , N_("By Filename"), NULL,
+	  N_("Sorts the list by filename."),
+	  G_CALLBACK(action_playlist_sort_selected_by_filename) },
+
+	{ "playlist sort selected by full path", NULL , N_("By Path + Filename"), NULL,
+	  N_("Sorts the list by full pathname."),
+	  G_CALLBACK(action_playlist_sort_selected_by_full_path) },
+
+	{ "playlist sort selected by date", NULL , N_("By Date"), NULL,
+	  N_("Sorts the list by modification time."),
+	  G_CALLBACK(action_playlist_sort_selected_by_date) },
+
+	{ "playlist sort selected by track number", NULL , N_("By Track Number"), NULL,
+	  N_("Sorts the list by track number."),
+	  G_CALLBACK(action_playlist_sort_selected_by_track_number) },
+
+	{ "playlist sort selected by playlist entry", NULL, N_("By Playlist Entry"), NULL,
+	  N_("Sorts the list by playlist entry."),
+	  G_CALLBACK(action_playlist_sort_selected_by_playlist_entry) },
+};
+
+static GtkActionEntry action_entries_others[] = {
+
+	{ "dummy", NULL, "dummy" },
+
+        /* XXX Carbon support */
+        { "file", NULL, N_("File") },
+        { "help", NULL, N_("Help") },
+
+	{ "plugins-menu", AUD_STOCK_PLUGIN, N_("Plugin Services") },
+
+	{ "current track info", GTK_STOCK_INFO , N_("View Track Details"), "I",
+	  N_("View track details"), G_CALLBACK(action_current_track_info) },
+
+	{ "playlist track info", GTK_STOCK_INFO , N_("View Track Details"), "<Alt>I",
+	  N_("View track details"), G_CALLBACK(action_playlist_track_info) },
+
+	{ "about audacious", GTK_STOCK_DIALOG_INFO , N_("About Audacious"), NULL,
+	  N_("About Audacious"), G_CALLBACK(action_about_audacious) },
+
+	{ "play file", GTK_STOCK_OPEN , N_("Play File"), "L",
+	  N_("Load and play a file"), G_CALLBACK(action_play_file) },
+
+	{ "play location", GTK_STOCK_NETWORK , N_("Play Location"), "<Ctrl>L",
+	  N_("Play media from the selected location"), G_CALLBACK(action_play_location) },
+
+    { "plugins", NULL , N_("Plugin services") },
+
+	{ "preferences", GTK_STOCK_PREFERENCES , N_("Preferences"), "<Ctrl>P",
+	  N_("Open preferences window"), G_CALLBACK(action_preferences) },
+
+	{ "quit", GTK_STOCK_QUIT , N_("_Quit"), NULL,
+	  N_("Quit Audacious"), G_CALLBACK(action_quit) },
+
+	{ "ab set", NULL , N_("Set A-B"), "A",
+	  N_("Set A-B"), G_CALLBACK(action_ab_set) },
+
+	{ "ab clear", NULL , N_("Clear A-B"), "<Shift>A",
+	  N_("Clear A-B"), G_CALLBACK(action_ab_clear) },
+
+	{ "jump to playlist start", GTK_STOCK_GOTO_TOP , N_("Jump to Playlist Start"), "<Ctrl>Z",
+	  N_("Jump to Playlist Start"), G_CALLBACK(action_jump_to_playlist_start) },
+
+	{ "jump to file", GTK_STOCK_JUMP_TO , N_("Jump to File"), "J",
+	  N_("Jump to File"), G_CALLBACK(action_jump_to_file) },
+
+	{ "jump to time", GTK_STOCK_JUMP_TO , N_("Jump to Time"), "<Ctrl>J",
+	  N_("Jump to Time"), G_CALLBACK(action_jump_to_time) },
+
+	{ "queue toggle", AUD_STOCK_QUEUETOGGLE , N_("Queue Toggle"), "Q", 
+	  N_("Enables/disables the entry in the playlist's queue."),
+	  G_CALLBACK(action_queue_toggle) },
+};
+
+
+static GtkActionEntry action_entries_equalizer[] = {
+
+    { "equ preset load menu", NULL, N_("Load") },
+    { "equ preset import menu", NULL, N_("Import") },
+    { "equ preset save menu", NULL, N_("Save") },
+    { "equ preset delete menu", NULL, N_("Delete") },
+
+    { "equ load preset", NULL, N_("Preset"), NULL,
+      N_("Load preset"), G_CALLBACK(action_equ_load_preset) },
+
+    { "equ load auto preset", NULL, N_("Auto-load preset"), NULL,
+      N_("Load auto-load preset"), G_CALLBACK(action_equ_load_auto_preset) },
+
+    { "equ load default preset", NULL, N_("Default"), NULL,
+      N_("Load default preset into equalizer"), G_CALLBACK(action_equ_load_default_preset) },
+
+    { "equ zero preset", NULL, N_("Zero"), NULL,
+      N_("Set equalizer preset levels to zero"), G_CALLBACK(action_equ_zero_preset) },
+
+    { "equ load preset file", NULL, N_("From file"), NULL,
+      N_("Load preset from file"), G_CALLBACK(action_equ_load_preset_file) },
+
+    { "equ load preset eqf", NULL, N_("From WinAMP EQF file"), NULL,
+      N_("Load preset from WinAMP EQF file"), G_CALLBACK(action_equ_load_preset_eqf) },
+
+    { "equ import winamp presets", NULL, N_("WinAMP Presets"), NULL,
+      N_("Import WinAMP presets"), G_CALLBACK(action_equ_import_winamp_presets) },
+
+    { "equ save preset", NULL, N_("Preset"), NULL,
+      N_("Save preset"), G_CALLBACK(action_equ_save_preset) },
+
+    { "equ save auto preset", NULL, N_("Auto-load preset"), NULL,
+      N_("Save auto-load preset"), G_CALLBACK(action_equ_save_auto_preset) },
+
+    { "equ save default preset", NULL, N_("Default"), NULL,
+      N_("Save default preset"), G_CALLBACK(action_equ_save_default_preset) },
+
+    { "equ save preset file", NULL, N_("To file"), NULL,
+      N_("Save preset to file"), G_CALLBACK(action_equ_save_preset_file) },
+
+    { "equ save preset eqf", NULL, N_("To WinAMP EQF file"), NULL,
+      N_("Save preset to WinAMP EQF file"), G_CALLBACK(action_equ_save_preset_eqf) },
+
+    { "equ delete preset", NULL, N_("Preset"), NULL,
+      N_("Delete preset"), G_CALLBACK(action_equ_delete_preset) },
+
+    { "equ delete auto preset", NULL, N_("Auto-load preset"), NULL,
+      N_("Delete auto-load preset"), G_CALLBACK(action_equ_delete_auto_preset) }
+};
+
+
+
+/* ***************************** */
+
+
+static GtkActionGroup *
+ui_manager_new_action_group( const gchar * group_name )
+{
+  GtkActionGroup *group = gtk_action_group_new( group_name );
+  gtk_action_group_set_translation_domain( group , PACKAGE_NAME );
+  return group;
+}
+
+void
+ui_manager_init ( void )
+{
+  /* toggle actions */
+  toggleaction_group_others = ui_manager_new_action_group("toggleaction_others");
+  gtk_action_group_add_toggle_actions(
+    toggleaction_group_others , toggleaction_entries_others ,
+    G_N_ELEMENTS(toggleaction_entries_others) , NULL );
+
+  /* radio actions */
+  radioaction_group_anamode = ui_manager_new_action_group("radioaction_anamode");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_anamode , radioaction_entries_anamode ,
+    G_N_ELEMENTS(radioaction_entries_anamode) , 0 , G_CALLBACK(action_anamode) , NULL );
+
+  radioaction_group_anatype = ui_manager_new_action_group("radioaction_anatype");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_anatype , radioaction_entries_anatype ,
+    G_N_ELEMENTS(radioaction_entries_anatype) , 0 , G_CALLBACK(action_anatype) , NULL );
+
+  radioaction_group_scomode = ui_manager_new_action_group("radioaction_scomode");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_scomode , radioaction_entries_scomode ,
+    G_N_ELEMENTS(radioaction_entries_scomode) , 0 , G_CALLBACK(action_scomode) , NULL );
+
+  radioaction_group_vprmode = ui_manager_new_action_group("radioaction_vprmode");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_vprmode , radioaction_entries_vprmode ,
+    G_N_ELEMENTS(radioaction_entries_vprmode) , 0 , G_CALLBACK(action_vprmode) , NULL );
+
+  radioaction_group_wshmode = ui_manager_new_action_group("radioaction_wshmode");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_wshmode , radioaction_entries_wshmode ,
+    G_N_ELEMENTS(radioaction_entries_wshmode) , 0 , G_CALLBACK(action_wshmode) , NULL );
+
+  radioaction_group_refrate = ui_manager_new_action_group("radioaction_refrate");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_refrate , radioaction_entries_refrate ,
+    G_N_ELEMENTS(radioaction_entries_refrate) , 0 , G_CALLBACK(action_refrate) , NULL );
+
+  radioaction_group_anafoff = ui_manager_new_action_group("radioaction_anafoff");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_anafoff , radioaction_entries_anafoff ,
+    G_N_ELEMENTS(radioaction_entries_anafoff) , 0 , G_CALLBACK(action_anafoff) , NULL );
+
+  radioaction_group_peafoff = ui_manager_new_action_group("radioaction_peafoff");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_peafoff , radioaction_entries_peafoff ,
+    G_N_ELEMENTS(radioaction_entries_peafoff) , 0 , G_CALLBACK(action_peafoff) , NULL );
+
+  radioaction_group_vismode = ui_manager_new_action_group("radioaction_vismode");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_vismode , radioaction_entries_vismode ,
+    G_N_ELEMENTS(radioaction_entries_vismode) , 0 , G_CALLBACK(action_vismode) , NULL );
+
+  radioaction_group_viewtime = ui_manager_new_action_group("radioaction_viewtime");
+  gtk_action_group_add_radio_actions(
+    radioaction_group_viewtime , radioaction_entries_viewtime ,
+    G_N_ELEMENTS(radioaction_entries_viewtime) , 0 , G_CALLBACK(action_viewtime) , NULL );
+
+  /* normal actions */
+  action_group_playback = ui_manager_new_action_group("action_playback");
+    gtk_action_group_add_actions(
+    action_group_playback , action_entries_playback ,
+    G_N_ELEMENTS(action_entries_playback) , NULL );
+
+  action_group_playlist = ui_manager_new_action_group("action_playlist");
+    gtk_action_group_add_actions(
+    action_group_playlist , action_entries_playlist ,
+    G_N_ELEMENTS(action_entries_playlist) , NULL );
+
+  action_group_visualization = ui_manager_new_action_group("action_visualization");
+    gtk_action_group_add_actions(
+    action_group_visualization , action_entries_visualization ,
+    G_N_ELEMENTS(action_entries_visualization) , NULL );
+
+  action_group_view = ui_manager_new_action_group("action_view");
+    gtk_action_group_add_actions(
+    action_group_view , action_entries_view ,
+    G_N_ELEMENTS(action_entries_view) , NULL );
+
+  action_group_others = ui_manager_new_action_group("action_others");
+    gtk_action_group_add_actions(
+    action_group_others , action_entries_others ,
+    G_N_ELEMENTS(action_entries_others) , NULL );
+
+  action_group_playlist_add = ui_manager_new_action_group("action_playlist_add");
+  gtk_action_group_add_actions(
+    action_group_playlist_add, action_entries_playlist_add,
+    G_N_ELEMENTS(action_entries_playlist_add), NULL );
+
+  action_group_playlist_select = ui_manager_new_action_group("action_playlist_select");
+  gtk_action_group_add_actions(
+    action_group_playlist_select, action_entries_playlist_select,
+    G_N_ELEMENTS(action_entries_playlist_select), NULL );
+
+  action_group_playlist_delete = ui_manager_new_action_group("action_playlist_delete");
+  gtk_action_group_add_actions(
+    action_group_playlist_delete, action_entries_playlist_delete,
+    G_N_ELEMENTS(action_entries_playlist_delete), NULL );
+
+  action_group_playlist_sort = ui_manager_new_action_group("action_playlist_sort");
+  gtk_action_group_add_actions(
+    action_group_playlist_sort, action_entries_playlist_sort,
+    G_N_ELEMENTS(action_entries_playlist_sort), NULL );
+
+  action_group_equalizer = ui_manager_new_action_group("action_equalizer");
+  gtk_action_group_add_actions(
+    action_group_equalizer, action_entries_equalizer,
+    G_N_ELEMENTS(action_entries_equalizer), NULL);
+
+  /* ui */
+  ui_manager = gtk_ui_manager_new();
+  gtk_ui_manager_insert_action_group( ui_manager , toggleaction_group_others , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_anamode , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_anatype , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_scomode , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_vprmode , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_wshmode , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_refrate , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_anafoff , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_peafoff , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_vismode , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_viewtime , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_playback , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_visualization , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_view , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_others , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_add , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_select , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_delete , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_sort , 0 );
+  gtk_ui_manager_insert_action_group( ui_manager , action_group_equalizer , 0 );
+
+  return;
+}
+
+#ifdef GDK_WINDOWING_QUARTZ
+static GtkWidget *carbon_menubar;
+#endif
+
+static void
+ui_manager_create_menus_init_pmenu( gchar * path )
+{
+  GtkWidget *plugins_menu_item = gtk_ui_manager_get_widget( ui_manager , path );
+  if ( plugins_menu_item )
+  {
+    /* initially set count of items under plugins_menu_item to 0 */
+    g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(0) );
+    /* and since it's 0, hide the plugins_menu_item */
+    gtk_widget_hide( plugins_menu_item );
+  }
+  return;
+}
+
+
+void
+ui_manager_create_menus ( void )
+{
+  GError *gerr = NULL;
+
+  /* attach xml menu definitions */
+  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/mainwin.ui" , &gerr );
+
+  if ( gerr != NULL )
+  {
+    g_critical( "Error creating UI<ui/mainwin.ui>: %s" , gerr->message );
+    g_error_free( gerr );
+    return;
+  }
+
+  /* create GtkMenu widgets using path from xml definitions */
+  mainwin_songname_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/songname-menu" );
+  mainwin_visualization_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/visualization" );
+  mainwin_playback_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/playback" );
+  mainwin_playlist_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/playlist" );
+  mainwin_view_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/view" );
+  mainwin_general_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu" );
+
+  /* initialize plugins-menu for mainwin-menus */
+  ui_manager_create_menus_init_pmenu( "/mainwin-menus/main-menu/plugins-menu" );
+
+#ifdef GDK_WINDOWING_QUARTZ
+  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/carbon-menubar.ui" , &gerr );
+
+  if ( gerr != NULL )
+  {
+    g_critical( "Error creating UI<ui/carbon-menubar.ui>: %s" , gerr->message );
+    g_error_free( gerr );
+    return;
+  }
+
+  carbon_menubar = ui_manager_get_popup_menu( ui_manager , "/carbon-menubar/main-menu" );
+  sync_menu_takeover_menu(GTK_MENU_SHELL(carbon_menubar));
+#endif
+
+  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/playlist.ui" , &gerr );
+
+  if ( gerr != NULL )
+  {
+    g_critical( "Error creating UI<ui/playlist.ui>: %s" , gerr->message );
+    g_error_free( gerr );
+    return;
+  }
+
+  playlistwin_popup_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/playlist-rightclick-menu");
+
+  playlistwin_pladd_menu  = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/add-menu");
+  playlistwin_pldel_menu  = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/del-menu");
+  playlistwin_plsel_menu  = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/select-menu");
+  playlistwin_plsort_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/misc-menu");
+  playlistwin_pllist_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/playlist-menu");
+
+  /* initialize plugins-menu for playlist-menus */
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/playlist-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/add-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/del-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/select-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/misc-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/playlist-rightclick-menu/plugins-menu" );
+
+  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/equalizer.ui" , &gerr );
+
+  if ( gerr != NULL )
+  {
+    g_critical( "Error creating UI<ui/equalizer.ui>: %s" , gerr->message );
+    g_error_free( gerr );
+    return;
+  }
+
+  equalizerwin_presets_menu = ui_manager_get_popup_menu(ui_manager, "/equalizer-menus/preset-menu");
+
+  menu_created = TRUE;
+
+  return;
+}
+
+
+GtkAccelGroup *
+ui_manager_get_accel_group ( void )
+{
+  return gtk_ui_manager_get_accel_group( ui_manager );
+}
+
+
+GtkWidget *
+ui_manager_get_popup_menu ( GtkUIManager * self , const gchar * path )
+{
+  GtkWidget *menu_item = gtk_ui_manager_get_widget( self , path );
+
+  if (GTK_IS_MENU_ITEM(menu_item))
+    return gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item));
+  else
+    return NULL;
+}
+
+
+static void
+menu_popup_pos_func (GtkMenu * menu , gint * x , gint * y , gboolean * push_in , gint * point )
+{
+  GtkRequisition requisition;
+  gint screen_width;
+  gint screen_height;
+
+  gtk_widget_size_request(GTK_WIDGET(menu), &requisition);
+
+  screen_width = gdk_screen_width();
+  screen_height = gdk_screen_height();
+
+  *x = CLAMP(point[0] - 2, 0, MAX(0, screen_width - requisition.width));
+  *y = CLAMP(point[1] - 2, 0, MAX(0, screen_height - requisition.height));
+
+  *push_in = FALSE;
+}
+
+
+void
+ui_manager_popup_menu_show ( GtkMenu * menu , gint x , gint y , guint button , guint time )
+{
+  gint pos[2];
+  pos[0] = x;
+  pos[1] = y;
+
+  gtk_menu_popup( menu , NULL , NULL ,
+    (GtkMenuPositionFunc) menu_popup_pos_func , pos , button , time );
+}
+
+
+
+/******************************/
+/* plugin-available functions */
+
+#define _MP_GWID(y) gtk_ui_manager_get_widget( ui_manager , y )
+
+static GtkWidget*
+audacious_menu_plugin_menuwid( menu_id )
+{
+  switch (menu_id)
+  {
+    case AUDACIOUS_MENU_MAIN:
+      return _MP_GWID("/mainwin-menus/main-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST:
+      return _MP_GWID("/playlist-menus/playlist-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_RCLICK:
+      return _MP_GWID("/playlist-menus/playlist-rightclick-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_ADD:
+      return _MP_GWID("/playlist-menus/add-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_REMOVE:
+      return _MP_GWID("/playlist-menus/del-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_SELECT:
+      return _MP_GWID("/playlist-menus/select-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_MISC:
+      return _MP_GWID("/playlist-menus/misc-menu/plugins-menu");
+    default:
+      return NULL;
+  }
+}
+
+
+gint
+menu_plugin_item_add( gint menu_id , GtkWidget * item )
+{
+  if ( menu_created )
+  {
+    GtkWidget *plugins_menu = NULL;
+    GtkWidget *plugins_menu_item = audacious_menu_plugin_menuwid( menu_id );
+    if ( plugins_menu_item )
+    {
+      gint ic = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(plugins_menu_item),"ic"));
+      if ( ic == 0 ) /* no items under plugins_menu_item, create the submenu */
+      {
+        plugins_menu = gtk_menu_new();
+        gtk_menu_item_set_submenu( GTK_MENU_ITEM(plugins_menu_item), plugins_menu );
+      }
+      else /* items available under plugins_menu_item, pick the existing submenu */
+      {
+        plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
+        if ( !plugins_menu ) return -1;
+      }
+      gtk_menu_shell_append( GTK_MENU_SHELL(plugins_menu) , item );
+      gtk_widget_show( plugins_menu_item );
+      g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(++ic) );
+      return 0; /* success */
+    }
+  }
+  return -1; /* failure */
+}
+
+
+gint
+menu_plugin_item_remove( gint menu_id , GtkWidget * item )
+{
+  if ( menu_created )
+  {
+    GtkWidget *plugins_menu = NULL;
+    GtkWidget *plugins_menu_item = audacious_menu_plugin_menuwid( menu_id );
+    if ( plugins_menu_item )
+    {
+      gint ic = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(plugins_menu_item),"ic"));
+      if ( ic > 0 )
+      {
+        plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
+        if ( plugins_menu )
+        {
+          /* remove the plugin-added entry */
+          gtk_container_remove( GTK_CONTAINER(plugins_menu) , item );
+          g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(--ic) );
+          if ( ic == 0 ) /* if the menu is empty now, destroy it */
+          {
+            gtk_menu_item_remove_submenu( GTK_MENU_ITEM(plugins_menu_item) );
+            gtk_widget_destroy( plugins_menu );
+            gtk_widget_hide( plugins_menu_item );
+          }
+          return 0; /* success */
+        }
+      }
+    }
+  }
+  return -1; /* failure */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_manager.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,77 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_MANAGER_H
+#define AUDACIOUS_UI_MANAGER_H
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+GtkWidget *mainwin_songname_menu;
+GtkWidget *mainwin_general_menu;
+GtkWidget *mainwin_visualization_menu;
+GtkWidget *mainwin_playback_menu;
+GtkWidget *mainwin_playlist_menu;
+GtkWidget *mainwin_view_menu;
+
+GtkWidget *playlistwin_pladd_menu;
+GtkWidget *playlistwin_pldel_menu;
+GtkWidget *playlistwin_plsel_menu;
+GtkWidget *playlistwin_plsort_menu;
+GtkWidget *playlistwin_pllist_menu;
+GtkWidget *playlistwin_popup_menu;
+
+GtkWidget *equalizerwin_presets_menu;
+
+GtkActionGroup *toggleaction_group_others;
+GtkActionGroup *radioaction_group_anamode; /* Analyzer mode */
+GtkActionGroup *radioaction_group_anatype; /* Analyzer type */
+GtkActionGroup *radioaction_group_scomode; /* Scope mode */
+GtkActionGroup *radioaction_group_vprmode; /* Voiceprint mode */
+GtkActionGroup *radioaction_group_wshmode; /* WindowShade VU mode */
+GtkActionGroup *radioaction_group_refrate; /* Refresh rate */
+GtkActionGroup *radioaction_group_anafoff; /* Analyzer Falloff */
+GtkActionGroup *radioaction_group_peafoff; /* Peak Falloff */
+GtkActionGroup *radioaction_group_vismode; /* Visualization mode */
+GtkActionGroup *radioaction_group_viewtime; /* View time (remaining/elapsed) */
+GtkActionGroup *action_group_playback;
+GtkActionGroup *action_group_visualization;
+GtkActionGroup *action_group_view;
+GtkActionGroup *action_group_others;
+GtkActionGroup *action_group_playlist;
+GtkActionGroup *action_group_playlist_add;
+GtkActionGroup *action_group_playlist_select;
+GtkActionGroup *action_group_playlist_delete;
+GtkActionGroup *action_group_playlist_sort;
+GtkActionGroup *action_group_equalizer;
+
+
+void ui_manager_init ( void );
+void ui_manager_create_menus ( void );
+GtkAccelGroup * ui_manager_get_accel_group ( void );
+GtkWidget * ui_manager_get_popup_menu ( GtkUIManager * , const gchar * );
+void ui_manager_popup_menu_show( GtkMenu * , gint , gint , guint , guint );
+#define popup_menu_show(x1,x2,x3,x4,x5) ui_manager_popup_menu_show(x1,x2,x3,x4,x5)
+
+G_END_DECLS
+
+#endif /* AUDACIOUS_UI_MANAGER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_playlist.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,1923 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2006  Audacious development team.
+ *
+ *  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+/* #define AUD_DEBUG 1 */
+
+#include "ui_playlist.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "platform/smartinclude.h"
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "actions-playlist.h"
+#include "dnd.h"
+#include "input.h"
+#include "main.h"
+#include "playback.h"
+#include "playlist.h"
+#include "playlist_container.h"
+#include "strings.h"
+#include "ui_dock.h"
+#include "ui_equalizer.h"
+#include "ui_fileinfo.h"
+#include "ui_fileopener.h"
+#include "ui_main.h"
+#include "ui_manager.h"
+#include "ui_playlist_evlisteners.h"
+#include "ui_playlist_manager.h"
+#include "util.h"
+#include "config.h"
+
+#include "ui_skinned_window.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_textbox.h"
+#include "ui_skinned_playlist_slider.h"
+#include "ui_skinned_playlist.h"
+
+#include "icons-stock.h"
+#include "images/audacious_playlist.xpm"
+
+GtkWidget *playlistwin;
+
+static GMutex *resize_mutex = NULL;
+
+static GtkWidget *playlistwin_list = NULL;
+static GtkWidget *playlistwin_shade, *playlistwin_close;
+
+static gboolean playlistwin_hint_flag = FALSE;
+
+static GtkWidget *playlistwin_slider;
+static GtkWidget *playlistwin_time_min, *playlistwin_time_sec;
+static GtkWidget *playlistwin_info, *playlistwin_sinfo;
+static GtkWidget *playlistwin_srew, *playlistwin_splay;
+static GtkWidget *playlistwin_spause, *playlistwin_sstop;
+static GtkWidget *playlistwin_sfwd, *playlistwin_seject;
+static GtkWidget *playlistwin_sscroll_up, *playlistwin_sscroll_down;
+
+static void playlistwin_select_search_cbt_cb(GtkWidget *called_cbt,
+                                             gpointer other_cbt);
+static gboolean playlistwin_select_search_kp_cb(GtkWidget *entry,
+                                                GdkEventKey *event,
+                                                gpointer searchdlg_win);
+
+static gboolean playlistwin_resizing = FALSE;
+static gint playlistwin_resize_x, playlistwin_resize_y;
+
+gboolean
+playlistwin_is_shaded(void)
+{
+    return cfg.playlist_shaded;
+}
+
+gint
+playlistwin_get_width(void)
+{
+    cfg.playlist_width /= PLAYLISTWIN_WIDTH_SNAP;
+    cfg.playlist_width *= PLAYLISTWIN_WIDTH_SNAP;
+    return cfg.playlist_width;
+}
+
+gint
+playlistwin_get_height_unshaded(void)
+{
+    cfg.playlist_height /= PLAYLISTWIN_HEIGHT_SNAP;
+    cfg.playlist_height *= PLAYLISTWIN_HEIGHT_SNAP;
+    return cfg.playlist_height;
+}
+
+gint
+playlistwin_get_height_shaded(void)
+{
+    return PLAYLISTWIN_SHADED_HEIGHT;
+}
+
+gint
+playlistwin_get_height(void)
+{
+    if (playlistwin_is_shaded())
+        return playlistwin_get_height_shaded();
+    else
+        return playlistwin_get_height_unshaded();
+}
+
+static void
+playlistwin_update_info(Playlist *playlist)
+{
+    gchar *text, *sel_text, *tot_text;
+    gulong selection, total;
+    gboolean selection_more, total_more;
+
+    playlist_get_total_time(playlist, &total, &selection, &total_more, &selection_more);
+
+    if (selection > 0 || (selection == 0 && !selection_more)) {
+        if (selection > 3600)
+            sel_text =
+                g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", selection / 3600,
+                                (selection / 60) % 60, selection % 60,
+                                (selection_more ? "+" : ""));
+        else
+            sel_text =
+                g_strdup_printf("%lu:%-2.2lu%s", selection / 60,
+                                selection % 60, (selection_more ? "+" : ""));
+    }
+    else
+        sel_text = g_strdup("?");
+    if (total > 0 || (total == 0 && !total_more)) {
+        if (total > 3600)
+            tot_text =
+                g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", total / 3600,
+                                (total / 60) % 60, total % 60,
+                                total_more ? "+" : "");
+        else
+            tot_text =
+                g_strdup_printf("%lu:%-2.2lu%s", total / 60, total % 60,
+                                total_more ? "+" : "");
+    }
+    else
+        tot_text = g_strdup("?");
+    text = g_strconcat(sel_text, "/", tot_text, NULL);
+    ui_skinned_textbox_set_text(playlistwin_info, text ? text : "");
+    g_free(text);
+    g_free(tot_text);
+    g_free(sel_text);
+}
+
+static void
+playlistwin_update_sinfo(Playlist *playlist)
+{
+    gchar *posstr, *timestr, *title, *info;
+    gint pos, time;
+
+    pos = playlist_get_position(playlist);
+    title = playlist_get_songtitle(playlist, pos);
+
+    if (!title) {
+        ui_skinned_textbox_set_text(playlistwin_sinfo, "");
+        return;
+    }
+
+    convert_title_text(title);
+
+    time = playlist_get_songtime(playlist, pos);
+
+    if (cfg.show_numbers_in_pl)
+        posstr = g_strdup_printf("%d. ", pos + 1);
+    else
+        posstr = g_strdup("");
+
+    if (time != -1) {
+        timestr = g_strdup_printf(" (%d:%-2.2d)", time / 60000,
+                                      (time / 1000) % 60);
+    }
+    else
+        timestr = g_strdup("");
+
+    info = g_strdup_printf("%s%s%s", posstr, title, timestr);
+
+    g_free(posstr);
+    g_free(title);
+    g_free(timestr);
+
+    ui_skinned_textbox_set_text(playlistwin_sinfo, info ? info : "");
+    g_free(info);
+}
+
+gboolean
+playlistwin_item_visible(gint index)
+{
+    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), FALSE);
+
+    if (index >= UI_SKINNED_PLAYLIST(playlistwin_list)->first &&
+        index < (UI_SKINNED_PLAYLIST(playlistwin_list)->first + UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible) ) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+gint
+playlistwin_list_get_visible_count(void)
+{
+    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1);
+
+    return UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible;
+}
+
+gint
+playlistwin_list_get_first(void)
+{
+    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1);
+
+    return UI_SKINNED_PLAYLIST(playlistwin_list)->first;
+}
+
+gint
+playlistwin_get_toprow(void)
+{
+    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1);
+
+    return (UI_SKINNED_PLAYLIST(playlistwin_list)->first);
+}
+
+void
+playlistwin_set_toprow(gint toprow)
+{
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list))
+        UI_SKINNED_PLAYLIST(playlistwin_list)->first = toprow;
+    g_cond_signal(cond_scan);
+    playlistwin_update_list(playlist_get_active());
+}
+
+void
+playlistwin_update_list(Playlist *playlist)
+{
+    /* this can happen early on. just bail gracefully. */
+    g_return_if_fail(playlistwin_list);
+
+    playlistwin_update_info(playlist);
+    playlistwin_update_sinfo(playlist);
+    gtk_widget_queue_draw(playlistwin_list);
+    gtk_widget_queue_draw(playlistwin_slider);
+}
+
+static void
+playlistwin_set_geometry_hints(gboolean shaded)
+{
+    GdkGeometry geometry;
+    GdkWindowHints mask;
+
+    geometry.min_width = PLAYLISTWIN_MIN_WIDTH;
+    geometry.max_width = G_MAXUINT16;
+
+    geometry.width_inc = PLAYLISTWIN_WIDTH_SNAP;
+    geometry.height_inc = PLAYLISTWIN_HEIGHT_SNAP;
+
+    if (shaded) {
+        geometry.min_height = PLAYLISTWIN_SHADED_HEIGHT;
+        geometry.max_height = PLAYLISTWIN_SHADED_HEIGHT;
+        geometry.base_height = PLAYLISTWIN_SHADED_HEIGHT;
+    }
+    else {
+        geometry.min_height = PLAYLISTWIN_MIN_HEIGHT;
+        geometry.max_height = G_MAXUINT16;
+    }
+
+    mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_RESIZE_INC;
+
+    gtk_window_set_geometry_hints(GTK_WINDOW(playlistwin),
+                                  playlistwin, &geometry, mask);
+}
+
+void
+playlistwin_set_sinfo_font(gchar *font)
+{
+    gchar *tmp = NULL, *tmp2 = NULL;
+
+    g_return_if_fail(font);
+    AUDDBG("Attempt to set font \"%s\"\n", font);
+
+    tmp = g_strdup(font);
+    g_return_if_fail(tmp);
+
+    *strrchr(tmp, ' ') = '\0';
+    tmp2 = g_strdup_printf("%s 8", tmp);
+    g_return_if_fail(tmp2);
+
+    ui_skinned_textbox_set_xfont(playlistwin_sinfo, !cfg.mainwin_use_bitmapfont, tmp2);
+
+    g_free(tmp);
+    g_free(tmp2);
+}
+
+void
+playlistwin_set_sinfo_scroll(gboolean scroll)
+{
+    if(playlistwin_is_shaded())
+        ui_skinned_textbox_set_scroll(playlistwin_sinfo, cfg.autoscroll);
+    else
+        ui_skinned_textbox_set_scroll(playlistwin_sinfo, FALSE);
+}
+
+void
+playlistwin_set_shade(gboolean shaded)
+{
+    cfg.playlist_shaded = shaded;
+
+    if (shaded) {
+        playlistwin_set_sinfo_font(cfg.playlist_font);
+        playlistwin_set_sinfo_scroll(cfg.autoscroll);
+        gtk_widget_show(playlistwin_sinfo);
+        ui_skinned_set_push_button_data(playlistwin_shade, 128, 45, 150, 42);
+        ui_skinned_set_push_button_data(playlistwin_close, 138, 45, -1, -1);
+    }
+    else {
+        gtk_widget_hide(playlistwin_sinfo);
+        playlistwin_set_sinfo_scroll(FALSE);
+        ui_skinned_set_push_button_data(playlistwin_shade, 157, 3, 62, 42);
+        ui_skinned_set_push_button_data(playlistwin_close, 167, 3, -1, -1);
+    }
+
+    dock_shade(get_dock_window_list(), GTK_WINDOW(playlistwin),
+               playlistwin_get_height());
+
+    playlistwin_set_geometry_hints(cfg.playlist_shaded);
+
+    gtk_window_resize(GTK_WINDOW(playlistwin),
+                      playlistwin_get_width(),
+                      playlistwin_get_height());
+}
+
+static void
+playlistwin_set_shade_menu(gboolean shaded)
+{
+    GtkAction *action = gtk_action_group_get_action(
+      toggleaction_group_others , "roll up playlist editor" );
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded );
+
+    playlistwin_set_shade(shaded);
+    playlistwin_update_list(playlist_get_active());
+}
+
+void
+playlistwin_shade_toggle(void)
+{
+    playlistwin_set_shade_menu(!cfg.playlist_shaded);
+}
+
+static gboolean
+playlistwin_release(GtkWidget * widget,
+                    GdkEventButton * event,
+                    gpointer callback_data)
+{
+    playlistwin_resizing = FALSE;
+    return FALSE;
+}
+
+void
+playlistwin_scroll(gint num)
+{
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list))
+        UI_SKINNED_PLAYLIST(playlistwin_list)->first += num;
+    playlistwin_update_list(playlist_get_active());
+}
+
+void
+playlistwin_scroll_up_pushed(void)
+{
+    playlistwin_scroll(-3);
+}
+
+void
+playlistwin_scroll_down_pushed(void)
+{
+    playlistwin_scroll(3);
+}
+
+static void
+playlistwin_select_all(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_select_all(playlist, TRUE);
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
+        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = 0;
+        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = 0;
+        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_max = playlist_get_length(playlist) - 1;
+    }
+    playlistwin_update_list(playlist);
+}
+
+static void
+playlistwin_select_none(void)
+{
+    playlist_select_all(playlist_get_active(), FALSE);
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
+        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = -1;
+        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = -1;
+    }
+    playlistwin_update_list(playlist_get_active());
+}
+
+static void
+playlistwin_select_search(void)
+{
+    Playlist *playlist = playlist_get_active();
+    GtkWidget *searchdlg_win, *searchdlg_table;
+    GtkWidget *searchdlg_hbox, *searchdlg_logo, *searchdlg_helptext;
+    GtkWidget *searchdlg_entry_title, *searchdlg_label_title;
+    GtkWidget *searchdlg_entry_album, *searchdlg_label_album;
+    GtkWidget *searchdlg_entry_file_name, *searchdlg_label_file_name;
+    GtkWidget *searchdlg_entry_performer, *searchdlg_label_performer;
+    GtkWidget *searchdlg_checkbt_clearprevsel;
+    GtkWidget *searchdlg_checkbt_newplaylist;
+    GtkWidget *searchdlg_checkbt_autoenqueue;
+    gint result;
+
+    /* create dialog */
+    searchdlg_win = gtk_dialog_new_with_buttons(
+      _("Search entries in active playlist") , GTK_WINDOW(mainwin) ,
+      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
+      GTK_STOCK_CANCEL , GTK_RESPONSE_REJECT , GTK_STOCK_OK , GTK_RESPONSE_ACCEPT , NULL );
+    gtk_window_set_position(GTK_WINDOW(searchdlg_win), GTK_WIN_POS_CENTER);
+
+    /* help text and logo */
+    searchdlg_hbox = gtk_hbox_new( FALSE , 4 );
+    searchdlg_logo = gtk_image_new_from_stock( GTK_STOCK_FIND , GTK_ICON_SIZE_DIALOG );
+    searchdlg_helptext = gtk_label_new( _("Select entries in playlist by filling one or more "
+      "fields. Fields use regular expressions syntax, case-insensitive. If you don't know how "
+      "regular expressions work, simply insert a literal portion of what you're searching for.") );
+    gtk_label_set_line_wrap( GTK_LABEL(searchdlg_helptext) , TRUE );
+    gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_logo , FALSE , FALSE , 0 );
+    gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_helptext , FALSE , FALSE , 0 );
+
+    /* title */
+    searchdlg_label_title = gtk_label_new( _("Title: ") );
+    searchdlg_entry_title = gtk_entry_new();
+    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_title) , 0 , 0.5 );
+    g_signal_connect( G_OBJECT(searchdlg_entry_title) , "key-press-event" ,
+      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+    /* album */
+    searchdlg_label_album= gtk_label_new( _("Album: ") );
+    searchdlg_entry_album= gtk_entry_new();
+    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_album) , 0 , 0.5 );
+    g_signal_connect( G_OBJECT(searchdlg_entry_album) , "key-press-event" ,
+      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+    /* artist */
+    searchdlg_label_performer = gtk_label_new( _("Artist: ") );
+    searchdlg_entry_performer = gtk_entry_new();
+    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_performer) , 0 , 0.5 );
+    g_signal_connect( G_OBJECT(searchdlg_entry_performer) , "key-press-event" ,
+      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+    /* file name */
+    searchdlg_label_file_name = gtk_label_new( _("Filename: ") );
+    searchdlg_entry_file_name = gtk_entry_new();
+    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_file_name) , 0 , 0.5 );
+    g_signal_connect( G_OBJECT(searchdlg_entry_file_name) , "key-press-event" ,
+      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
+
+    /* some options that control behaviour */
+    searchdlg_checkbt_clearprevsel = gtk_check_button_new_with_label(
+      _("Clear previous selection before searching") );
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel) , TRUE );
+    searchdlg_checkbt_autoenqueue = gtk_check_button_new_with_label(
+      _("Automatically toggle queue for matching entries") );
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue) , FALSE );
+    searchdlg_checkbt_newplaylist = gtk_check_button_new_with_label(
+      _("Create a new playlist with matching entries") );
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist) , FALSE );
+    g_signal_connect( G_OBJECT(searchdlg_checkbt_autoenqueue) , "clicked" ,
+      G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_newplaylist );
+    g_signal_connect( G_OBJECT(searchdlg_checkbt_newplaylist) , "clicked" ,
+      G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_autoenqueue );
+
+    /* place fields in searchdlg_table */
+    searchdlg_table = gtk_table_new( 8 , 2 , FALSE );
+    gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 0 , 8 );
+    gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 4 , 8 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_hbox ,
+      0 , 2 , 0 , 1 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_title ,
+      0 , 1 , 1 , 2 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_title ,
+      1 , 2 , 1 , 2 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_album,
+      0 , 1 , 2 , 3 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_album,
+      1 , 2 , 2 , 3 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_performer ,
+      0 , 1 , 3 , 4 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_performer ,
+      1 , 2 , 3 , 4 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_file_name ,
+      0 , 1 , 4 , 5 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_file_name ,
+      1 , 2 , 4 , 5 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_clearprevsel ,
+      0 , 2 , 5 , 6 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_autoenqueue ,
+      0 , 2 , 6 , 7 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
+    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_newplaylist ,
+      0 , 2 , 7 , 8 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
+
+    gtk_container_set_border_width( GTK_CONTAINER(searchdlg_table) , 5 );
+    gtk_container_add( GTK_CONTAINER(GTK_DIALOG(searchdlg_win)->vbox) , searchdlg_table );
+    gtk_widget_show_all( searchdlg_win );
+    result = gtk_dialog_run( GTK_DIALOG(searchdlg_win) );
+    switch(result)
+    {
+      case GTK_RESPONSE_ACCEPT:
+      {
+         gint matched_entries_num = 0;
+         /* create a TitleInput tuple with user search data */
+         Tuple *tuple = tuple_new();
+         gchar *searchdata = NULL;
+
+         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_title) );
+         AUDDBG("title=\"%s\"\n", searchdata);
+         tuple_associate_string(tuple, FIELD_TITLE, NULL, searchdata);
+
+         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_album) );
+         AUDDBG("album=\"%s\"\n", searchdata);
+         tuple_associate_string(tuple, FIELD_ALBUM, NULL, searchdata);
+
+         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_performer) );
+         AUDDBG("performer=\"%s\"\n", searchdata);
+         tuple_associate_string(tuple, FIELD_ARTIST, NULL, searchdata);
+
+         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_file_name) );
+         AUDDBG("filename=\"%s\"\n", searchdata);
+         tuple_associate_string(tuple, FIELD_FILE_NAME, NULL, searchdata);
+
+         /* check if previous selection should be cleared before searching */
+         if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel)) == TRUE )
+             playlistwin_select_none();
+         /* now send this tuple to the real search function */
+         matched_entries_num = playlist_select_search( playlist , tuple , 0 );
+         /* we do not need the tuple and its data anymore */
+         mowgli_object_unref(tuple);
+         playlistwin_update_list(playlist_get_active());
+         /* check if a new playlist should be created after searching */
+         if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist)) == TRUE )
+             playlist_new_from_selected();
+         /* check if matched entries should be queued */
+         else if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue)) == TRUE )
+             playlist_queue(playlist_get_active());
+         break;
+      }
+      default:
+         break;
+    }
+    /* done here :) */
+    gtk_widget_destroy( searchdlg_win );
+}
+
+static void
+playlistwin_inverse_selection(void)
+{
+    playlist_select_invert_all(playlist_get_active());
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
+        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = -1;
+        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = -1;
+    }
+    playlistwin_update_list(playlist_get_active());
+}
+
+static void
+playlistwin_resize(gint width, gint height)
+{
+    gint tx, ty;
+    gint dx, dy;
+
+    g_return_if_fail(width > 0 && height > 0);
+
+    tx = (width - PLAYLISTWIN_MIN_WIDTH) / PLAYLISTWIN_WIDTH_SNAP;
+    tx = (tx * PLAYLISTWIN_WIDTH_SNAP) + PLAYLISTWIN_MIN_WIDTH;
+    if (tx < PLAYLISTWIN_MIN_WIDTH)
+        tx = PLAYLISTWIN_MIN_WIDTH;
+
+    if (!cfg.playlist_shaded)
+    {
+        ty = (height - PLAYLISTWIN_MIN_HEIGHT) / PLAYLISTWIN_HEIGHT_SNAP;
+        ty = (ty * PLAYLISTWIN_HEIGHT_SNAP) + PLAYLISTWIN_MIN_HEIGHT;
+        if (ty < PLAYLISTWIN_MIN_HEIGHT)
+            ty = PLAYLISTWIN_MIN_HEIGHT;
+    }
+    else
+        ty = cfg.playlist_height;
+
+    if (tx == cfg.playlist_width && ty == cfg.playlist_height)
+        return;
+
+    /* difference between previous size and new size */
+    dx = tx - cfg.playlist_width;
+    dy = ty - cfg.playlist_height;
+
+    cfg.playlist_width = width = tx;
+    cfg.playlist_height = height = ty;
+
+    g_mutex_lock(resize_mutex);
+    ui_skinned_playlist_resize_relative(playlistwin_list, dx, dy);
+
+    ui_skinned_playlist_slider_move_relative(playlistwin_slider, dx);
+    ui_skinned_playlist_slider_resize_relative(playlistwin_slider, dy);
+
+    playlistwin_update_sinfo(playlist_get_active());
+
+    ui_skinned_button_move_relative(playlistwin_shade, dx, 0);
+    ui_skinned_button_move_relative(playlistwin_close, dx, 0);
+    ui_skinned_textbox_move_relative(playlistwin_time_min, dx, dy);
+    ui_skinned_textbox_move_relative(playlistwin_time_sec, dx, dy);
+    ui_skinned_textbox_move_relative(playlistwin_info, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_srew, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_splay, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_spause, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_sstop, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_sfwd, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_seject, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_sscroll_up, dx, dy);
+    ui_skinned_button_move_relative(playlistwin_sscroll_down, dx, dy);
+
+    gtk_widget_set_size_request(playlistwin_sinfo, playlistwin_get_width() - 35,
+                                aud_active_skin->properties.textbox_bitmap_font_height);
+    GList *iter;
+    for (iter = GTK_FIXED (SKINNED_WINDOW(playlistwin)->fixed)->children; iter; iter = g_list_next (iter)) {
+         GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
+         GtkWidget *child = child_data->widget;
+         g_signal_emit_by_name(child, "redraw");
+    }
+    g_mutex_unlock(resize_mutex);
+}
+
+static void
+playlistwin_motion(GtkWidget * widget,
+                   GdkEventMotion * event,
+                   gpointer callback_data)
+{
+    /*
+     * GDK2's resize is broken and doesn't really play nice, so we have
+     * to do all of this stuff by hand.
+     */
+    if (playlistwin_resizing == TRUE)
+    {
+        if (event->x + playlistwin_resize_x != playlistwin_get_width() ||
+            event->y + playlistwin_resize_y != playlistwin_get_height())
+        {
+            playlistwin_resize(event->x + playlistwin_resize_x,
+                               event->y + playlistwin_resize_y);
+            gdk_window_resize(playlistwin->window,
+                              cfg.playlist_width, playlistwin_get_height());
+            gdk_flush();
+        }
+    }
+    else if (dock_is_moving(GTK_WINDOW(playlistwin)))
+        dock_move_motion(GTK_WINDOW(playlistwin), event);
+}
+
+static void
+playlistwin_show_filebrowser(void)
+{
+    run_filebrowser(FALSE);
+}
+
+static void
+playlistwin_fileinfo(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    /* Show the first selected file, or the current file if nothing is
+     * selected */
+    GList *list = playlist_get_selected(playlist);
+    if (list) {
+        ui_fileinfo_show(playlist, GPOINTER_TO_INT(list->data));
+        g_list_free(list);
+    }
+    else
+        ui_fileinfo_show_current(playlist);
+}
+
+static void
+show_playlist_save_error(GtkWindow *parent,
+                         const gchar *filename)
+{
+    GtkWidget *dialog;
+
+    g_return_if_fail(GTK_IS_WINDOW(parent));
+    g_return_if_fail(filename);
+
+    dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_ERROR,
+                                    GTK_BUTTONS_OK,
+                                    _("Error writing playlist \"%s\": %s"),
+                                    filename, strerror(errno));
+
+    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+}
+
+static gboolean
+show_playlist_overwrite_prompt(GtkWindow * parent,
+                               const gchar * filename)
+{
+    GtkWidget *dialog;
+    gint result;
+
+    g_return_val_if_fail(GTK_IS_WINDOW(parent), FALSE);
+    g_return_val_if_fail(filename != NULL, FALSE);
+
+    dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_QUESTION,
+                                    GTK_BUTTONS_YES_NO,
+                                    _("%s already exist. Continue?"),
+                                    filename);
+
+    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
+    result = gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+
+    return (result == GTK_RESPONSE_YES);
+}
+
+static void
+show_playlist_save_format_error(GtkWindow * parent,
+                                const gchar * filename)
+{
+    const gchar *markup =
+        N_("<b><big>Unable to save playlist.</big></b>\n\n"
+           "Unknown file type for '%s'.\n");
+
+    GtkWidget *dialog;
+
+    g_return_if_fail(GTK_IS_WINDOW(parent));
+    g_return_if_fail(filename != NULL);
+
+    dialog =
+        gtk_message_dialog_new_with_markup(GTK_WINDOW(parent),
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_OK,
+                                           _(markup),
+                                           filename);
+
+    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+}
+
+static void
+playlistwin_save_playlist(const gchar * filename)
+{
+    PlaylistContainer *plc;
+    gchar *ext = strrchr(filename, '.') + 1;
+
+    plc = playlist_container_find(ext);
+    if (plc == NULL) {
+        show_playlist_save_format_error(GTK_WINDOW(playlistwin), filename);
+        return;
+    }
+
+    str_replace_in(&cfg.playlist_path, g_path_get_dirname(filename));
+
+    if (g_file_test(filename, G_FILE_TEST_IS_REGULAR))
+        if (!show_playlist_overwrite_prompt(GTK_WINDOW(playlistwin), filename))
+            return;
+
+    if (!playlist_save(playlist_get_active(), filename))
+        show_playlist_save_error(GTK_WINDOW(playlistwin), filename);
+}
+
+static void
+playlistwin_load_playlist(const gchar * filename)
+{
+    const gchar *title;
+    Playlist *playlist = playlist_get_active();
+
+    g_return_if_fail(filename != NULL);
+
+    str_replace_in(&cfg.playlist_path, g_path_get_dirname(filename));
+
+    playlist_clear(playlist);
+    mainwin_clear_song_info();
+
+    playlist_load(playlist, filename);
+    title = playlist_get_current_name(playlist);
+    if(!title || !title[0])
+        playlist_set_current_name(playlist, filename);
+}
+
+static gchar *
+playlist_file_selection_load(const gchar * title,
+                        const gchar * default_filename)
+{
+    GtkWidget *dialog;
+    gchar *filename;
+
+    g_return_val_if_fail(title != NULL, NULL);
+
+    dialog = make_filebrowser(title, FALSE);
+    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), cfg.playlist_path);
+    if (default_filename)
+        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), default_filename);
+    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
+
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+    else
+        filename = NULL;
+
+    gtk_widget_destroy(dialog);
+    return filename;
+}
+
+static void
+on_static_toggle(GtkToggleButton *button, gpointer data)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist->attribute =
+        gtk_toggle_button_get_active(button) ?
+        playlist->attribute | PLAYLIST_STATIC :
+        playlist->attribute & ~PLAYLIST_STATIC;
+}
+
+static void
+on_relative_toggle(GtkToggleButton *button, gpointer data)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist->attribute =
+        gtk_toggle_button_get_active(button) ?
+        playlist->attribute | PLAYLIST_USE_RELATIVE :
+        playlist->attribute & ~PLAYLIST_USE_RELATIVE;
+}
+
+static gchar *
+playlist_file_selection_save(const gchar * title,
+                        const gchar * default_filename)
+{
+    GtkWidget *dialog;
+    gchar *filename;
+    GtkWidget *hbox;
+    GtkWidget *toggle, *toggle2;
+
+    g_return_val_if_fail(title != NULL, NULL);
+
+    dialog = make_filebrowser(title, TRUE);
+    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), cfg.playlist_path);
+    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), default_filename);
+
+    hbox = gtk_hbox_new(FALSE, 5);
+
+    /* static playlist */
+    toggle = gtk_check_button_new_with_label(_("Save as Static Playlist"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
+                                 (playlist_get_active()->attribute & PLAYLIST_STATIC) ? TRUE : FALSE);
+    g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(on_static_toggle), dialog);
+    gtk_box_pack_start(GTK_BOX(hbox), toggle, FALSE, FALSE, 0);
+
+    /* use relative path */
+    toggle2 = gtk_check_button_new_with_label(_("Use Relative Path"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle2),
+                                 (playlist_get_active()->attribute & PLAYLIST_USE_RELATIVE) ? TRUE : FALSE);
+    g_signal_connect(G_OBJECT(toggle2), "toggled", G_CALLBACK(on_relative_toggle), dialog);
+    gtk_box_pack_start(GTK_BOX(hbox), toggle2, FALSE, FALSE, 0);
+
+    gtk_widget_show_all(hbox);
+    gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), hbox);
+
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+    else
+        filename = NULL;
+
+    gtk_widget_destroy(dialog);
+    return filename;
+}
+
+void
+playlistwin_select_playlist_to_load(const gchar * default_filename)
+{
+    gchar *filename =
+        playlist_file_selection_load(_("Load Playlist"), default_filename);
+
+    if (filename) {
+        playlistwin_load_playlist(filename);
+        g_free(filename);
+    }
+}
+
+static void
+playlistwin_select_playlist_to_save(const gchar * default_filename)
+{
+    gchar *dot = NULL, *basename = NULL;
+    gchar *filename =
+        playlist_file_selection_save(_("Save Playlist"), default_filename);
+
+    if (filename) {
+        /* Default extension */
+        basename = g_path_get_basename(filename);
+        dot = strrchr(basename, '.');
+        if( dot == NULL || dot == basename) {
+            gchar *oldname = filename;
+#ifdef HAVE_XSPF_PLAYLIST
+            filename = g_strconcat(oldname, ".xspf", NULL);
+#else
+            filename = g_strconcat(oldname, ".m3u", NULL);
+#endif
+            g_free(oldname);
+        }
+        g_free(basename);
+
+        playlistwin_save_playlist(filename);
+        g_free(filename);
+    }
+}
+
+#define REGION_L(x1,x2,y1,y2)                   \
+    (event->x >= (x1) && event->x < (x2) &&     \
+     event->y >= cfg.playlist_height - (y1) &&  \
+     event->y < cfg.playlist_height - (y2))
+
+#define REGION_R(x1,x2,y1,y2)                      \
+    (event->x >= playlistwin_get_width() - (x1) && \
+     event->x < playlistwin_get_width() - (x2) &&  \
+     event->y >= cfg.playlist_height - (y1) &&     \
+     event->y < cfg.playlist_height - (y2))
+
+static void
+playlistwin_scrolled(GtkWidget * widget,
+                     GdkEventScroll * event,
+                     gpointer callback_data)
+{
+    if (event->direction == GDK_SCROLL_DOWN)
+        playlistwin_scroll(cfg.scroll_pl_by);
+
+    if (event->direction == GDK_SCROLL_UP)
+        playlistwin_scroll(-cfg.scroll_pl_by);
+
+    g_cond_signal(cond_scan);
+}
+
+static gboolean
+playlistwin_press(GtkWidget * widget,
+                  GdkEventButton * event,
+                  gpointer callback_data)
+{
+    gint xpos, ypos;
+    GtkRequisition req;
+
+    gtk_window_get_position(GTK_WINDOW(playlistwin), &xpos, &ypos);
+
+    if (event->button == 1 && !cfg.show_wm_decorations &&
+        ((!cfg.playlist_shaded &&
+          event->x > playlistwin_get_width() - 20 &&
+          event->y > cfg.playlist_height - 20) ||
+         (cfg.playlist_shaded &&
+          event->x >= playlistwin_get_width() - 31 &&
+          event->x < playlistwin_get_width() - 22))) {
+
+        if (event->type != GDK_2BUTTON_PRESS &&
+            event->type != GDK_3BUTTON_PRESS) {
+            playlistwin_resizing = TRUE;
+            playlistwin_resize_x = cfg.playlist_width - event->x;
+            playlistwin_resize_y = cfg.playlist_height - event->y;
+        }
+    }
+    else if (event->button == 1 && REGION_L(12, 37, 29, 11)) {
+        /* ADD button menu */
+        gtk_widget_size_request(playlistwin_pladd_menu, &req);
+        ui_manager_popup_menu_show(GTK_MENU(playlistwin_pladd_menu),
+                   xpos + 12,
+                   (ypos + playlistwin_get_height()) - 8 - req.height,
+                   event->button,
+                   event->time);
+    }
+    else if (event->button == 1 && REGION_L(41, 66, 29, 11)) {
+        /* SUB button menu */
+        gtk_widget_size_request(playlistwin_pldel_menu, &req);
+        ui_manager_popup_menu_show(GTK_MENU(playlistwin_pldel_menu),
+                   xpos + 40,
+                   (ypos + playlistwin_get_height()) - 8 - req.height,
+                   event->button,
+                   event->time);
+    }
+    else if (event->button == 1 && REGION_L(70, 95, 29, 11)) {
+        /* SEL button menu */
+        gtk_widget_size_request(playlistwin_plsel_menu, &req);
+        ui_manager_popup_menu_show(GTK_MENU(playlistwin_plsel_menu),
+                   xpos + 68,
+                   (ypos + playlistwin_get_height()) - 8 - req.height,
+                   event->button,
+                   event->time);
+    }
+    else if (event->button == 1 && REGION_L(99, 124, 29, 11)) {
+        /* MISC button menu */
+        gtk_widget_size_request(playlistwin_plsort_menu, &req);
+        ui_manager_popup_menu_show(GTK_MENU(playlistwin_plsort_menu),
+                   xpos + 100,
+                   (ypos + playlistwin_get_height()) - 8 - req.height,
+                   event->button,
+                   event->time);
+    }
+    else if (event->button == 1 && REGION_R(46, 23, 29, 11)) {
+        /* LIST button menu */
+        gtk_widget_size_request(playlistwin_pllist_menu, &req);
+        ui_manager_popup_menu_show(GTK_MENU(playlistwin_pllist_menu),
+                   xpos + playlistwin_get_width() - req.width - 12,
+                   (ypos + playlistwin_get_height()) - 8 - req.height,
+                   event->button,
+                   event->time);
+    }
+    else if (event->button == 1 && event->type == GDK_BUTTON_PRESS &&
+             (cfg.easy_move || event->y < 14))
+    {
+        return FALSE;
+    }
+    else if (event->button == 1 && event->type == GDK_2BUTTON_PRESS
+             && event->y < 14) {
+        /* double click on title bar */
+        playlistwin_shade_toggle();
+        if (dock_is_moving(GTK_WINDOW(playlistwin)))
+            dock_move_release(GTK_WINDOW(playlistwin));
+        return TRUE;
+    }
+    else if (event->button == 3) {
+        /*
+         * Pop up the main menu a few pixels down to avoid
+         * anything to be selected initially.
+         */
+        ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), event->x_root,
+                                event->y_root + 2, 3, event->time);
+    }
+
+    return TRUE;
+}
+
+static gboolean
+playlistwin_delete(GtkWidget * w, gpointer data)
+{
+    playlistwin_hide();
+    return TRUE;
+}
+
+static gboolean
+playlistwin_keypress_up_down_handler(UiSkinnedPlaylist * pl,
+                                     gboolean up, guint state)
+{
+    Playlist *playlist = playlist_get_active();
+    if ((!(pl->prev_selected || pl->first) && up) ||
+       ((pl->prev_selected >= playlist_get_length(playlist) - 1) && !up))
+         return FALSE;
+
+    if ((state & GDK_MOD1_MASK) && (state & GDK_SHIFT_MASK))
+        return FALSE;
+    if (!(state & GDK_MOD1_MASK))
+        playlist_select_all(playlist, FALSE);
+
+    if (pl->prev_selected == -1 ||
+        (!playlistwin_item_visible(pl->prev_selected) &&
+         !(state & GDK_SHIFT_MASK && pl->prev_min != -1))) {
+        pl->prev_selected = pl->first;
+    }
+    else if (state & GDK_SHIFT_MASK) {
+        if (pl->prev_min == -1) {
+            pl->prev_max = pl->prev_selected;
+            pl->prev_min = pl->prev_selected;
+        }
+        pl->prev_max += (up ? -1 : 1);
+        pl->prev_max =
+            CLAMP(pl->prev_max, 0, playlist_get_length(playlist) - 1);
+
+        pl->first = MIN(pl->first, pl->prev_max);
+        pl->first = MAX(pl->first, pl->prev_max -
+                           pl->num_visible + 1);
+        playlist_select_range(playlist, pl->prev_min, pl->prev_max, TRUE);
+        return TRUE;
+    }
+    else if (state & GDK_MOD1_MASK) {
+        if (up)
+            ui_skinned_playlist_move_up(pl);
+        else
+            ui_skinned_playlist_move_down(pl);
+        if (pl->prev_min < pl->first)
+            pl->first = pl->prev_min;
+        else if (pl->prev_max >= (pl->first + pl->num_visible))
+            pl->first = pl->prev_max - pl->num_visible + 1;
+        return TRUE;
+    }
+    else if (up)
+        pl->prev_selected--;
+    else
+        pl->prev_selected++;
+
+    pl->prev_selected =
+        CLAMP(pl->prev_selected, 0, playlist_get_length(playlist) - 1);
+
+    if (pl->prev_selected < pl->first)
+        pl->first--;
+    else if (pl->prev_selected >= (pl->first + pl->num_visible))
+        pl->first++;
+
+    playlist_select_range(playlist, pl->prev_selected, pl->prev_selected, TRUE);
+    pl->prev_min = -1;
+
+    return TRUE;
+}
+
+/* FIXME: Handle the keys through menu */
+
+static gboolean
+playlistwin_keypress(GtkWidget * w, GdkEventKey * event, gpointer data)
+{
+    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), FALSE);
+    Playlist *playlist = playlist_get_active();
+
+    guint keyval;
+    gboolean refresh = FALSE;
+    guint cur_pos;
+
+    if (cfg.playlist_shaded)
+        return FALSE;
+
+    switch (keyval = event->keyval) {
+    case GDK_KP_Up:
+    case GDK_KP_Down:
+    case GDK_Up:
+    case GDK_Down:
+        refresh = playlistwin_keypress_up_down_handler(UI_SKINNED_PLAYLIST(playlistwin_list),
+                                                       keyval == GDK_Up
+                                                       || keyval == GDK_KP_Up,
+                                                       event->state);
+        break;
+    case GDK_Page_Up:
+        playlistwin_scroll(-UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible);
+        refresh = TRUE;
+        break;
+    case GDK_Page_Down:
+        playlistwin_scroll(UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible);
+        refresh = TRUE;
+        break;
+    case GDK_Home:
+        UI_SKINNED_PLAYLIST(playlistwin_list)->first = 0;
+        refresh = TRUE;
+        break;
+    case GDK_End:
+        UI_SKINNED_PLAYLIST(playlistwin_list)->first =
+            playlist_get_length(playlist) - UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible;
+        refresh = TRUE;
+        break;
+    case GDK_Return:
+        if (UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected > -1
+            && playlistwin_item_visible(UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected)) {
+            playlist_set_position(playlist, UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected);
+            if (!playback_get_playing())
+                playback_initiate();
+        }
+        refresh = TRUE;
+        break;
+    case GDK_3:
+        if (event->state & GDK_CONTROL_MASK)
+            playlistwin_fileinfo();
+        break;
+    case GDK_Delete:
+        if (event->state & GDK_CONTROL_MASK)
+            playlist_delete(playlist, TRUE);
+        else
+            playlist_delete(playlist, FALSE);
+        break;
+    case GDK_Insert:
+        if (event->state & GDK_MOD1_MASK)
+            hook_call("urlopener show", NULL);
+        else
+            playlistwin_show_filebrowser();
+        break;
+    case GDK_Left:
+    case GDK_KP_Left:
+    case GDK_KP_7:
+        if (playlist_get_current_length(playlist) != -1)
+            playback_seek(CLAMP
+                              (playback_get_time() - 5000, 0,
+                              playlist_get_current_length(playlist)) / 1000);
+        break;
+    case GDK_Right:
+    case GDK_KP_Right:
+    case GDK_KP_9:
+        if (playlist_get_current_length(playlist) != -1)
+            playback_seek(CLAMP
+                              (playback_get_time() + 5000, 0,
+                              playlist_get_current_length(playlist)) / 1000);
+        break;
+    case GDK_KP_4:
+        playlist_prev(playlist);
+        break;
+    case GDK_KP_6:
+        playlist_next(playlist);
+        break;
+
+    case GDK_Escape:
+        mainwin_minimize_cb();
+        break;
+    case GDK_Tab:
+        if (event->state & GDK_CONTROL_MASK) {
+            if (cfg.player_visible)
+                gtk_window_present(GTK_WINDOW(mainwin));
+            else if (cfg.equalizer_visible)
+                gtk_window_present(GTK_WINDOW(equalizerwin));
+        }
+        break;
+    case GDK_space:
+        cur_pos=playlist_get_position(playlist);
+        UI_SKINNED_PLAYLIST(playlistwin_list)->first =
+            cur_pos - (UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible >> 1);
+        refresh = TRUE;
+        break;
+    default:
+        return FALSE;
+    }
+
+    if (refresh) {
+        g_cond_signal(cond_scan);
+        playlistwin_update_list(playlist_get_active());
+    }
+
+    return TRUE;
+}
+
+void
+playlistwin_hide_timer(void)
+{
+    ui_skinned_textbox_set_text(playlistwin_time_min, "   ");
+    ui_skinned_textbox_set_text(playlistwin_time_sec, "  ");
+}
+
+void
+playlistwin_set_time(gint time, gint length, TimerMode mode)
+{
+    gchar *text, sign;
+
+    if (mode == TIMER_REMAINING && length != -1) {
+        time = length - time;
+        sign = '-';
+    }
+    else
+        sign = ' ';
+
+    time /= 1000;
+
+    if (time < 0)
+        time = 0;
+    if (time > 99 * 60)
+        time /= 60;
+
+    text = g_strdup_printf("%c%-2.2d", sign, time / 60);
+    ui_skinned_textbox_set_text(playlistwin_time_min, text);
+    g_free(text);
+
+    text = g_strdup_printf("%-2.2d", time % 60);
+    ui_skinned_textbox_set_text(playlistwin_time_sec, text);
+    g_free(text);
+}
+
+static void
+playlistwin_drag_motion(GtkWidget * widget,
+                        GdkDragContext * context,
+                        gint x, gint y,
+                        GtkSelectionData * selection_data,
+                        guint info, guint time, gpointer user_data)
+{
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
+        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion = TRUE;
+        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion_x = x;
+        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion_y = y;
+    }
+    playlistwin_update_list(playlist_get_active());
+    playlistwin_hint_flag = TRUE;
+}
+
+static void
+playlistwin_drag_end(GtkWidget * widget,
+                     GdkDragContext * context, gpointer user_data)
+{
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list))
+        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion = FALSE;
+    playlistwin_hint_flag = FALSE;
+    playlistwin_update_list(playlist_get_active());
+}
+
+static void
+playlistwin_drag_data_received(GtkWidget * widget,
+                               GdkDragContext * context,
+                               gint x, gint y,
+                               GtkSelectionData *
+                               selection_data, guint info,
+                               guint time, gpointer user_data)
+{
+    gint pos;
+    Playlist *playlist = playlist_get_active();
+
+    g_return_if_fail(selection_data);
+
+    if (!selection_data->data) {
+        g_message("Received no DND data!");
+        return;
+    }
+    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list) &&
+        (x < playlistwin_get_width() - 20 || y < cfg.playlist_height - 38)) {
+        pos = y / UI_SKINNED_PLAYLIST(playlistwin_list)->fheight + UI_SKINNED_PLAYLIST(playlistwin_list)->first;
+
+        pos = MIN(pos, playlist_get_length(playlist));
+        playlist_ins_url(playlist, (gchar *) selection_data->data, pos);
+    }
+    else
+        playlist_add_url(playlist, (gchar *) selection_data->data);
+}
+
+static void
+local_playlist_prev(void)
+{
+    playlist_prev(playlist_get_active());
+}
+
+static void
+local_playlist_next(void)
+{
+    playlist_next(playlist_get_active());
+}
+
+static void
+playlistwin_create_widgets(void)
+{
+    /* This function creates the custom widgets used by the playlist editor */
+
+    /* text box for displaying song title in shaded mode */
+    playlistwin_sinfo = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
+                                               4, 4, playlistwin_get_width() - 35, TRUE, SKIN_TEXT);
+
+    playlistwin_set_sinfo_font(cfg.playlist_font);
+
+    playlistwin_shade = ui_skinned_button_new();
+    /* shade/unshade window push button */
+    if (cfg.playlist_shaded)
+        ui_skinned_push_button_setup(playlistwin_shade, SKINNED_WINDOW(playlistwin)->fixed,
+                                     playlistwin_get_width() - 21, 3,
+                                     9, 9, 128, 45, 150, 42, SKIN_PLEDIT);
+    else
+        ui_skinned_push_button_setup(playlistwin_shade, SKINNED_WINDOW(playlistwin)->fixed,
+                                     playlistwin_get_width() - 21, 3,
+                                     9, 9, 157, 3, 62, 42, SKIN_PLEDIT);
+
+    g_signal_connect(playlistwin_shade, "clicked", playlistwin_shade_toggle, NULL );
+
+    /* close window push button */
+    playlistwin_close = ui_skinned_button_new();
+    ui_skinned_push_button_setup(playlistwin_close, SKINNED_WINDOW(playlistwin)->fixed,
+                                 playlistwin_get_width() - 11, 3, 9, 9,
+                                 cfg.playlist_shaded ? 138 : 167,
+                                 cfg.playlist_shaded ? 45 : 3, 52, 42, SKIN_PLEDIT);
+
+    g_signal_connect(playlistwin_close, "clicked", playlistwin_hide, NULL );
+
+    /* playlist list box */
+    playlistwin_list = ui_skinned_playlist_new(SKINNED_WINDOW(playlistwin)->fixed, 12, 20,
+                             playlistwin_get_width() - 31,
+                             cfg.playlist_height - 58);
+    ui_skinned_playlist_set_font(cfg.playlist_font);
+
+    /* playlist list box slider */
+    playlistwin_slider = ui_skinned_playlist_slider_new(SKINNED_WINDOW(playlistwin)->fixed, playlistwin_get_width() - 15,
+                              20, cfg.playlist_height - 58);
+
+    /* track time (minute) */
+    playlistwin_time_min = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
+                       playlistwin_get_width() - 82,
+                       cfg.playlist_height - 15, 15, FALSE, SKIN_TEXT);
+    g_signal_connect(playlistwin_time_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    /* track time (second) */
+    playlistwin_time_sec = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
+                       playlistwin_get_width() - 64,
+                       cfg.playlist_height - 15, 10, FALSE, SKIN_TEXT);
+    g_signal_connect(playlistwin_time_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
+
+    /* playlist information (current track length / total track length) */
+    playlistwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
+                       playlistwin_get_width() - 143,
+                       cfg.playlist_height - 28, 90, FALSE, SKIN_TEXT);
+
+    /* mini play control buttons at right bottom corner */
+
+    /* rewind button */
+    playlistwin_srew = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_srew, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 144,
+                                  cfg.playlist_height - 16, 8, 7);
+    g_signal_connect(playlistwin_srew, "clicked", local_playlist_prev, NULL);
+
+    /* play button */
+    playlistwin_splay = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_splay, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 138,
+                                  cfg.playlist_height - 16, 10, 7);
+    g_signal_connect(playlistwin_splay, "clicked", mainwin_play_pushed, NULL);
+
+    /* pause button */
+    playlistwin_spause = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_spause, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 128,
+                                  cfg.playlist_height - 16, 10, 7);
+    g_signal_connect(playlistwin_spause, "clicked", playback_pause, NULL);
+
+    /* stop button */
+    playlistwin_sstop = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_sstop, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 118,
+                                  cfg.playlist_height - 16, 9, 7);
+    g_signal_connect(playlistwin_sstop, "clicked", mainwin_stop_pushed, NULL);
+
+    /* forward button */
+    playlistwin_sfwd = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_sfwd, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 109,
+                                  cfg.playlist_height - 16, 8, 7);
+    g_signal_connect(playlistwin_sfwd, "clicked", local_playlist_next, NULL);
+
+    /* eject button */
+    playlistwin_seject = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_seject, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 100,
+                                  cfg.playlist_height - 16, 9, 7);
+    g_signal_connect(playlistwin_seject, "clicked", mainwin_eject_pushed, NULL);
+
+    playlistwin_sscroll_up = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_sscroll_up, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 14,
+                                  cfg.playlist_height - 35, 8, 5);
+    g_signal_connect(playlistwin_sscroll_up, "clicked", playlistwin_scroll_up_pushed, NULL);
+
+    playlistwin_sscroll_down = ui_skinned_button_new();
+    ui_skinned_small_button_setup(playlistwin_sscroll_down, SKINNED_WINDOW(playlistwin)->fixed,
+                                  playlistwin_get_width() - 14,
+                                  cfg.playlist_height - 30, 8, 5);
+    g_signal_connect(playlistwin_sscroll_down, "clicked", playlistwin_scroll_down_pushed, NULL);
+
+    ui_playlist_evlistener_init();
+}
+
+static void
+selection_received(GtkWidget * widget,
+                   GtkSelectionData * selection_data, gpointer data)
+{
+    if (selection_data->type == GDK_SELECTION_TYPE_STRING &&
+        selection_data->length > 0)
+        playlist_add_url(playlist_get_active(), (gchar *) selection_data->data);
+}
+
+static void
+playlistwin_create_window(void)
+{
+    GdkPixbuf *icon;
+
+    playlistwin = ui_skinned_window_new("playlist");
+    gtk_window_set_title(GTK_WINDOW(playlistwin), _("Audacious Playlist Editor"));
+    gtk_window_set_role(GTK_WINDOW(playlistwin), "playlist");
+    gtk_window_set_default_size(GTK_WINDOW(playlistwin),
+                                playlistwin_get_width(),
+                                playlistwin_get_height());
+    gtk_window_set_resizable(GTK_WINDOW(playlistwin), TRUE);
+    playlistwin_set_geometry_hints(cfg.playlist_shaded);
+
+    gtk_window_set_transient_for(GTK_WINDOW(playlistwin),
+                                 GTK_WINDOW(mainwin));
+    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(playlistwin), TRUE);
+
+    icon = gdk_pixbuf_new_from_xpm_data((const gchar **) audacious_playlist_icon);
+    gtk_window_set_icon(GTK_WINDOW(playlistwin), icon);
+    g_object_unref(icon);
+
+    if (cfg.playlist_x != -1 && cfg.save_window_position)
+        gtk_window_move(GTK_WINDOW(playlistwin),
+                        cfg.playlist_x, cfg.playlist_y);
+
+    gtk_widget_add_events(playlistwin, GDK_POINTER_MOTION_MASK |
+                          GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK |
+                          GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+                          GDK_SCROLL_MASK | GDK_VISIBILITY_NOTIFY_MASK);
+    gtk_widget_realize(playlistwin);
+
+    g_signal_connect(playlistwin, "delete_event",
+                     G_CALLBACK(playlistwin_delete), NULL);
+    g_signal_connect(playlistwin, "button_press_event",
+                     G_CALLBACK(playlistwin_press), NULL);
+    g_signal_connect(playlistwin, "button_release_event",
+                     G_CALLBACK(playlistwin_release), NULL);
+    g_signal_connect(playlistwin, "scroll_event",
+                     G_CALLBACK(playlistwin_scrolled), NULL);
+    g_signal_connect(playlistwin, "motion_notify_event",
+                     G_CALLBACK(playlistwin_motion), NULL);
+
+    aud_drag_dest_set(playlistwin);
+
+    /* DnD stuff */
+    g_signal_connect(playlistwin, "drag-leave",
+                     G_CALLBACK(playlistwin_drag_end), NULL);
+    g_signal_connect(playlistwin, "drag-data-delete",
+                     G_CALLBACK(playlistwin_drag_end), NULL);
+    g_signal_connect(playlistwin, "drag-end",
+                     G_CALLBACK(playlistwin_drag_end), NULL);
+    g_signal_connect(playlistwin, "drag-drop",
+                     G_CALLBACK(playlistwin_drag_end), NULL);
+    g_signal_connect(playlistwin, "drag-data-received",
+                     G_CALLBACK(playlistwin_drag_data_received), NULL);
+    g_signal_connect(playlistwin, "drag-motion",
+                     G_CALLBACK(playlistwin_drag_motion), NULL);
+
+    g_signal_connect(playlistwin, "key_press_event",
+                     G_CALLBACK(playlistwin_keypress), NULL);
+    g_signal_connect(playlistwin, "selection_received",
+                     G_CALLBACK(selection_received), NULL);
+}
+
+void
+playlistwin_create(void)
+{
+    resize_mutex = g_mutex_new();
+    playlistwin_create_window();
+
+    playlistwin_create_widgets();
+    playlistwin_update_info(playlist_get_active());
+
+    gtk_window_add_accel_group(GTK_WINDOW(playlistwin), ui_manager_get_accel_group());
+}
+
+
+void
+playlistwin_show(void)
+{
+    gtk_window_move(GTK_WINDOW(playlistwin), cfg.playlist_x, cfg.playlist_y);
+    GtkAction *action = gtk_action_group_get_action(
+      toggleaction_group_others , "show playlist editor" );
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , TRUE );
+
+    cfg.playlist_visible = TRUE;
+    UI_SKINNED_BUTTON(mainwin_pl)->inside = TRUE;
+    gtk_widget_queue_draw(mainwin_pl);
+
+    playlistwin_set_toprow(0);
+    playlist_check_pos_current(playlist_get_active());
+
+    gtk_widget_show_all(playlistwin);
+    if (!cfg.playlist_shaded)
+        gtk_widget_hide(playlistwin_sinfo);
+    gtk_window_present(GTK_WINDOW(playlistwin));
+}
+
+void
+playlistwin_hide(void)
+{
+    GtkAction *action = gtk_action_group_get_action(
+      toggleaction_group_others , "show playlist editor" );
+    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , FALSE );
+
+    gtk_widget_hide(playlistwin);
+    cfg.playlist_visible = FALSE;
+    UI_SKINNED_BUTTON(mainwin_pl)->inside = FALSE;
+    gtk_widget_queue_draw(mainwin_pl);
+
+    if ( cfg.player_visible )
+    {
+      gtk_window_present(GTK_WINDOW(mainwin));
+      gtk_widget_grab_focus(mainwin);
+    }
+}
+
+void action_playlist_track_info(void)
+{
+    playlistwin_fileinfo();
+}
+
+void action_queue_toggle(void)
+{
+    playlist_queue(playlist_get_active());
+}
+
+void action_playlist_sort_by_playlist_entry(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort(playlist, PLAYLIST_SORT_PLAYLIST);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_by_track_number(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort(playlist, PLAYLIST_SORT_TRACK);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_by_title(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort(playlist, PLAYLIST_SORT_TITLE);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_by_artist(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort(playlist, PLAYLIST_SORT_ARTIST);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_by_full_path(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort(playlist, PLAYLIST_SORT_PATH);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_by_date(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort(playlist, PLAYLIST_SORT_DATE);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_by_filename(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort(playlist, PLAYLIST_SORT_FILENAME);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_selected_by_playlist_entry(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort_selected(playlist, PLAYLIST_SORT_PLAYLIST);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_selected_by_track_number(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort_selected(playlist, PLAYLIST_SORT_TRACK);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_selected_by_title(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort_selected(playlist, PLAYLIST_SORT_TITLE);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_selected_by_artist(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort_selected(playlist, PLAYLIST_SORT_ARTIST);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_selected_by_full_path(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort_selected(playlist, PLAYLIST_SORT_PATH);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_selected_by_date(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort_selected(playlist, PLAYLIST_SORT_DATE);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_sort_selected_by_filename(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_sort_selected(playlist, PLAYLIST_SORT_FILENAME);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_randomize_list(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_random(playlist);
+    playlistwin_update_list(playlist);
+}
+
+void action_playlist_reverse_list(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_reverse(playlist);
+    playlistwin_update_list(playlist);
+}
+
+void
+action_playlist_clear_queue(void)
+{
+    playlist_clear_queue(playlist_get_active());
+}
+
+void
+action_playlist_remove_unavailable(void)
+{
+    playlist_remove_dead_files(playlist_get_active());
+}
+
+void
+action_playlist_remove_dupes_by_title(void)
+{
+    playlist_remove_duplicates(playlist_get_active(), PLAYLIST_DUPS_TITLE);
+}
+
+void
+action_playlist_remove_dupes_by_filename(void)
+{
+    playlist_remove_duplicates(playlist_get_active(), PLAYLIST_DUPS_FILENAME);
+}
+
+void
+action_playlist_remove_dupes_by_full_path(void)
+{
+    playlist_remove_duplicates(playlist_get_active(), PLAYLIST_DUPS_PATH);
+}
+
+void
+action_playlist_remove_all(void)
+{
+    playlist_clear(playlist_get_active());
+
+    /* XXX -- should this really be coupled here? -nenolod */
+    mainwin_clear_song_info();
+}
+
+void
+action_playlist_remove_selected(void)
+{
+    playlist_delete(playlist_get_active(), FALSE);
+}
+
+void
+action_playlist_remove_unselected(void)
+{
+    playlist_delete(playlist_get_active(), TRUE);
+}
+
+void
+action_playlist_add_files(void)
+{
+    run_filebrowser(FALSE);
+}
+
+void
+action_playlist_add_url(void)
+{
+    hook_call("urlopener show", NULL);
+}
+
+void
+action_playlist_new( void )
+{
+  Playlist *new_pl = playlist_new();
+  playlist_add_playlist(new_pl);
+  playlist_select_playlist(new_pl);
+}
+
+void
+action_playlist_prev( void )
+{
+    playlist_select_prev();
+}
+
+void
+action_playlist_next( void )
+{
+    playlist_select_next();
+}
+
+void
+action_playlist_delete( void )
+{
+    playlist_remove_playlist( playlist_get_active() );
+}
+
+void
+action_playlist_save_list(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlistwin_select_playlist_to_save(playlist_get_current_name(playlist));
+}
+
+void
+action_playlist_save_default_list(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_save(playlist, aud_paths[BMP_PATH_PLAYLIST_FILE]);
+}
+
+void
+action_playlist_load_list(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlistwin_select_playlist_to_load(playlist_get_current_name(playlist));
+}
+
+void
+action_playlist_refresh_list(void)
+{
+    Playlist *playlist = playlist_get_active();
+
+    playlist_read_info_selection(playlist);
+    playlistwin_update_list(playlist);
+}
+
+void
+action_open_list_manager(void)
+{
+    playlist_manager_ui_show();
+}
+
+void
+action_playlist_search_and_select(void)
+{
+    playlistwin_select_search();
+}
+
+void
+action_playlist_invert_selection(void)
+{
+    playlistwin_inverse_selection();
+}
+
+void
+action_playlist_select_none(void)
+{
+    playlistwin_select_none();
+}
+
+void
+action_playlist_select_all(void)
+{
+    playlistwin_select_all();
+}
+
+
+static void
+playlistwin_select_search_cbt_cb(GtkWidget *called_cbt, gpointer other_cbt)
+{
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(called_cbt)) == TRUE)
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_cbt), FALSE);
+    return;
+}
+
+static gboolean
+playlistwin_select_search_kp_cb(GtkWidget *entry, GdkEventKey *event,
+                                gpointer searchdlg_win)
+{
+    switch (event->keyval)
+    {
+        case GDK_Return:
+            if (gtk_im_context_filter_keypress (GTK_ENTRY (entry)->im_context, event)) {
+                GTK_ENTRY (entry)->need_im_reset = TRUE;
+                return TRUE;
+            } else {
+                gtk_dialog_response(GTK_DIALOG(searchdlg_win), GTK_RESPONSE_ACCEPT);
+                return TRUE;
+            }
+        default:
+            return FALSE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_playlist.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,80 @@
+/*  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_PLAYLIST_H
+#define AUDACIOUS_UI_PLAYLIST_H
+
+#include <glib.h>
+
+#include "ui_main.h"
+#include "playlist.h"
+
+#define PLAYLISTWIN_FRAME_TOP_HEIGHT    20
+#define PLAYLISTWIN_FRAME_BOTTOM_HEIGHT 38
+#define PLAYLISTWIN_FRAME_LEFT_WIDTH    12
+#define PLAYLISTWIN_FRAME_RIGHT_WIDTH   19
+
+#define PLAYLISTWIN_MIN_WIDTH           MAINWIN_WIDTH
+#define PLAYLISTWIN_MIN_HEIGHT          MAINWIN_HEIGHT
+#define PLAYLISTWIN_WIDTH_SNAP          25
+#define PLAYLISTWIN_HEIGHT_SNAP         29
+#define PLAYLISTWIN_SHADED_HEIGHT       MAINWIN_SHADED_HEIGHT
+#define PLAYLISTWIN_WIDTH               cfg.playlist_width
+#define PLAYLISTWIN_HEIGHT \
+    (cfg.playlist_shaded ? PLAYLISTWIN_SHADED_HEIGHT : cfg.playlist_height)
+
+#define PLAYLISTWIN_DEFAULT_WIDTH       275
+#define PLAYLISTWIN_DEFAULT_HEIGHT      232
+#define PLAYLISTWIN_DEFAULT_POS_X       295
+#define PLAYLISTWIN_DEFAULT_POS_Y       20
+
+#define PLAYLISTWIN_DEFAULT_FONT        "Sans Bold 8"
+
+gboolean playlistwin_is_shaded(void);
+gint playlistwin_get_width(void);
+gint playlistwin_get_height(void);
+void playlistwin_update_list(Playlist *playlist);
+gboolean playlistwin_item_visible(gint index);
+gint playlistwin_get_toprow(void);
+void playlistwin_set_toprow(gint top);
+void playlistwin_set_shade_menu_cb(gboolean shaded);
+void playlistwin_set_shade(gboolean shaded);
+void playlistwin_shade_toggle(void);
+void playlistwin_create(void);
+void playlistwin_hide_timer(void);
+void playlistwin_set_time(gint time, gint length, TimerMode mode);
+void playlistwin_show(void);
+void playlistwin_hide(void);
+void playlistwin_scroll(gint num);
+void playlistwin_scroll_up_pushed(void);
+void playlistwin_scroll_down_pushed(void);
+void playlistwin_select_playlist_to_load(const gchar * default_filename);
+void playlistwin_set_sinfo_font(gchar *font);
+void playlistwin_set_sinfo_scroll(gboolean scroll);
+gint playlistwin_list_get_visible_count(void);
+gint playlistwin_list_get_first(void);
+
+extern GtkWidget *playlistwin;
+
+extern gboolean playlistwin_focus;
+
+#endif /* AUDACIOUS_UI_PLAYLIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_playlist_evlisteners.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,54 @@
+/*
+ * Audacious
+ * Copyright (c) 2006-2007 Audacious development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_playlist_evlisteners.h"
+
+#include <glib.h>
+
+#include "hook.h"
+#include "playlist.h"
+#include "ui_playlist.h"
+#include "ui_playlist_manager.h"
+
+static void
+ui_playlist_evlistener_playlist_update(gpointer hook_data, gpointer user_data)
+{
+    Playlist *playlist = (Playlist *) hook_data;
+    if (playlist != NULL)
+        playlistwin_update_list(playlist);
+
+    playlist_manager_update();
+}
+
+static void
+ui_playlist_evlistener_playlistwin_show(gpointer hook_data, gpointer user_data)
+{
+    gboolean *show = (gboolean*)hook_data;
+    if (*show == TRUE)
+        playlistwin_show();
+    else
+        playlistwin_hide();
+}
+
+void ui_playlist_evlistener_init(void)
+{
+    hook_associate("playlist update", ui_playlist_evlistener_playlist_update, NULL);
+    hook_associate("playlistwin show", ui_playlist_evlistener_playlistwin_show, NULL);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_playlist_evlisteners.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,26 @@
+/*
+ * Audacious
+ * Copyright (c) 2006-2007 Audacious development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H
+#define AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H
+
+void ui_playlist_evlistener_init(void);
+
+#endif /* AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_playlist_manager.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,498 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_playlist_manager.h"
+#include "ui_playlist.h"
+#include "playlist.h"
+#include "ui_main.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+
+#define DISABLE_MANAGER_UPDATE() g_object_set_data(G_OBJECT(listview),"opt1",GINT_TO_POINTER(1))
+#define ENABLE_MANAGER_UPDATE() g_object_set_data(G_OBJECT(listview),"opt1",GINT_TO_POINTER(0))
+
+
+static GtkWidget *playman_win = NULL;
+
+
+/* in this enum, place the columns according to visualization order
+   (information not displayed in columns should be placed right before PLLIST_NUMCOLS) */
+enum
+{
+    PLLIST_COL_NAME = 0,
+    PLLIST_COL_ENTRIESNUM,
+    PLLIST_PLPOINTER,
+    PLLIST_TEXT_WEIGHT,
+    PLLIST_NUMCOLS
+};
+
+
+static GtkTreeIter
+playlist_manager_populate ( GtkListStore * store )
+{
+    GList *playlists = NULL;
+    Playlist *active, *iter_playlist, *next_playlist;
+    GtkTreeIter iter, insert, next, active_iter;
+    gboolean valid, have_active_iter;
+
+    active = playlist_get_active();
+    playlists = playlist_get_playlists();
+    valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(store) , &iter );
+    have_active_iter = FALSE;
+    while ( playlists != NULL )
+    {
+        GList *entries = NULL;
+        gint entriesnum = 0;
+        gchar *pl_name = NULL;
+        Playlist *playlist = (Playlist*)playlists->data;
+
+        if(playlist != active) //XXX the active playlist has been locked in playlist_new_from_selected()
+            PLAYLIST_LOCK(playlist);
+
+        /* for each playlist, pick name and number of entries */
+        pl_name = (gchar*)playlist_get_current_name( playlist );
+        for (entries = playlist->entries; entries; entries = g_list_next(entries))
+            entriesnum++;
+
+        if(playlist != active)
+            PLAYLIST_UNLOCK(playlist);
+
+        /* update the tree model conservatively */
+
+        if ( !valid )
+        {
+            /* append */
+            gtk_list_store_append( store , &insert );
+            goto store_set;
+        }
+
+        gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter ,
+                PLLIST_PLPOINTER , &iter_playlist , -1 );
+
+        if ( playlist == iter_playlist )
+        {
+            /* already have - just update */
+            insert = iter;
+            valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(store) , &iter );
+            goto store_set;
+        }
+
+        /* handle movement/deletion/insertion of single elements */
+        if ( gtk_tree_model_iter_next( GTK_TREE_MODEL(store) , &next ) )
+        {
+            gtk_tree_model_get( GTK_TREE_MODEL(store) , &next ,
+                    PLLIST_PLPOINTER , &next_playlist , -1 );
+            if ( playlist == next_playlist )
+            {
+                /* remove */
+                gtk_list_store_remove( store , &iter );
+                iter = next;
+                valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
+                goto next_playlist;
+            }
+        }
+
+        /* insert */
+        gtk_list_store_insert_before( store , &insert , &iter );
+
+store_set:
+        gtk_list_store_set( store, &insert,
+                            PLLIST_COL_NAME , pl_name ,
+                            PLLIST_COL_ENTRIESNUM , entriesnum ,
+                            PLLIST_PLPOINTER , playlist ,
+                            PLLIST_TEXT_WEIGHT , playlist == active ?
+                                PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL ,
+                            -1 );
+        if ( !have_active_iter && playlist == active )
+        {
+            active_iter = insert;
+            have_active_iter = TRUE;
+        }
+
+next_playlist:
+        playlists = g_list_next(playlists);
+    }
+
+    while (valid)
+    {
+        /* remove any other elements */
+        next = iter;
+        valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(store) , &next );
+        gtk_list_store_remove( store , &iter );
+        iter = next;
+    }
+
+    if ( !have_active_iter )
+        gtk_tree_model_get_iter_first( GTK_TREE_MODEL(store) , &active_iter );
+
+    return active_iter;
+}
+
+
+static void
+playlist_manager_cb_new ( gpointer listview )
+{
+    GList *playlists = NULL;
+    Playlist *newpl = NULL;
+    GtkTreeIter iter;
+    GtkListStore *store;
+    gchar *pl_name = NULL;
+
+    /* this ensures that playlist_manager_update() will
+       not perform update, since we're already doing it here */
+    DISABLE_MANAGER_UPDATE();
+
+    newpl = playlist_new();
+    pl_name = (gchar*)playlist_get_current_name( newpl );
+    playlists = playlist_get_playlists();
+    playlist_add_playlist( newpl );
+
+    store = (GtkListStore*)gtk_tree_view_get_model( GTK_TREE_VIEW(listview) );
+    gtk_list_store_append( store , &iter );
+    gtk_list_store_set( store, &iter,
+                        PLLIST_COL_NAME , pl_name ,
+                        PLLIST_COL_ENTRIESNUM , 0 ,
+                        PLLIST_PLPOINTER , newpl ,
+                        PLLIST_TEXT_WEIGHT , PANGO_WEIGHT_NORMAL ,
+                        -1 );
+
+    ENABLE_MANAGER_UPDATE();
+
+    return;
+}
+
+
+static void
+playlist_manager_cb_del ( gpointer listview )
+{
+    GtkTreeSelection *listsel = gtk_tree_view_get_selection( GTK_TREE_VIEW(listview) );
+    GtkTreeModel *store;
+    GtkTreeIter iter;
+    Playlist *active;
+    gboolean was_active;
+
+    if ( gtk_tree_selection_get_selected( listsel , &store , &iter ) == TRUE )
+    {
+        Playlist *playlist = NULL;
+        gtk_tree_model_get( store, &iter, PLLIST_PLPOINTER , &playlist , -1 );
+
+        active = playlist_get_active();
+        was_active = ( playlist == active );
+
+        if ( gtk_tree_model_iter_n_children( store , NULL ) < 2 )
+        {
+            /* let playlist_manager_update() handle the deletion of the last playlist */
+            playlist_remove_playlist( playlist );
+        }
+        else
+        {
+            gtk_list_store_remove( (GtkListStore*)store , &iter );
+            /* this ensures that playlist_manager_update() will
+               not perform update, since we're already doing it here */
+            DISABLE_MANAGER_UPDATE();
+            playlist_remove_playlist( playlist );
+            ENABLE_MANAGER_UPDATE();
+        }
+
+        if ( was_active && gtk_tree_model_get_iter_first( store , &iter ) )
+        {
+            /* update bolded playlist */
+            active = playlist_get_active();
+            do {
+                gtk_tree_model_get( store , &iter ,
+                        PLLIST_PLPOINTER , &playlist , -1 );
+                gtk_list_store_set( GTK_LIST_STORE(store) , &iter ,
+                        PLLIST_TEXT_WEIGHT , playlist == active ?
+                            PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL ,
+                       -1 );
+            } while ( gtk_tree_model_iter_next( store , &iter ) );
+        }
+    }
+
+    return;
+}
+
+
+static void
+playlist_manager_cb_lv_dclick ( GtkTreeView * listview , GtkTreePath * path ,
+                                GtkTreeViewColumn * col , gpointer userdata )
+{
+    GtkTreeModel *store;
+    GtkTreeIter iter;
+    Playlist *playlist = NULL, *active;
+
+    store = gtk_tree_view_get_model( GTK_TREE_VIEW(listview) );
+    if ( gtk_tree_model_get_iter( store , &iter , path ) == TRUE )
+    {
+        gtk_tree_model_get( store , &iter , PLLIST_PLPOINTER , &playlist , -1 );
+        DISABLE_MANAGER_UPDATE();
+        playlist_select_playlist( playlist );
+        ENABLE_MANAGER_UPDATE();
+    }
+
+    if ( gtk_tree_model_get_iter_first( store , &iter ) )
+    {
+        /* update bolded playlist */
+        active = playlist_get_active();
+        do {
+            gtk_tree_model_get( store , &iter ,
+                    PLLIST_PLPOINTER , &playlist , -1 );
+            gtk_list_store_set( GTK_LIST_STORE(store) , &iter ,
+                    PLLIST_TEXT_WEIGHT , playlist == active ?
+                        PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL ,
+                   -1 );
+        } while ( gtk_tree_model_iter_next( store , &iter ) );
+    }
+
+    return;
+}
+
+
+static void
+playlist_manager_cb_lv_pmenu_rename ( GtkMenuItem *menuitem , gpointer lv )
+{
+    GtkTreeSelection *listsel = gtk_tree_view_get_selection( GTK_TREE_VIEW(lv) );
+    GtkTreeModel *store;
+    GtkTreeIter iter;
+
+    if ( gtk_tree_selection_get_selected( listsel , &store , &iter ) == TRUE )
+    {
+        GtkTreePath *path = gtk_tree_model_get_path( GTK_TREE_MODEL(store) , &iter );
+        GtkCellRenderer *rndrname = g_object_get_data( G_OBJECT(lv) , "rn" );
+        /* set the name renderer to editable and start editing */
+        g_object_set( G_OBJECT(rndrname) , "editable" , TRUE , NULL );
+        gtk_tree_view_set_cursor_on_cell( GTK_TREE_VIEW(lv) , path ,
+                                          gtk_tree_view_get_column( GTK_TREE_VIEW(lv) , PLLIST_COL_NAME ) , rndrname , TRUE );
+        gtk_tree_path_free( path );
+    }
+}
+
+static void
+playlist_manager_cb_lv_name_edited ( GtkCellRendererText *cell , gchar *path_string ,
+                                     gchar *new_text , gpointer listview )
+{
+    /* this is currently used to change playlist names */
+    GtkTreeModel *store = gtk_tree_view_get_model( GTK_TREE_VIEW(listview) );
+    GtkTreeIter iter;
+
+    if ( gtk_tree_model_get_iter_from_string( store , &iter , path_string ) == TRUE )
+    {
+        Playlist *playlist = NULL;
+        gtk_tree_model_get( GTK_TREE_MODEL(store), &iter, PLLIST_PLPOINTER , &playlist , -1 );
+        DISABLE_MANAGER_UPDATE();
+        playlist_set_current_name( playlist , new_text );
+        ENABLE_MANAGER_UPDATE();
+        gtk_list_store_set( GTK_LIST_STORE(store), &iter, PLLIST_COL_NAME , new_text , -1 );
+    }
+    /* set the renderer uneditable again */
+    g_object_set( G_OBJECT(cell) , "editable" , FALSE , NULL );
+}
+
+
+static gboolean
+playlist_manager_cb_lv_btpress ( GtkWidget *lv , GdkEventButton *event )
+{
+    if (( event->type == GDK_BUTTON_PRESS ) && ( event->button == 3 ))
+    {
+        GtkWidget *pmenu = (GtkWidget*)g_object_get_data( G_OBJECT(lv) , "menu" );
+        gtk_menu_popup( GTK_MENU(pmenu) , NULL , NULL , NULL , NULL ,
+                        (event != NULL) ? event->button : 0,
+                        event->time);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+static gboolean
+playlist_manager_cb_keypress ( GtkWidget *win , GdkEventKey *event )
+{
+    switch (event->keyval)
+    {
+        case GDK_Escape:
+            gtk_widget_destroy( playman_win );
+            return TRUE;
+        default:
+            return FALSE;
+    }
+}
+
+
+void
+playlist_manager_ui_show ( void )
+{
+    GtkWidget *playman_vbox;
+    GtkWidget *playman_pl_lv, *playman_pl_lv_frame, *playman_pl_lv_sw;
+    GtkCellRenderer *playman_pl_lv_textrndr_name, *playman_pl_lv_textrndr_entriesnum;
+    GtkTreeViewColumn *playman_pl_lv_col_name, *playman_pl_lv_col_entriesnum;
+    GtkListStore *pl_store;
+    GtkWidget *playman_pl_lv_pmenu, *playman_pl_lv_pmenu_rename;
+    GtkWidget *playman_bbar_hbbox;
+    GtkWidget *playman_bbar_bt_new, *playman_bbar_bt_del, *playman_bbar_bt_close;
+    GdkGeometry playman_win_hints;
+    GtkTreeIter active_iter;
+    GtkTreePath *active_path;
+
+    if ( playman_win != NULL )
+    {
+        gtk_window_present( GTK_WINDOW(playman_win) );
+        return;
+    }
+
+    playman_win = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+    gtk_window_set_type_hint( GTK_WINDOW(playman_win), GDK_WINDOW_TYPE_HINT_DIALOG );
+    gtk_window_set_transient_for( GTK_WINDOW(playman_win) , GTK_WINDOW(mainwin) );
+    gtk_window_set_position( GTK_WINDOW(playman_win), GTK_WIN_POS_CENTER );
+    gtk_window_set_title( GTK_WINDOW(playman_win), _("Playlist Manager") );
+    gtk_container_set_border_width( GTK_CONTAINER(playman_win), 10 );
+    g_signal_connect( G_OBJECT(playman_win) , "destroy" ,
+                      G_CALLBACK(gtk_widget_destroyed) , &playman_win );
+    g_signal_connect( G_OBJECT(playman_win) , "key-press-event" ,
+                      G_CALLBACK(playlist_manager_cb_keypress) , NULL );
+    playman_win_hints.min_width = 400;
+    playman_win_hints.min_height = 250;
+    gtk_window_set_geometry_hints( GTK_WINDOW(playman_win) , GTK_WIDGET(playman_win) ,
+                                   &playman_win_hints , GDK_HINT_MIN_SIZE );
+
+    playman_vbox = gtk_vbox_new( FALSE , 10 );
+    gtk_container_add( GTK_CONTAINER(playman_win) , playman_vbox );
+
+    /* current liststore model
+       ----------------------------------------------
+       G_TYPE_STRING -> playlist name
+       G_TYPE_UINT -> number of entries in playlist
+       G_TYPE_POINTER -> playlist pointer (Playlist*)
+       PANGO_TYPE_WEIGHT -> font weight
+       ----------------------------------------------
+       */
+    pl_store = gtk_list_store_new( PLLIST_NUMCOLS ,
+            G_TYPE_STRING , G_TYPE_UINT , G_TYPE_POINTER , PANGO_TYPE_WEIGHT );
+    active_iter = playlist_manager_populate( pl_store );
+
+    playman_pl_lv_frame = gtk_frame_new( NULL );
+    playman_pl_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(pl_store) );
+
+    g_object_set_data( G_OBJECT(playman_win) , "lv" , playman_pl_lv );
+    g_object_set_data( G_OBJECT(playman_pl_lv) , "opt1" , GINT_TO_POINTER(0) );
+    playman_pl_lv_textrndr_entriesnum = gtk_cell_renderer_text_new(); /* uneditable */
+    playman_pl_lv_textrndr_name = gtk_cell_renderer_text_new(); /* can become editable */
+    g_object_set( G_OBJECT(playman_pl_lv_textrndr_entriesnum) , "weight-set" , TRUE , NULL );
+    g_object_set( G_OBJECT(playman_pl_lv_textrndr_name) , "weight-set" , TRUE , NULL );
+    g_signal_connect( G_OBJECT(playman_pl_lv_textrndr_name) , "edited" ,
+                      G_CALLBACK(playlist_manager_cb_lv_name_edited) , playman_pl_lv );
+    g_object_set_data( G_OBJECT(playman_pl_lv) , "rn" , playman_pl_lv_textrndr_name );
+    playman_pl_lv_col_name = gtk_tree_view_column_new_with_attributes(
+            _("Playlist") , playman_pl_lv_textrndr_name ,
+            "text" , PLLIST_COL_NAME ,
+            "weight", PLLIST_TEXT_WEIGHT ,
+            NULL );
+    gtk_tree_view_column_set_expand( GTK_TREE_VIEW_COLUMN(playman_pl_lv_col_name) , TRUE );
+    gtk_tree_view_append_column( GTK_TREE_VIEW(playman_pl_lv), playman_pl_lv_col_name );
+    playman_pl_lv_col_entriesnum = gtk_tree_view_column_new_with_attributes(
+            _("Entries") , playman_pl_lv_textrndr_entriesnum ,
+            "text" , PLLIST_COL_ENTRIESNUM ,
+            "weight", PLLIST_TEXT_WEIGHT ,
+            NULL );
+    gtk_tree_view_column_set_expand( GTK_TREE_VIEW_COLUMN(playman_pl_lv_col_entriesnum) , FALSE );
+    gtk_tree_view_append_column( GTK_TREE_VIEW(playman_pl_lv), playman_pl_lv_col_entriesnum );
+    playman_pl_lv_sw = gtk_scrolled_window_new( NULL , NULL );
+    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(playman_pl_lv_sw) ,
+                                    GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
+    gtk_container_add( GTK_CONTAINER(playman_pl_lv_sw) , playman_pl_lv );
+    gtk_container_add( GTK_CONTAINER(playman_pl_lv_frame) , playman_pl_lv_sw );
+    gtk_box_pack_start( GTK_BOX(playman_vbox) , playman_pl_lv_frame , TRUE , TRUE , 0 );
+
+    /* listview popup menu */
+    playman_pl_lv_pmenu = gtk_menu_new();
+    playman_pl_lv_pmenu_rename = gtk_menu_item_new_with_mnemonic( _( "_Rename" ) );
+    g_signal_connect( G_OBJECT(playman_pl_lv_pmenu_rename) , "activate" ,
+                      G_CALLBACK(playlist_manager_cb_lv_pmenu_rename) , playman_pl_lv );
+    gtk_menu_shell_append( GTK_MENU_SHELL(playman_pl_lv_pmenu) , playman_pl_lv_pmenu_rename );
+    gtk_widget_show_all( playman_pl_lv_pmenu );
+    g_object_set_data( G_OBJECT(playman_pl_lv) , "menu" , playman_pl_lv_pmenu );
+    g_signal_connect_swapped( G_OBJECT(playman_win) , "destroy" ,
+                              G_CALLBACK(gtk_widget_destroy) , playman_pl_lv_pmenu );
+
+    /* button bar */
+    playman_bbar_hbbox = gtk_hbutton_box_new();
+    gtk_button_box_set_layout( GTK_BUTTON_BOX(playman_bbar_hbbox) , GTK_BUTTONBOX_END );
+	gtk_button_box_set_spacing(GTK_BUTTON_BOX(playman_bbar_hbbox), 5);
+    playman_bbar_bt_close = gtk_button_new_from_stock( GTK_STOCK_CLOSE );
+    playman_bbar_bt_del = gtk_button_new_from_stock( GTK_STOCK_DELETE );
+    playman_bbar_bt_new = gtk_button_new_from_stock( GTK_STOCK_NEW );
+    gtk_container_add( GTK_CONTAINER(playman_bbar_hbbox) , playman_bbar_bt_close );
+    gtk_container_add( GTK_CONTAINER(playman_bbar_hbbox) , playman_bbar_bt_del );
+    gtk_container_add( GTK_CONTAINER(playman_bbar_hbbox) , playman_bbar_bt_new );
+    gtk_button_box_set_child_secondary( GTK_BUTTON_BOX(playman_bbar_hbbox) ,
+                                        playman_bbar_bt_close , TRUE );
+    gtk_box_pack_start( GTK_BOX(playman_vbox) , playman_bbar_hbbox , FALSE , FALSE , 0 );
+
+    g_signal_connect( G_OBJECT(playman_pl_lv) , "button-press-event" ,
+                      G_CALLBACK(playlist_manager_cb_lv_btpress) , NULL );
+    g_signal_connect( G_OBJECT(playman_pl_lv) , "row-activated" ,
+                      G_CALLBACK(playlist_manager_cb_lv_dclick) , NULL );
+    g_signal_connect_swapped( G_OBJECT(playman_bbar_bt_new) , "clicked" ,
+                              G_CALLBACK(playlist_manager_cb_new) , playman_pl_lv );
+    g_signal_connect_swapped( G_OBJECT(playman_bbar_bt_del) , "clicked" ,
+                              G_CALLBACK(playlist_manager_cb_del) , playman_pl_lv );
+    g_signal_connect_swapped( G_OBJECT(playman_bbar_bt_close) , "clicked" ,
+                              G_CALLBACK(gtk_widget_destroy) , playman_win );
+
+    /* have active playlist selected and scrolled to */
+    active_path = gtk_tree_model_get_path( GTK_TREE_MODEL(pl_store) ,
+            &active_iter );
+    gtk_tree_view_set_cursor( GTK_TREE_VIEW(playman_pl_lv) ,
+            active_path , NULL , FALSE );
+    gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(playman_pl_lv) ,
+            active_path , NULL , TRUE , 0.5 , 0.0 );
+    gtk_tree_path_free( active_path );
+
+    g_object_unref( pl_store );
+
+    gtk_widget_show_all( playman_win );
+}
+
+
+void
+playlist_manager_update ( void )
+{
+    /* this function is called whenever there is a change in playlist, such as
+       playlist created/deleted or entry added/deleted in a playlist; if the playlist
+       manager is active, it should be updated to keep consistency of information */
+
+    /* CAREFUL! this currently locks/unlocks all the playlists */
+
+    if ( playman_win != NULL )
+    {
+        GtkWidget *lv = (GtkWidget*)g_object_get_data( G_OBJECT(playman_win) , "lv" );
+        if ( GPOINTER_TO_INT(g_object_get_data(G_OBJECT(lv),"opt1")) == 0 )
+        {
+            GtkListStore *store = (GtkListStore*)gtk_tree_view_get_model( GTK_TREE_VIEW(lv) );
+            playlist_manager_populate( store );
+        }
+        return;
+    }
+    else
+        return; /* if the playlist manager is not active, simply return */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_playlist_manager.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,26 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_PLAYLIST_MANAGER_H
+#define AUDACIOUS_UI_PLAYLIST_MANAGER_H
+
+void playlist_manager_update ( void );
+void playlist_manager_ui_show ( void );
+
+#endif /* AUDACIOUS_UI_PLAYLIST_MANAGER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skin.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,2052 @@
+/*  Audacious
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+/*#define AUD_DEBUG*/
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+/* TODO: enforce default sizes! */
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "ui_skin.h"
+#include "ui_equalizer.h"
+#include "main.h"
+#include "ui_playlist.h"
+#include "ui_skinselector.h"
+#include "util.h"
+
+#include "debug.h"
+
+#include "platform/smartinclude.h"
+#include "vfs.h"
+
+#include "ui_skinned_window.h"
+#include "ui_skinned_button.h"
+#include "ui_skinned_number.h"
+#include "ui_skinned_horizontal_slider.h"
+#include "ui_skinned_playstatus.h"
+
+#define EXTENSION_TARGETS 7
+
+static gchar *ext_targets[EXTENSION_TARGETS] =
+{ "bmp", "xpm", "png", "svg", "gif", "jpg", "jpeg" };
+
+struct _SkinPixmapIdMapping {
+    SkinPixmapId id;
+    const gchar *name;
+    const gchar *alt_name;
+    gint width, height;
+};
+
+struct _SkinMaskInfo {
+    gint width, height;
+    gchar *inistr;
+};
+
+typedef struct _SkinPixmapIdMapping SkinPixmapIdMapping;
+typedef struct _SkinMaskInfo SkinMaskInfo;
+
+
+Skin *aud_active_skin = NULL;
+
+static gint skin_current_num;
+
+static SkinMaskInfo skin_mask_info[] = {
+    {275, 116, "Normal"},
+    {275, 16,  "WindowShade"},
+    {275, 116, "Equalizer"},
+    {275, 16,  "EqualizerWS"}
+};
+
+static SkinPixmapIdMapping skin_pixmap_id_map[] = {
+    {SKIN_MAIN, "main", NULL, 0, 0},
+    {SKIN_CBUTTONS, "cbuttons", NULL, 0, 0},
+    {SKIN_SHUFREP, "shufrep", NULL, 0, 0},
+    {SKIN_TEXT, "text", NULL, 0, 0},
+    {SKIN_TITLEBAR, "titlebar", NULL, 0, 0},
+    {SKIN_VOLUME, "volume", NULL, 0, 0},
+    {SKIN_BALANCE, "balance", "volume", 0, 0},
+    {SKIN_MONOSTEREO, "monoster", NULL, 0, 0},
+    {SKIN_PLAYPAUSE, "playpaus", NULL, 0, 0},
+    {SKIN_NUMBERS, "nums_ex", "numbers", 0, 0},
+    {SKIN_POSBAR, "posbar", NULL, 0, 0},
+    {SKIN_EQMAIN, "eqmain", NULL, 0, 0},
+    {SKIN_PLEDIT, "pledit", NULL, 0, 0},
+    {SKIN_EQ_EX, "eq_ex", NULL, 0, 0}
+};
+
+static guint skin_pixmap_id_map_size = G_N_ELEMENTS(skin_pixmap_id_map);
+
+static const guchar skin_default_viscolor[24][3] = {
+    {9, 34, 53},
+    {10, 18, 26},
+    {0, 54, 108},
+    {0, 58, 116},
+    {0, 62, 124},
+    {0, 66, 132},
+    {0, 70, 140},
+    {0, 74, 148},
+    {0, 78, 156},
+    {0, 82, 164},
+    {0, 86, 172},
+    {0, 92, 184},
+    {0, 98, 196},
+    {0, 104, 208},
+    {0, 110, 220},
+    {0, 116, 232},
+    {0, 122, 244},
+    {0, 128, 255},
+    {0, 128, 255},
+    {0, 104, 208},
+    {0, 80, 160},
+    {0, 56, 112},
+    {0, 32, 64},
+    {200, 200, 200}
+};
+
+static gchar *original_gtk_theme = NULL;
+
+static GdkBitmap *skin_create_transparent_mask(const gchar *,
+                                               const gchar *,
+                                               const gchar *,
+                                               GdkWindow *,
+                                               gint, gint, gboolean);
+
+static void skin_set_default_vis_color(Skin * skin);
+
+void
+skin_lock(Skin * skin)
+{
+    g_mutex_lock(skin->lock);
+}
+
+void
+skin_unlock(Skin * skin)
+{
+    g_mutex_unlock(skin->lock);
+}
+
+gboolean
+aud_active_skin_reload(void) 
+{
+    AUDDBG("\n");
+    return aud_active_skin_load(aud_active_skin->path); 
+}
+
+gboolean
+aud_active_skin_load(const gchar * path)
+{
+    AUDDBG("%s\n", path);
+    g_return_val_if_fail(aud_active_skin != NULL, FALSE);
+
+    if (!skin_load(aud_active_skin, path)) {
+        AUDDBG("loading failed\n");
+        return FALSE;
+    }
+
+    ui_skinned_window_draw_all(mainwin);
+    ui_skinned_window_draw_all(equalizerwin);
+    ui_skinned_window_draw_all(playlistwin);
+
+    playlistwin_update_list(playlist_get_active());
+
+    SkinPixmap *pixmap;
+    pixmap = &aud_active_skin->pixmaps[SKIN_POSBAR];
+    /* last 59 pixels of SKIN_POSBAR are knobs (normal and selected) */
+    gtk_widget_set_size_request(mainwin_position, pixmap->width - 59, pixmap->height);
+
+    return TRUE;
+}
+
+void
+skin_pixmap_free(SkinPixmap * p)
+{
+    g_return_if_fail(p != NULL);
+    g_return_if_fail(p->pixbuf != NULL);
+
+    g_object_unref(p->pixbuf);
+    p->pixbuf = NULL;
+}
+
+Skin *
+skin_new(void)
+{
+    Skin *skin;
+    skin = g_new0(Skin, 1);
+    skin->lock = g_mutex_new();
+    return skin;
+}
+
+/**
+ * Frees the data associated for skin.
+ *
+ * Does not free skin itself or lock variable so that the skin can immediately
+ * populated with new skin data if needed.
+ */
+void
+skin_free(Skin * skin)
+{
+    gint i;
+
+    g_return_if_fail(skin != NULL);
+
+    for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
+        skin_pixmap_free(&skin->pixmaps[i]);
+
+    for (i = 0; i < SKIN_MASK_COUNT; i++) {
+        if (skin->masks[i])
+            g_object_unref(skin->masks[i]);
+        if (skin->scaled_masks[i])
+            g_object_unref(skin->scaled_masks[i]);
+
+        skin->masks[i] = NULL;
+        skin->scaled_masks[i] = NULL;
+    }
+
+    for (i = 0; i < SKIN_COLOR_COUNT; i++) {
+        if (skin->colors[i])
+            g_free(skin->colors[i]);
+
+        skin->colors[i] = NULL;
+    }
+
+    g_free(skin->path);
+    skin->path = NULL;
+
+    skin_set_default_vis_color(skin);
+}
+
+void
+skin_destroy(Skin * skin)
+{
+    g_return_if_fail(skin != NULL);
+    skin_free(skin);
+    g_mutex_free(skin->lock);
+    g_free(skin);
+}
+
+const SkinPixmapIdMapping *
+skin_pixmap_id_lookup(guint id)
+{
+    guint i;
+
+    for (i = 0; i < skin_pixmap_id_map_size; i++) {
+        if (id == skin_pixmap_id_map[i].id) {
+            return &skin_pixmap_id_map[i];
+        }
+    }
+
+    return NULL;
+}
+
+const gchar *
+skin_pixmap_id_to_name(SkinPixmapId id)
+{
+    guint i;
+
+    for (i = 0; i < skin_pixmap_id_map_size; i++) {
+        if (id == skin_pixmap_id_map[i].id)
+            return skin_pixmap_id_map[i].name;
+    }
+    return NULL;
+}
+
+static void
+skin_set_default_vis_color(Skin * skin)
+{
+    memcpy(skin->vis_color, skin_default_viscolor,
+           sizeof(skin_default_viscolor));
+}
+
+/*
+ * I have rewritten this to take an array of possible targets,
+ * once we find a matching target we now return, instead of loop
+ * recursively. This allows for us to support many possible format
+ * targets for our skinning engine than just the original winamp 
+ * formats.
+ *
+ *    -- nenolod, 16 January 2006
+ */
+gchar *
+skin_pixmap_locate(const gchar * dirname, gchar ** basenames)
+{
+    gchar *filename;
+    gint i;
+
+    for (i = 0; basenames[i]; i++)
+    if (!(filename = find_path_recursively(dirname, basenames[i]))) 
+        g_free(filename);
+    else
+        return filename;
+
+    /* can't find any targets -- sorry */
+    return NULL;
+}
+
+/**
+ * Creates possible file names for a pixmap.
+ *
+ * Basically this makes list of all possible file names that pixmap data
+ * can be found from by using the static ext_targets variable to get all
+ * possible extensions that pixmap file might have.
+ */
+static gchar **
+skin_pixmap_create_basenames(const SkinPixmapIdMapping * pixmap_id_mapping)
+{
+    gchar **basenames = g_malloc0(sizeof(gchar*) * (EXTENSION_TARGETS * 2 + 1));
+    gint i, y;
+
+    // Create list of all possible image formats that can be loaded
+    for (i = 0, y = 0; i < EXTENSION_TARGETS; i++, y++)
+    {
+        basenames[y] =
+            g_strdup_printf("%s.%s", pixmap_id_mapping->name, ext_targets[i]);
+
+        if (pixmap_id_mapping->alt_name)
+            basenames[++y] =
+                g_strdup_printf("%s.%s", pixmap_id_mapping->alt_name,
+                                ext_targets[i]);
+    }
+
+    return basenames;
+}
+
+/**
+ * Frees the data allocated by skin_pixmap_create_basenames
+ */
+static void
+skin_pixmap_free_basenames(gchar ** basenames)
+{
+    int i;
+    for (i = 0; basenames[i] != NULL; i++)
+    {
+        g_free(basenames[i]);
+        basenames[i] = NULL;
+    }
+    g_free(basenames);
+}
+
+/**
+ * Locates a pixmap file for skin.
+ */
+static gchar *
+skin_pixmap_locate_basenames(const Skin * skin,
+                             const SkinPixmapIdMapping * pixmap_id_mapping,
+                             const gchar * path_p)
+{
+    gchar *filename = NULL;
+    const gchar *path = path_p ? path_p : skin->path;
+    gchar **basenames = skin_pixmap_create_basenames(pixmap_id_mapping);
+
+    filename = skin_pixmap_locate(path, basenames);
+
+    skin_pixmap_free_basenames(basenames);
+
+    return filename;
+}
+
+
+static gboolean
+skin_load_pixmap_id(Skin * skin, SkinPixmapId id, const gchar * path_p)
+{
+    const SkinPixmapIdMapping *pixmap_id_mapping;
+    gchar *filename;
+    SkinPixmap *pm = NULL;
+
+    g_return_val_if_fail(skin != NULL, FALSE);
+    g_return_val_if_fail(id < SKIN_PIXMAP_COUNT, FALSE);
+
+    pixmap_id_mapping = skin_pixmap_id_lookup(id);
+    g_return_val_if_fail(pixmap_id_mapping != NULL, FALSE);
+
+    filename = skin_pixmap_locate_basenames(skin, pixmap_id_mapping, path_p);
+
+    if (filename == NULL)
+        return FALSE;
+
+    AUDDBG("loaded %s\n", filename);
+
+    pm = &skin->pixmaps[id];
+    GdkPixbuf *pix = gdk_pixbuf_new_from_file(filename, NULL);
+    pm->pixbuf = audacious_create_colorized_pixbuf(pix, cfg.colorize_r, cfg.colorize_g, cfg.colorize_b);
+    g_object_unref(pix);
+    pm->width = gdk_pixbuf_get_width(pm->pixbuf);
+    pm->height = gdk_pixbuf_get_height(pm->pixbuf);
+    pm->current_width = pm->width;
+    pm->current_height = pm->height;
+
+    g_free(filename);
+
+    return TRUE;
+}
+
+void
+skin_mask_create(Skin * skin,
+                 const gchar * path,
+                 gint id,
+                 GdkWindow * window)
+{
+    skin->masks[id] =
+        skin_create_transparent_mask(path, "region.txt",
+                                     skin_mask_info[id].inistr, window,
+                                     skin_mask_info[id].width,
+                                     skin_mask_info[id].height, FALSE);
+
+    skin->scaled_masks[id] =
+        skin_create_transparent_mask(path, "region.txt",
+                                     skin_mask_info[id].inistr, window,
+                                     skin_mask_info[id].width * 2,
+                                     skin_mask_info[id].height * 2, TRUE);
+}
+
+static GdkBitmap *
+create_default_mask(GdkWindow * parent, gint w, gint h)
+{
+    GdkBitmap *ret;
+    GdkGC *gc;
+    GdkColor pattern;
+
+    ret = gdk_pixmap_new(parent, w, h, 1);
+    gc = gdk_gc_new(ret);
+    pattern.pixel = 1;
+    gdk_gc_set_foreground(gc, &pattern);
+    gdk_draw_rectangle(ret, gc, TRUE, 0, 0, w, h);
+    g_object_unref(gc);
+
+    return ret;
+}
+
+static void
+skin_query_color(GdkColormap * cm, GdkColor * c)
+{
+#ifdef GDK_WINDOWING_X11
+    XColor xc = { 0,0,0,0,0,0 };
+
+    xc.pixel = c->pixel;
+    XQueryColor(GDK_COLORMAP_XDISPLAY(cm), GDK_COLORMAP_XCOLORMAP(cm), &xc);
+    c->red = xc.red;
+    c->green = xc.green;
+    c->blue = xc.blue;
+#else
+    /* do nothing. see what breaks? */
+#endif
+}
+
+static glong
+skin_calc_luminance(GdkColor * c)
+{
+    return (0.212671 * c->red + 0.715160 * c->green + 0.072169 * c->blue);
+}
+
+static void
+skin_get_textcolors(GdkPixbuf * pix, GdkColor * bgc, GdkColor * fgc)
+{
+    /*
+     * Try to extract reasonable background and foreground colors
+     * from the font pixmap
+     */
+
+    GdkImage *gi;
+    GdkColormap *cm;
+    gint i;
+
+    g_return_if_fail(pix != NULL);
+
+    GdkPixmap *text = gdk_pixmap_new(NULL, gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix), gdk_rgb_get_visual()->depth);
+    gdk_draw_pixbuf(text, NULL, pix, 0, 0, 0, 0, gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix),
+                    GDK_RGB_DITHER_NONE, 0, 0);
+    /* Get the first line of text */
+    gi = gdk_drawable_get_image(text, 0, 0, 152, 6);
+    cm = gdk_colormap_get_system();
+
+    for (i = 0; i < 6; i++) {
+        GdkColor c;
+        gint x;
+        glong d, max_d;
+
+        /* Get a pixel from the middle of the space character */
+        bgc[i].pixel = gdk_image_get_pixel(gi, 151, i);
+        skin_query_color(cm, &bgc[i]);
+
+        max_d = 0;
+        for (x = 1; x < 150; x++) {
+            c.pixel = gdk_image_get_pixel(gi, x, i);
+            skin_query_color(cm, &c);
+
+            d = labs(skin_calc_luminance(&c) - skin_calc_luminance(&bgc[i]));
+            if (d > max_d) {
+                memcpy(&fgc[i], &c, sizeof(GdkColor));
+                max_d = d;
+            }
+        }
+    }
+    g_object_unref(gi);
+    g_object_unref(text);
+}
+
+gboolean
+init_skins(const gchar * path)
+{
+    aud_active_skin = skin_new();
+
+    skin_parse_hints(aud_active_skin, NULL);
+
+    /* create the windows if they haven't been created yet, needed for bootstrapping */
+    if (mainwin == NULL)
+    {
+        mainwin_create();
+        equalizerwin_create();
+        playlistwin_create();
+    }
+
+    if (!aud_active_skin_load(path)) {
+        if (path != NULL)
+            AUDDBG("Unable to load skin (%s), trying default...\n", path);
+        else
+            AUDDBG("Skin not defined: trying default...\n");
+
+        /* can't load configured skin, retry with default */
+        if (!aud_active_skin_load(BMP_DEFAULT_SKIN_PATH)) {
+            AUDDBG("Unable to load default skin (%s)! Giving up.\n",
+                      BMP_DEFAULT_SKIN_PATH);
+            return FALSE;
+        }
+    }
+
+    if (cfg.random_skin_on_play)
+        skinlist_update();
+
+    return TRUE;
+}
+
+void cleanup_skins()
+{
+    skin_destroy(aud_active_skin);
+    aud_active_skin = NULL;
+}
+
+
+/*
+ * Opens and parses a skin's hints file.
+ * Hints files are somewhat like "scripts" in Winamp3/5.
+ * We'll probably add scripts to it next.
+ */
+void
+skin_parse_hints(Skin * skin, gchar *path_p)
+{
+    gchar *filename, *tmp;
+    INIFile *inifile;
+
+    path_p = path_p ? path_p : skin->path;
+
+    skin->properties.mainwin_othertext = FALSE;
+    skin->properties.mainwin_vis_x = 24;
+    skin->properties.mainwin_vis_y = 43;
+    skin->properties.mainwin_vis_width = 76;
+    skin->properties.mainwin_text_x = 112;
+    skin->properties.mainwin_text_y = 27;
+    skin->properties.mainwin_text_width = 153;
+    skin->properties.mainwin_infobar_x = 112;
+    skin->properties.mainwin_infobar_y = 43;
+    skin->properties.mainwin_number_0_x = 36;
+    skin->properties.mainwin_number_0_y = 26;
+    skin->properties.mainwin_number_1_x = 48;
+    skin->properties.mainwin_number_1_y = 26;
+    skin->properties.mainwin_number_2_x = 60;
+    skin->properties.mainwin_number_2_y = 26;
+    skin->properties.mainwin_number_3_x = 78;
+    skin->properties.mainwin_number_3_y = 26;
+    skin->properties.mainwin_number_4_x = 90;
+    skin->properties.mainwin_number_4_y = 26;
+    skin->properties.mainwin_playstatus_x = 24;
+    skin->properties.mainwin_playstatus_y = 28;
+    skin->properties.mainwin_menurow_visible = TRUE;
+    skin->properties.mainwin_volume_x = 107;
+    skin->properties.mainwin_volume_y = 57;
+    skin->properties.mainwin_balance_x = 177;
+    skin->properties.mainwin_balance_y = 57;
+    skin->properties.mainwin_position_x = 16;
+    skin->properties.mainwin_position_y = 72;
+    skin->properties.mainwin_othertext_is_status = FALSE;
+    skin->properties.mainwin_othertext_visible = skin->properties.mainwin_othertext;
+    skin->properties.mainwin_text_visible = TRUE;
+    skin->properties.mainwin_vis_visible = TRUE;
+    skin->properties.mainwin_previous_x = 16;
+    skin->properties.mainwin_previous_y = 88;
+    skin->properties.mainwin_play_x = 39;
+    skin->properties.mainwin_play_y = 88;
+    skin->properties.mainwin_pause_x = 62;
+    skin->properties.mainwin_pause_y = 88;
+    skin->properties.mainwin_stop_x = 85;
+    skin->properties.mainwin_stop_y = 88;
+    skin->properties.mainwin_next_x = 108;
+    skin->properties.mainwin_next_y = 88;
+    skin->properties.mainwin_eject_x = 136;
+    skin->properties.mainwin_eject_y = 89;
+    skin->properties.mainwin_width = 275;
+    skin_mask_info[0].width = skin->properties.mainwin_width;
+    skin->properties.mainwin_height = 116;
+    skin_mask_info[0].height = skin->properties.mainwin_height;
+    skin->properties.mainwin_about_x = 247;
+    skin->properties.mainwin_about_y = 83;
+    skin->properties.mainwin_shuffle_x = 164;
+    skin->properties.mainwin_shuffle_y = 89;
+    skin->properties.mainwin_repeat_x = 210;
+    skin->properties.mainwin_repeat_y = 89;
+    skin->properties.mainwin_eqbutton_x = 219;
+    skin->properties.mainwin_eqbutton_y = 58;
+    skin->properties.mainwin_plbutton_x = 242;
+    skin->properties.mainwin_plbutton_y = 58;
+    skin->properties.textbox_bitmap_font_width = 5;
+    skin->properties.textbox_bitmap_font_height = 6;
+    skin->properties.mainwin_minimize_x = 244;
+    skin->properties.mainwin_minimize_y = 3;
+    skin->properties.mainwin_shade_x = 254;
+    skin->properties.mainwin_shade_y = 3;
+    skin->properties.mainwin_close_x = 264;
+    skin->properties.mainwin_close_y = 3;
+
+    if (path_p == NULL)
+        return;
+
+    filename = find_file_recursively(path_p, "skin.hints");
+
+    if (filename == NULL)
+        return;
+
+    inifile = open_ini_file(filename);
+    if (!inifile)
+        return;
+
+    tmp = read_ini_string(inifile, "skin", "mainwinOthertext");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_othertext = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinVisX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_vis_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinVisY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_vis_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinVisWidth");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_vis_width = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinTextX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_text_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinTextY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_text_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinTextWidth");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_text_width = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinInfoBarX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_infobar_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinInfoBarY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_infobar_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber0X");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_0_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber0Y");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_0_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber1X");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_1_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber1Y");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_1_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber2X");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_2_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber2Y");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_2_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber3X");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_3_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber3Y");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_3_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber4X");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_4_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNumber4Y");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_number_4_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPlayStatusX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_playstatus_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPlayStatusY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_playstatus_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinMenurowVisible");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_menurow_visible = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinVolumeX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_volume_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinVolumeY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_volume_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinBalanceX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_balance_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinBalanceY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_balance_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPositionX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_position_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPositionY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_position_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinOthertextIsStatus");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_othertext_is_status = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinOthertextVisible");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_othertext_visible = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinTextVisible");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_text_visible = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinVisVisible");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_vis_visible = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPreviousX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_previous_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPreviousY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_previous_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPlayX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_play_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPlayY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_play_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPauseX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_pause_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPauseY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_pause_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinStopX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_stop_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinStopY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_stop_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNextX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_next_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinNextY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_next_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinEjectX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_eject_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinEjectY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_eject_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinWidth");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_width = atoi(tmp);
+        g_free(tmp);
+    }
+
+    skin_mask_info[0].width = skin->properties.mainwin_width;
+
+    tmp = read_ini_string(inifile, "skin", "mainwinHeight");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_height = atoi(tmp);
+        g_free(tmp);
+    }
+
+    skin_mask_info[0].height = skin->properties.mainwin_height;
+
+    tmp = read_ini_string(inifile, "skin", "mainwinAboutX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_about_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinAboutY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_about_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinShuffleX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_shuffle_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinShuffleY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_shuffle_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinRepeatX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_repeat_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinRepeatY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_repeat_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinEQButtonX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_eqbutton_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinEQButtonY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_eqbutton_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPLButtonX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_plbutton_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinPLButtonY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_plbutton_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "textboxBitmapFontWidth");
+
+    if (tmp != NULL)
+    {
+        skin->properties.textbox_bitmap_font_width = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "textboxBitmapFontHeight");
+
+    if (tmp != NULL)
+    {
+        skin->properties.textbox_bitmap_font_height = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinMinimizeX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_minimize_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinMinimizeY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_minimize_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinShadeX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_shade_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinShadeY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_shade_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinCloseX");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_close_x = atoi(tmp);
+        g_free(tmp);
+    }
+
+    tmp = read_ini_string(inifile, "skin", "mainwinCloseY");
+
+    if (tmp != NULL)
+    {
+        skin->properties.mainwin_close_y = atoi(tmp);
+        g_free(tmp);
+    }
+
+    if (filename != NULL)
+        g_free(filename);
+
+    close_ini_file(inifile);
+}
+
+static guint
+hex_chars_to_int(gchar hi, gchar lo)
+{
+    /*
+     * Converts a value in the range 0x00-0xFF
+     * to a integer in the range 0-65535
+     */
+    gchar str[3];
+
+    str[0] = hi;
+    str[1] = lo;
+    str[2] = 0;
+
+    return (CLAMP(strtol(str, NULL, 16), 0, 0xFF) << 8);
+}
+
+static GdkColor *
+skin_load_color(INIFile *inifile,
+                const gchar * section, const gchar * key,
+                gchar * default_hex)
+{
+    gchar *value;
+    GdkColor *color = NULL;
+
+    if (inifile || default_hex) {
+        if (inifile) {
+            value = read_ini_string(inifile, section, key);
+            if (value == NULL) {
+                value = g_strdup(default_hex);
+            }
+        } else {
+            value = g_strdup(default_hex);
+        }
+        if (value) {
+            gchar *ptr = value;
+            gint len;
+
+            color = g_new0(GdkColor, 1);
+            g_strstrip(value);
+
+            if (value[0] == '#')
+                ptr++;
+            len = strlen(ptr);
+            /*
+             * The handling of incomplete values is done this way
+             * to maximize winamp compatibility
+             */
+            if (len >= 6) {
+                color->red = hex_chars_to_int(*ptr, *(ptr + 1));
+                ptr += 2;
+            }
+            if (len >= 4) {
+                color->green = hex_chars_to_int(*ptr, *(ptr + 1));
+                ptr += 2;
+            }
+            if (len >= 2)
+                color->blue = hex_chars_to_int(*ptr, *(ptr + 1));
+
+            g_free(value);
+        }
+    }
+    return color;
+}
+
+
+
+GdkBitmap *
+skin_create_transparent_mask(const gchar * path,
+                             const gchar * file,
+                             const gchar * section,
+                             GdkWindow * window,
+                             gint width,
+                             gint height, gboolean scale)
+{
+    GdkBitmap *mask = NULL;
+    GdkGC *gc = NULL;
+    GdkColor pattern;
+    GdkPoint *gpoints;
+
+    gchar *filename = NULL;
+    INIFile *inifile = NULL;
+    gboolean created_mask = FALSE;
+    GArray *num, *point;
+    guint i, j;
+    gint k;
+
+    if (path)
+        filename = find_file_recursively(path, file);
+
+    /* filename will be null if path wasn't set */
+    if (!filename)
+        return create_default_mask(window, width, height);
+
+    inifile = open_ini_file(filename);
+
+    if ((num = read_ini_array(inifile, section, "NumPoints")) == NULL) {
+        g_free(filename);
+        close_ini_file(inifile);
+        return NULL;
+    }
+
+    if ((point = read_ini_array(inifile, section, "PointList")) == NULL) {
+        g_array_free(num, TRUE);
+        g_free(filename);
+        close_ini_file(inifile);
+        return NULL;
+    }
+
+    close_ini_file(inifile);
+
+    mask = gdk_pixmap_new(window, width, height, 1);
+    gc = gdk_gc_new(mask);
+
+    pattern.pixel = 0;
+    gdk_gc_set_foreground(gc, &pattern);
+    gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height);
+    pattern.pixel = 1;
+    gdk_gc_set_foreground(gc, &pattern);
+
+    j = 0;
+    for (i = 0; i < num->len; i++) {
+        if ((int)(point->len - j) >= (g_array_index(num, gint, i) * 2)) {
+            created_mask = TRUE;
+            gpoints = g_new(GdkPoint, g_array_index(num, gint, i));
+            for (k = 0; k < g_array_index(num, gint, i); k++) {
+                gpoints[k].x =
+                    g_array_index(point, gint, j + k * 2) * (scale ? cfg.scale_factor : 1 );
+                gpoints[k].y =
+                    g_array_index(point, gint,
+                                  j + k * 2 + 1) * (scale ? cfg.scale_factor : 1);
+            }
+            j += k * 2;
+            gdk_draw_polygon(mask, gc, TRUE, gpoints,
+                             g_array_index(num, gint, i));
+            g_free(gpoints);
+        }
+    }
+    g_array_free(num, TRUE);
+    g_array_free(point, TRUE);
+    g_free(filename);
+
+    if (!created_mask)
+        gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height);
+
+    g_object_unref(gc);
+
+    return mask;
+}
+
+void
+skin_load_viscolor(Skin * skin, const gchar * path, const gchar * basename)
+{
+    VFSFile *file;
+    gint i, c;
+    gchar line[256], *filename;
+    GArray *a;
+
+    g_return_if_fail(skin != NULL);
+    g_return_if_fail(path != NULL);
+    g_return_if_fail(basename != NULL);
+
+    skin_set_default_vis_color(skin);
+
+    filename = find_file_recursively(path, basename);
+    if (!filename)
+        return;
+
+    if (!(file = vfs_fopen(filename, "r"))) {
+        g_free(filename);
+        return;
+    }
+
+    g_free(filename);
+
+    for (i = 0; i < 24; i++) {
+        if (vfs_fgets(line, 255, file)) {
+            a = string_to_garray(line);
+            if (a->len > 2) {
+                for (c = 0; c < 3; c++)
+                    skin->vis_color[i][c] = g_array_index(a, gint, c);
+            }
+            g_array_free(a, TRUE);
+        }
+        else
+            break;
+    }
+
+    vfs_fclose(file);
+}
+
+static void
+skin_numbers_generate_dash(Skin * skin)
+{
+    GdkPixbuf *pixbuf;
+    SkinPixmap *numbers;
+
+    g_return_if_fail(skin != NULL);
+
+    numbers = &skin->pixmaps[SKIN_NUMBERS];
+    if (!numbers->pixbuf || numbers->current_width < 99)
+        return;
+
+    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+                            108, numbers->current_height);
+
+    skin_draw_pixbuf(NULL, skin, pixbuf, SKIN_NUMBERS, 0, 0, 0, 0, 99, numbers->current_height);
+    skin_draw_pixbuf(NULL, skin, pixbuf, SKIN_NUMBERS, 90, 0, 99, 0, 9, numbers->current_height);
+    skin_draw_pixbuf(NULL, skin, pixbuf, SKIN_NUMBERS, 20, 6, 101, 6, 5, 1);
+
+    g_object_unref(numbers->pixbuf);
+
+    numbers->pixbuf = pixbuf;
+    numbers->current_width = 108;
+    numbers->width = 108;
+}
+
+static gboolean
+skin_load_pixmaps(Skin * skin, const gchar * path)
+{
+    GdkPixbuf *text_pb;
+    guint i;
+    gchar *filename;
+    INIFile *inifile;
+    
+    if(!skin) return FALSE;
+    if(!path) return FALSE;
+
+    AUDDBG("Loading pixmaps in %s\n", path);
+
+    for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
+        if (!skin_load_pixmap_id(skin, i, path) && !cfg.allow_broken_skins)
+            return FALSE;
+
+    text_pb = skin->pixmaps[SKIN_TEXT].pixbuf;
+
+    if (text_pb)
+        skin_get_textcolors(text_pb, skin->textbg, skin->textfg);
+
+    if (skin->pixmaps[SKIN_NUMBERS].pixbuf &&
+        skin->pixmaps[SKIN_NUMBERS].width < 108 )
+        skin_numbers_generate_dash(skin);
+
+    filename = find_file_recursively(path, "pledit.txt");
+    inifile = open_ini_file(filename);
+
+    skin->colors[SKIN_PLEDIT_NORMAL] =
+        skin_load_color(inifile, "Text", "Normal", "#2499ff");
+    skin->colors[SKIN_PLEDIT_CURRENT] =
+        skin_load_color(inifile, "Text", "Current", "#ffeeff");
+    skin->colors[SKIN_PLEDIT_NORMALBG] =
+        skin_load_color(inifile, "Text", "NormalBG", "#0a120a");
+    skin->colors[SKIN_PLEDIT_SELECTEDBG] =
+        skin_load_color(inifile, "Text", "SelectedBG", "#0a124a");
+
+    if (inifile)
+        close_ini_file(inifile);
+
+    if (filename)
+        g_free(filename);
+
+    skin_mask_create(skin, path, SKIN_MASK_MAIN, mainwin->window);
+    skin_mask_create(skin, path, SKIN_MASK_MAIN_SHADE, mainwin->window);
+
+    skin_mask_create(skin, path, SKIN_MASK_EQ, equalizerwin->window);
+    skin_mask_create(skin, path, SKIN_MASK_EQ_SHADE, equalizerwin->window);
+
+    skin_load_viscolor(skin, path, "viscolor.txt");
+
+    return TRUE;
+}
+
+static void
+skin_set_gtk_theme(GtkSettings * settings, Skin * skin)
+{
+    if (original_gtk_theme == NULL)
+         g_object_get(settings, "gtk-theme-name", &original_gtk_theme, NULL);
+
+    /* the way GTK does things can be very broken. --nenolod */
+
+    gchar *tmp = g_strdup_printf("%s/.themes/aud-%s", g_get_home_dir(),
+                                 basename(skin->path));
+
+    gchar *troot = g_strdup_printf("%s/.themes", g_get_home_dir());
+    g_mkdir_with_parents(troot, 0755);
+    g_free(troot);
+
+    symlink(skin->path, tmp);
+    gtk_settings_set_string_property(settings, "gtk-theme-name",
+                                     basename(tmp), "audacious");
+    g_free(tmp);
+}
+
+/**
+ * Checks if all pixmap files exist that skin needs.
+ */
+static gboolean
+skin_check_pixmaps(const Skin * skin, const gchar * skin_path)
+{
+    guint i;
+    for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
+    {
+        gchar *filename = skin_pixmap_locate_basenames(skin,
+                                                       skin_pixmap_id_lookup(i),
+                                                       skin_path);
+        if (!filename)
+            return FALSE;
+        g_free(filename);
+    }
+    return TRUE;
+}
+
+static gboolean
+skin_load_nolock(Skin * skin, const gchar * path, gboolean force)
+{
+    GtkSettings *settings;
+    gchar *gtkrcpath;
+    gchar *newpath, *skin_path;
+    int archive = 0;
+
+    AUDDBG("Attempt to load skin \"%s\"\n", path);
+
+    g_return_val_if_fail(skin != NULL, FALSE);
+    g_return_val_if_fail(path != NULL, FALSE);
+    REQUIRE_LOCK(skin->lock);
+
+    if (!g_file_test(path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_DIR))
+        return FALSE;
+   
+    if(force) AUDDBG("reloading forced!\n");
+    if (!force && skin->path && !strcmp(skin->path, path)) {
+        AUDDBG("skin %s already loaded\n", path);
+        return FALSE;
+    }
+    
+    if (file_is_archive(path)) {
+        AUDDBG("Attempt to load archive\n");
+        if (!(skin_path = archive_decompress(path))) {
+            AUDDBG("Unable to extract skin archive (%s)\n", path);
+            return FALSE;
+        }
+        archive = 1;
+    } else {
+        skin_path = g_strdup(path);
+    }
+
+    // Check if skin path has all necessary files.
+    if (!cfg.allow_broken_skins && !skin_check_pixmaps(skin, skin_path)) {
+        if(archive) del_directory(skin_path);
+        g_free(skin_path);
+        AUDDBG("Skin path (%s) doesn't have all wanted pixmaps\n", skin_path);
+        return FALSE;
+    }
+
+    // skin_free() frees skin->path and variable path can actually be skin->path
+    // and we want to get the path before possibly freeing it.
+    newpath = g_strdup(path);
+    skin_free(skin);
+    skin->path = newpath;
+
+    memset(&(skin->properties), 0, sizeof(SkinProperties)); /* do it only if all tests above passed! --asphyx */
+    
+    skin_current_num++;
+
+    /* Parse the hints for this skin. */
+    skin_parse_hints(skin, skin_path);
+
+    if (!skin_load_pixmaps(skin, skin_path)) {
+        if(archive) del_directory(skin_path);
+        g_free(skin_path);
+        AUDDBG("Skin loading failed\n");
+        return FALSE;
+    }
+
+    /* restore gtk theme if changed by previous skin */
+    settings = gtk_settings_get_default();
+
+    if (original_gtk_theme != NULL) {
+        gtk_settings_set_string_property(settings, "gtk-theme-name",
+                                              original_gtk_theme, "audacious");
+        g_free(original_gtk_theme);
+        original_gtk_theme = NULL;
+    }
+
+#ifndef _WIN32
+    if (!cfg.disable_inline_gtk && !archive) {
+        gtkrcpath = find_path_recursively(skin->path, "gtkrc");
+        if (gtkrcpath != NULL)
+            skin_set_gtk_theme(settings, skin);
+        g_free(gtkrcpath);
+    }
+#endif
+
+    if(archive) del_directory(skin_path);
+    g_free(skin_path);
+
+    gtk_widget_shape_combine_mask(mainwin, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
+    gtk_widget_shape_combine_mask(equalizerwin, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
+
+    return TRUE;
+}
+
+void
+skin_install_skin(const gchar * path)
+{
+    gchar *command;
+
+    g_return_if_fail(path != NULL);
+
+    command = g_strdup_printf("cp %s %s",
+                              path, aud_paths[BMP_PATH_USER_SKIN_DIR]);
+    if (system(command)) {
+        AUDDBG("Unable to install skin (%s) into user directory (%s)\n",
+                  path, aud_paths[BMP_PATH_USER_SKIN_DIR]);
+    }
+    g_free(command);
+}
+
+static SkinPixmap *
+skin_get_pixmap(Skin * skin, SkinPixmapId map_id)
+{
+    g_return_val_if_fail(skin != NULL, NULL);
+    g_return_val_if_fail(map_id < SKIN_PIXMAP_COUNT, NULL);
+
+    return &skin->pixmaps[map_id];
+}
+
+gboolean
+skin_load(Skin * skin, const gchar * path)
+{
+    gboolean ret;
+
+    g_return_val_if_fail(skin != NULL, FALSE);
+
+    if (!path)
+        return FALSE;
+
+    skin_lock(skin);
+    ret = skin_load_nolock(skin, path, FALSE);
+    skin_unlock(skin);
+
+    if(!ret) {
+        AUDDBG("loading failed\n");
+        return FALSE; /* don't try to update anything if loading failed --asphyx */
+    }
+
+    SkinPixmap *pixmap = NULL;
+    pixmap = skin_get_pixmap(skin, SKIN_NUMBERS);
+    if (pixmap) {
+        ui_skinned_number_set_size(mainwin_minus_num, 9, pixmap->height);
+        ui_skinned_number_set_size(mainwin_10min_num, 9, pixmap->height);
+        ui_skinned_number_set_size(mainwin_min_num, 9, pixmap->height);
+        ui_skinned_number_set_size(mainwin_10sec_num, 9, pixmap->height);
+        ui_skinned_number_set_size(mainwin_sec_num, 9, pixmap->height);
+    }
+
+    pixmap = skin_get_pixmap(skin, SKIN_MAIN);
+    if (pixmap && skin->properties.mainwin_height > pixmap->height)
+        skin->properties.mainwin_height = pixmap->height;
+
+    pixmap = skin_get_pixmap(skin, SKIN_PLAYPAUSE);
+    if (pixmap)
+        ui_skinned_playstatus_set_size(mainwin_playstatus, 11, pixmap->height);
+
+    pixmap = skin_get_pixmap(skin, SKIN_EQMAIN);
+    if (pixmap->height >= 313)
+        gtk_widget_show(equalizerwin_graph);
+
+    return TRUE;
+}
+
+gboolean
+skin_reload_forced(void) 
+{
+    gboolean error;
+    AUDDBG("\n");
+
+    skin_lock(aud_active_skin);
+    error = skin_load_nolock(aud_active_skin, aud_active_skin->path, TRUE);
+    skin_unlock(aud_active_skin);
+
+    ui_skinned_window_draw_all(mainwin);
+    ui_skinned_window_draw_all(equalizerwin);
+    ui_skinned_window_draw_all(playlistwin);
+
+    return error;
+}
+
+void
+skin_reload(Skin * skin)
+{
+    AUDDBG("\n");
+    g_return_if_fail(skin != NULL);
+    skin_load_nolock(skin, skin->path, TRUE);
+}
+
+GdkBitmap *
+skin_get_mask(Skin * skin, SkinMaskId mi)
+{
+    GdkBitmap **masks;
+
+    g_return_val_if_fail(skin != NULL, NULL);
+    g_return_val_if_fail(mi < SKIN_PIXMAP_COUNT, NULL);
+
+    masks = cfg.scaled ? skin->scaled_masks : skin->masks;
+    return masks[mi];
+}
+
+GdkColor *
+skin_get_color(Skin * skin, SkinColorId color_id)
+{
+    GdkColor *ret = NULL;
+
+    g_return_val_if_fail(skin != NULL, NULL);
+
+    switch (color_id) {
+    case SKIN_TEXTBG:
+        if (skin->pixmaps[SKIN_TEXT].pixbuf)
+            ret = skin->textbg;
+        else
+            ret = skin->def_textbg;
+        break;
+    case SKIN_TEXTFG:
+        if (skin->pixmaps[SKIN_TEXT].pixbuf)
+            ret = skin->textfg;
+        else
+            ret = skin->def_textfg;
+        break;
+    default:
+        if (color_id < SKIN_COLOR_COUNT)
+            ret = skin->colors[color_id];
+        break;
+    }
+    return ret;
+}
+
+void
+skin_get_viscolor(Skin * skin, guchar vis_color[24][3])
+{
+    gint i;
+
+    g_return_if_fail(skin != NULL);
+
+    for (i = 0; i < 24; i++) {
+        vis_color[i][0] = skin->vis_color[i][0];
+        vis_color[i][1] = skin->vis_color[i][1];
+        vis_color[i][2] = skin->vis_color[i][2];
+    }
+}
+
+gint
+skin_get_id(void)
+{
+    return skin_current_num;
+}
+
+void
+skin_draw_pixbuf(GtkWidget *widget, Skin * skin, GdkPixbuf * pix,
+                 SkinPixmapId pixmap_id,
+                 gint xsrc, gint ysrc, gint xdest, gint ydest,
+                 gint width, gint height)
+{
+    SkinPixmap *pixmap;
+
+    g_return_if_fail(skin != NULL);
+
+    pixmap = skin_get_pixmap(skin, pixmap_id);
+    g_return_if_fail(pixmap != NULL);
+    g_return_if_fail(pixmap->pixbuf != NULL);
+
+    /* perhaps we should use transparency or resize widget? */
+    if (xsrc+width > pixmap->width || ysrc+height > pixmap->height) {
+        if (widget) {
+            /* it's better to hide widget using SKIN_PLAYPAUSE/SKIN_POSBAR than display mess */
+            if ((pixmap_id == SKIN_PLAYPAUSE && pixmap->width != 42) || pixmap_id == SKIN_POSBAR) {
+                gtk_widget_hide(widget);
+                return;
+            }
+            gint x, y;
+            x = -1;
+            y = -1;
+
+            if (gtk_widget_get_parent(widget) == SKINNED_WINDOW(mainwin)->fixed) {
+                GList *iter;
+                for (iter = GTK_FIXED (SKINNED_WINDOW(mainwin)->fixed)->children; iter; iter = g_list_next (iter)) {
+                     GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
+                     if (child_data->widget == widget) {
+                         x = child_data->x;
+                         y = child_data->y;
+                         break;
+                     }
+                }
+
+                if (x != -1 && y != -1) {
+                    /* Some skins include SKIN_VOLUME and/or SKIN_BALANCE
+                       without knobs */
+                    if (pixmap_id == SKIN_VOLUME || pixmap_id == SKIN_BALANCE) {
+                        if (ysrc+height > 421 && xsrc+width <= pixmap->width)
+                            return;
+                    }
+                    /* let's copy what's under widget */
+                    gdk_pixbuf_copy_area(skin_get_pixmap(aud_active_skin, SKIN_MAIN)->pixbuf,
+                                         x, y, width, height, pix, xdest, ydest);
+
+                    /* XMMS skins seems to have SKIN_MONOSTEREO with size 58x20 instead of 58x24 */
+                    if (pixmap_id == SKIN_MONOSTEREO)
+                        height = pixmap->height/2;
+                }
+            } else if (gtk_widget_get_parent(widget) == SKINNED_WINDOW(equalizerwin)->fixed) {
+                   if (!(pixmap_id == SKIN_EQMAIN && ysrc == 314)) /* equalizer preamp on equalizer graph */
+                         gtk_widget_hide(widget);
+            } else if (gtk_widget_get_parent(widget) == SKINNED_WINDOW(playlistwin)->fixed) {
+                   /* I haven't seen any skin with substandard playlist */
+                   gtk_widget_hide(widget);
+            }
+        } else
+            return;
+    }
+
+    width = MIN(width, pixmap->width - xsrc);
+    height = MIN(height, pixmap->height - ysrc);
+    gdk_pixbuf_copy_area(pixmap->pixbuf, xsrc, ysrc, width, height,
+                         pix, xdest, ydest);
+}
+
+void
+skin_get_eq_spline_colors(Skin * skin, guint32 colors[19])
+{
+    gint i;
+    GdkPixbuf *pixbuf;
+    SkinPixmap *eqmainpm;
+    guchar* pixels,*p;
+    guint rowstride, n_channels;
+    g_return_if_fail(skin != NULL);
+
+    eqmainpm = &skin->pixmaps[SKIN_EQMAIN];
+    if (eqmainpm->pixbuf &&
+            eqmainpm->current_width >= 116 && eqmainpm->current_height >= 313)
+        pixbuf = eqmainpm->pixbuf;
+    else
+        return;
+
+    if (!GDK_IS_PIXBUF(pixbuf))
+        return;
+
+    pixels = gdk_pixbuf_get_pixels (pixbuf);
+    rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+    n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+    for (i = 0; i < 19; i++)
+    {
+        p = pixels + rowstride * (i + 294) + 115 * n_channels;
+        colors[i] = (p[0] << 16) | (p[1] << 8) | p[2]; 
+        /* should we really treat the Alpha channel? */
+        /*if (n_channels == 4)
+            colors[i] = (colors[i] << 8) | p[3];*/
+    }
+}
+
+
+static void
+skin_draw_playlistwin_frame_top(Skin * skin, GdkPixbuf * pix,
+                                gint width, gint height, gboolean focus)
+{
+    /* The title bar skin consists of 2 sets of 4 images, 1 set
+     * for focused state and the other for unfocused. The 4 images
+     * are: 
+     *
+     * a. right corner (25,20)
+     * b. left corner  (25,20)
+     * c. tiler        (25,20)
+     * d. title        (100,20)
+     * 
+     * min allowed width = 100+25+25 = 150
+     */
+
+    gint i, y, c;
+
+    /* get y offset of the pixmap set to use */
+    if (focus)
+        y = 0;
+    else
+        y = 21;
+
+    /* left corner */
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 0, y, 0, 0, 25, 20);
+
+    /* titlebar title */
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 26, y,
+                     (width - 100) / 2, 0, 100, 20);
+
+    /* titlebar right corner  */
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 153, y,
+                     width - 25, 0, 25, 20);
+
+    /* tile draw the remaining frame */
+
+    /* compute tile count */
+    c = (width - (100 + 25 + 25)) / 25;
+
+    for (i = 0; i < c / 2; i++) {
+        /* left of title */
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
+                         25 + i * 25, 0, 25, 20);
+
+        /* right of title */
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
+                         (width + 100) / 2 + i * 25, 0, 25, 20);
+    }
+
+    if (c & 1) {
+        /* Odd tile count, so one remaining to draw. Here we split
+         * it into two and draw half on either side of the title */
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
+                         ((c / 2) * 25) + 25, 0, 12, 20);
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
+                         (width / 2) + ((c / 2) * 25) + 50, 0, 13, 20);
+    }
+}
+
+static void
+skin_draw_playlistwin_frame_bottom(Skin * skin, GdkPixbuf * pix,
+                                   gint width, gint height, gboolean focus)
+{
+    /* The bottom frame skin consists of 1 set of 4 images. The 4
+     * images are:
+     *
+     * a. left corner with menu buttons (125,38)
+     * b. visualization window (75,38)
+     * c. right corner with play buttons (150,38)
+     * d. frame tile (25,38)
+     * 
+     * (min allowed width = 125+150+25=300
+     */
+
+    gint i, c;
+
+    /* bottom left corner (menu buttons) */
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 0, 72,
+                     0, height - 38, 125, 38);
+
+    c = (width - 275) / 25;
+
+    /* draw visualization window, if width allows */
+    if (c >= 3) {
+        c -= 3;
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 205, 0,
+                         width - (150 + 75), height - 38, 75, 38);
+    }
+
+    /* Bottom right corner (playbuttons etc) */
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT,
+                     126, 72, width - 150, height - 38, 150, 38);
+
+    /* Tile draw the remaining undrawn portions */
+    for (i = 0; i < c; i++)
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 179, 0,
+                         125 + i * 25, height - 38, 25, 38);
+}
+
+static void
+skin_draw_playlistwin_frame_sides(Skin * skin, GdkPixbuf * pix,
+                                  gint width, gint height, gboolean focus)
+{
+    /* The side frames consist of 2 tile images. 1 for the left, 1 for
+     * the right. 
+     * a. left  (12,29)
+     * b. right (19,29)
+     */
+
+    gint i;
+
+    /* frame sides */
+    for (i = 0; i < (height - (20 + 38)) / 29; i++) {
+        /* left */
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 0, 42,
+                         0, 20 + i * 29, 12, 29);
+
+        /* right */
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 32, 42,
+                         width - 19, 20 + i * 29, 19, 29);
+    }
+}
+
+
+void
+skin_draw_playlistwin_frame(Skin * skin, GdkPixbuf * pix,
+                            gint width, gint height, gboolean focus)
+{
+    skin_draw_playlistwin_frame_top(skin, pix, width, height, focus);
+    skin_draw_playlistwin_frame_bottom(skin, pix, width, height, focus);
+    skin_draw_playlistwin_frame_sides(skin, pix, width, height, focus);
+}
+
+
+void
+skin_draw_playlistwin_shaded(Skin * skin, GdkPixbuf * pix,
+                             gint width, gboolean focus)
+{
+    /* The shade mode titlebar skin consists of 4 images:
+     * a) left corner               offset (72,42) size (25,14)
+     * b) right corner, focused     offset (99,57) size (50,14)
+     * c) right corner, unfocused   offset (99,42) size (50,14)
+     * d) bar tile                  offset (72,57) size (25,14)
+     */
+
+    gint i;
+
+    /* left corner */
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 72, 42, 0, 0, 25, 14);
+
+    /* bar tile */
+    for (i = 0; i < (width - 75) / 25; i++)
+        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 72, 57,
+                         (i * 25) + 25, 0, 25, 14);
+
+    /* right corner */
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 99, focus ? 42 : 57,
+                     width - 50, 0, 50, 14);
+}
+
+
+void
+skin_draw_mainwin_titlebar(Skin * skin, GdkPixbuf * pix,
+                           gboolean shaded, gboolean focus)
+{
+    /* The titlebar skin consists of 2 sets of 2 images, one for for
+     * shaded and the other for unshaded mode, giving a total of 4.
+     * The images are exactly 275x14 pixels, aligned and arranged
+     * vertically on each other in the pixmap in the following order:
+     * 
+     * a) unshaded, focused      offset (27, 0)
+     * b) unshaded, unfocused    offset (27, 15)
+     * c) shaded, focused        offset (27, 29)
+     * d) shaded, unfocused      offset (27, 42)
+     */
+
+    gint y_offset;
+
+    if (shaded) {
+        if (focus)
+            y_offset = 29;
+        else
+            y_offset = 42;
+    }
+    else {
+        if (focus)
+            y_offset = 0;
+        else
+            y_offset = 15;
+    }
+
+    skin_draw_pixbuf(NULL, skin, pix, SKIN_TITLEBAR, 27, y_offset,
+                     0, 0, aud_active_skin->properties.mainwin_width, MAINWIN_TITLEBAR_HEIGHT);
+}
+
+
+void
+skin_set_random_skin(void)
+{
+    SkinNode *node;
+    guint32 randval;
+
+    /* Get a random value to select the skin to use */
+    randval = g_random_int_range(0, g_list_length(skinlist));
+    node = g_list_nth(skinlist, randval)->data;
+    aud_active_skin_load(node->path);
+}
+
+
+void ui_skinned_widget_draw(GtkWidget *widget, GdkPixbuf *obj, gint width, gint height, gboolean scale) {
+    g_return_if_fail(widget != NULL);
+    g_return_if_fail(obj != NULL);
+
+    if (scale) {
+        gint s_width = width * cfg.scale_factor,
+             s_height = height * cfg.scale_factor;
+        GdkPixbuf *image = gdk_pixbuf_scale_simple(obj, s_width, s_height, GDK_INTERP_NEAREST);
+        gdk_draw_pixbuf(widget->window, NULL, image, 0, 0, 0, 0, s_width, s_height, GDK_RGB_DITHER_NONE, 0, 0);
+        g_object_unref(image);
+    } else {
+        gdk_draw_pixbuf(widget->window, NULL, obj, 0, 0, 0, 0, width, height, GDK_RGB_DITHER_NONE, 0, 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skin.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,247 @@
+/*  Audacious
+ *  Copyright (C) 2005-2007  Audacious development team.
+ *
+ *  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKIN_H
+#define AUDACIOUS_UI_SKIN_H
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include "audconfig.h"
+
+#define BMP_DEFAULT_SKIN_PATH \
+  DATA_DIR G_DIR_SEPARATOR_S "Skins" G_DIR_SEPARATOR_S "Default"
+
+
+typedef enum {
+    SKIN_MAIN = 0,
+    SKIN_CBUTTONS,
+    SKIN_TITLEBAR,
+    SKIN_SHUFREP,
+    SKIN_TEXT,
+    SKIN_VOLUME,
+    SKIN_BALANCE,
+    SKIN_MONOSTEREO,
+    SKIN_PLAYPAUSE,
+    SKIN_NUMBERS,
+    SKIN_POSBAR,
+    SKIN_PLEDIT,
+    SKIN_EQMAIN,
+    SKIN_EQ_EX,
+    SKIN_PIXMAP_COUNT
+} SkinPixmapId;
+
+typedef enum {
+    SKIN_MASK_MAIN = 0,
+    SKIN_MASK_MAIN_SHADE,
+    SKIN_MASK_EQ,
+    SKIN_MASK_EQ_SHADE,
+    SKIN_MASK_COUNT
+} SkinMaskId;
+
+typedef enum {
+    SKIN_PLEDIT_NORMAL = 0,
+    SKIN_PLEDIT_CURRENT,
+    SKIN_PLEDIT_NORMALBG,
+    SKIN_PLEDIT_SELECTEDBG,
+    SKIN_TEXTBG,
+    SKIN_TEXTFG,
+    SKIN_COLOR_COUNT
+} SkinColorId;
+
+typedef struct _SkinProperties {
+	/* this enables the othertext engine, not it's visibility -nenolod */
+	gboolean mainwin_othertext;
+
+	/* Vis properties */
+	gint mainwin_vis_x;
+	gint mainwin_vis_y;
+	gint mainwin_vis_width;
+	gboolean mainwin_vis_visible;
+
+	/* Text properties */
+	gint mainwin_text_x;
+	gint mainwin_text_y;
+	gint mainwin_text_width;
+	gboolean mainwin_text_visible;
+
+	/* Infobar properties */
+	gint mainwin_infobar_x;
+	gint mainwin_infobar_y;
+	gboolean mainwin_othertext_visible;
+
+	gint mainwin_number_0_x;
+	gint mainwin_number_0_y;
+
+	gint mainwin_number_1_x;
+	gint mainwin_number_1_y;
+
+	gint mainwin_number_2_x;
+	gint mainwin_number_2_y;
+
+	gint mainwin_number_3_x;
+	gint mainwin_number_3_y;
+
+	gint mainwin_number_4_x;
+	gint mainwin_number_4_y;
+
+	gint mainwin_playstatus_x;
+	gint mainwin_playstatus_y;
+
+	gint mainwin_volume_x;
+	gint mainwin_volume_y;	
+
+	gint mainwin_balance_x;
+	gint mainwin_balance_y;	
+
+	gint mainwin_position_x;
+	gint mainwin_position_y;
+
+	gint mainwin_previous_x;
+	gint mainwin_previous_y;
+
+	gint mainwin_play_x;
+	gint mainwin_play_y;
+
+	gint mainwin_pause_x;
+	gint mainwin_pause_y;
+
+	gint mainwin_stop_x;
+	gint mainwin_stop_y;
+
+	gint mainwin_next_x;
+	gint mainwin_next_y;
+
+	gint mainwin_eject_x;
+	gint mainwin_eject_y;
+
+	gint mainwin_eqbutton_x;
+	gint mainwin_eqbutton_y;
+
+	gint mainwin_plbutton_x;
+	gint mainwin_plbutton_y;
+
+	gint mainwin_shuffle_x;
+	gint mainwin_shuffle_y;
+
+	gint mainwin_repeat_x;
+	gint mainwin_repeat_y;
+
+	gint mainwin_about_x;
+	gint mainwin_about_y;
+
+	gint mainwin_minimize_x;
+	gint mainwin_minimize_y;
+
+	gint mainwin_shade_x;
+	gint mainwin_shade_y;
+
+	gint mainwin_close_x;
+	gint mainwin_close_y;
+
+	gint mainwin_width;
+	gint mainwin_height;
+
+	gboolean mainwin_menurow_visible;
+	gboolean mainwin_othertext_is_status;
+
+	gint textbox_bitmap_font_width;
+	gint textbox_bitmap_font_height;
+} SkinProperties;
+
+#define SKIN_PIXMAP(x)  ((SkinPixmap *)(x))
+typedef struct _SkinPixmap {
+    GdkPixbuf *pixbuf;
+
+    /* The real size of the pixmap */
+    gint width, height;
+
+    /* The size of the pixmap from the current skin,
+       which might be smaller */
+    gint current_width, current_height;
+} SkinPixmap;
+
+
+#define SKIN(x)  ((Skin *)(x))
+typedef struct _Skin {
+    GMutex *lock;
+    gchar *path;
+    gchar *def_path;
+    SkinPixmap pixmaps[SKIN_PIXMAP_COUNT];
+    GdkColor textbg[6], def_textbg[6];
+    GdkColor textfg[6], def_textfg[6];
+    GdkColor *colors[SKIN_COLOR_COUNT];
+    guchar vis_color[24][3];
+    GdkBitmap *masks[SKIN_MASK_COUNT];
+    GdkBitmap *scaled_masks[SKIN_MASK_COUNT];
+    SkinProperties properties;
+} Skin;
+
+extern Skin *aud_active_skin;
+
+gboolean init_skins(const gchar * path);
+void cleanup_skins(void);
+
+gboolean aud_active_skin_load(const gchar * path);
+gboolean aud_active_skin_reload(void);
+
+Skin *skin_new(void);
+gboolean skin_load(Skin * skin, const gchar * path);
+gboolean skin_reload_forced(void);
+void skin_reload(Skin * skin);
+void skin_free(Skin * skin);
+
+GdkBitmap *skin_get_mask(Skin * skin, SkinMaskId mi);
+GdkColor *skin_get_color(Skin * skin, SkinColorId color_id);
+
+void skin_get_viscolor(Skin * skin, guchar vis_color[24][3]);
+gint skin_get_id(void);
+void skin_draw_pixbuf(GtkWidget *widget, Skin * skin, GdkPixbuf * pix,
+                 SkinPixmapId pixmap_id,
+                 gint xsrc, gint ysrc, gint xdest, gint ydest,
+                 gint width, gint height);
+
+void skin_get_eq_spline_colors(Skin * skin, guint32 colors[19]);
+void skin_install_skin(const gchar * path);
+
+void skin_draw_playlistwin_shaded(Skin * skin, GdkPixbuf * pix,
+                                  gint width, gboolean focus);
+void skin_draw_playlistwin_frame(Skin * skin, GdkPixbuf * pix,
+                                 gint width, gint height, gboolean focus);
+
+void skin_draw_mainwin_titlebar(Skin * skin, GdkPixbuf * pix,
+                                gboolean shaded, gboolean focus);
+
+
+void skin_parse_hints(Skin * skin, gchar *path_p);
+
+
+void skin_set_random_skin(void);
+
+
+void ui_skinned_widget_draw(GtkWidget *widget, GdkPixbuf *obj, gint width, gint height, gboolean scale);
+
+#endif /* AUDACIOUS_UI_SKIN_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_button.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,535 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skinned_button.h"
+#include <math.h>
+
+#define UI_SKINNED_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_button_get_type(), UiSkinnedButtonPrivate))
+typedef struct _UiSkinnedButtonPrivate UiSkinnedButtonPrivate;
+
+enum {
+    PRESSED,
+    RELEASED,
+    CLICKED,
+    DOUBLED,
+    REDRAW,
+    LAST_SIGNAL
+};
+
+struct _UiSkinnedButtonPrivate {
+    //Skinned part
+    GdkGC            *gc;
+    gint             w;
+    gint             h;
+    SkinPixmapId     skin_index1;
+    SkinPixmapId     skin_index2;
+    gboolean         scaled;
+    gint             move_x, move_y;
+
+    gint             nx, ny, px, py;
+    //Toogle button needs also those
+    gint             pnx, pny, ppx, ppy;
+};
+
+
+static GtkWidgetClass *parent_class = NULL;
+static void ui_skinned_button_class_init(UiSkinnedButtonClass *klass);
+static void ui_skinned_button_init(UiSkinnedButton *button);
+static void ui_skinned_button_destroy(GtkObject *object);
+static void ui_skinned_button_realize(GtkWidget *widget);
+static void ui_skinned_button_unrealize(GtkWidget *widget);
+static void ui_skinned_button_map(GtkWidget *widget);
+static void ui_skinned_button_unmap(GtkWidget *widget);
+static void ui_skinned_button_size_request(GtkWidget *widget, GtkRequisition *requisition);
+static gint ui_skinned_button_expose(GtkWidget *widget,GdkEventExpose *event);
+
+static void ui_skinned_button_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
+static void ui_skinned_button_update_state(UiSkinnedButton *button);
+
+static guint button_signals[LAST_SIGNAL] = { 0 };
+static gint ui_skinned_button_button_press(GtkWidget *widget, GdkEventButton *event);
+static gint ui_skinned_button_button_release(GtkWidget *widget, GdkEventButton *event);
+static void button_pressed(UiSkinnedButton *button);
+static void button_released(UiSkinnedButton *button);
+static void ui_skinned_button_pressed(UiSkinnedButton *button);
+static void ui_skinned_button_released(UiSkinnedButton *button);
+static void ui_skinned_button_clicked(UiSkinnedButton *button);
+static void ui_skinned_button_set_pressed (UiSkinnedButton *button, gboolean pressed);
+
+static void ui_skinned_button_toggle_scaled(UiSkinnedButton *button);
+
+static gint ui_skinned_button_enter_notify(GtkWidget *widget, GdkEventCrossing *event);
+static gint ui_skinned_button_leave_notify(GtkWidget *widget, GdkEventCrossing *event);
+static void ui_skinned_button_redraw(UiSkinnedButton *button);
+
+GType ui_skinned_button_get_type() {
+    static GType button_type = 0;
+    if (!button_type) {
+        static const GTypeInfo button_info = {
+            sizeof (UiSkinnedButtonClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_button_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedButton),
+            0,
+            (GInstanceInitFunc) ui_skinned_button_init,
+        };
+        button_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedButton_", &button_info, 0);
+    }
+
+    return button_type;
+}
+
+static void ui_skinned_button_class_init (UiSkinnedButtonClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_button_destroy;
+
+    widget_class->realize = ui_skinned_button_realize;
+    widget_class->unrealize = ui_skinned_button_unrealize;
+    widget_class->map = ui_skinned_button_map;
+    widget_class->unmap = ui_skinned_button_unmap;
+    widget_class->expose_event = ui_skinned_button_expose;
+    widget_class->size_request = ui_skinned_button_size_request;
+    widget_class->size_allocate = ui_skinned_button_size_allocate;
+    widget_class->button_press_event = ui_skinned_button_button_press;
+    widget_class->button_release_event = ui_skinned_button_button_release;
+    widget_class->enter_notify_event = ui_skinned_button_enter_notify;
+    widget_class->leave_notify_event = ui_skinned_button_leave_notify;
+
+    klass->pressed = button_pressed;
+    klass->released = button_released;
+    klass->clicked = NULL;
+    klass->scaled = ui_skinned_button_toggle_scaled;
+    klass->redraw = ui_skinned_button_redraw;
+
+    button_signals[PRESSED] = 
+        g_signal_new ("pressed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST,
+                      G_STRUCT_OFFSET (UiSkinnedButtonClass, pressed), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    button_signals[RELEASED] = 
+        g_signal_new ("released", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST,
+                      G_STRUCT_OFFSET (UiSkinnedButtonClass, released), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    button_signals[CLICKED] = 
+        g_signal_new ("clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedButtonClass, clicked), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    button_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedButtonClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    button_signals[REDRAW] = 
+        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedButtonClass, redraw), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    g_type_class_add_private (gobject_class, sizeof (UiSkinnedButtonPrivate));
+}
+
+static void ui_skinned_button_init (UiSkinnedButton *button) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    button->inside = FALSE;
+    button->type = TYPE_NOT_SET;
+    priv->move_x = 0;
+    priv->move_y = 0;
+    button->event_window = NULL;
+}
+
+static void ui_skinned_button_destroy (GtkObject *object) {
+    UiSkinnedButton *button;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_BUTTON (object));
+
+    button = UI_SKINNED_BUTTON(object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_button_realize (GtkWidget *widget) {
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_BUTTON(widget));
+    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
+
+    if (button->type == TYPE_SMALL || button->type == TYPE_NOT_SET) {
+        widget->window = gtk_widget_get_parent_window (widget);
+        g_object_ref (widget->window);
+        attributes.wclass = GDK_INPUT_ONLY;
+        attributes_mask = GDK_WA_X | GDK_WA_Y;
+        button->event_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+        GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
+        gdk_window_set_user_data(button->event_window, widget);
+    } else {
+        attributes.visual = gtk_widget_get_visual(widget);
+        attributes.colormap = gtk_widget_get_colormap(widget);
+        attributes.wclass = GDK_INPUT_OUTPUT;
+        attributes.event_mask |= GDK_EXPOSURE_MASK;
+        attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+        widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+        GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW);
+        gdk_window_set_user_data(widget->window, widget);
+    }
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+}
+
+static void ui_skinned_button_unrealize (GtkWidget *widget) {
+    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
+
+    if ( button->event_window != NULL )
+    {
+      gdk_window_set_user_data( button->event_window , NULL );
+      gdk_window_destroy( button->event_window );
+      button->event_window = NULL;
+    }
+
+    if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+        (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void ui_skinned_button_map (GtkWidget *widget)
+{
+    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
+
+    if (button->event_window != NULL)
+      gdk_window_show (button->event_window);
+
+    if (GTK_WIDGET_CLASS (parent_class)->map)
+      (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+}
+
+static void ui_skinned_button_unmap (GtkWidget *widget)
+{
+    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
+
+    if (button->event_window != NULL)
+      gdk_window_hide (button->event_window);
+
+    if (GTK_WIDGET_CLASS (parent_class)->unmap)
+      (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+}
+
+static void ui_skinned_button_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(widget);
+    requisition->width = priv->w*(priv->scaled ? cfg.scale_factor : 1);
+    requisition->height = priv->h*(priv->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_button_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    widget->allocation = *allocation;
+    widget->allocation.x = ceil(widget->allocation.x*(priv->scaled ? cfg.scale_factor : 1));
+    widget->allocation.y = ceil(widget->allocation.y*(priv->scaled ? cfg.scale_factor : 1));
+
+    if (GTK_WIDGET_REALIZED (widget))
+    {
+        if ( button->event_window != NULL )
+            gdk_window_move_resize(button->event_window, ceil(allocation->x*(priv->scaled ? cfg.scale_factor : 1)), ceil(allocation->y*(priv->scaled ? cfg.scale_factor : 1)), allocation->width, allocation->height);
+        else
+            gdk_window_move_resize(widget->window, ceil(allocation->x*(priv->scaled ? cfg.scale_factor : 1)), ceil(allocation->y*(priv->scaled ? cfg.scale_factor : 1)), allocation->width, allocation->height);
+    }
+
+    if (button->x + priv->move_x == ceil(widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1)))
+        priv->move_x = 0;
+    if (button->y + priv->move_y == ceil(widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1)))
+        priv->move_y = 0;
+
+    button->x = ceil(widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1));
+    button->y = ceil(widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1));
+}
+
+static gboolean ui_skinned_button_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_BUTTON (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    g_return_val_if_fail (priv->w > 0 && priv->h > 0, FALSE);
+
+    //TYPE_SMALL doesn't have its own face
+    if (button->type == TYPE_SMALL || button->type == TYPE_NOT_SET)
+        return FALSE;
+
+    /* paranoia */
+    if (button->event_window != NULL)
+        return FALSE;
+
+    GdkPixbuf *obj;
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->w, priv->h);
+
+    switch (button->type) {
+        case TYPE_PUSH:
+            skin_draw_pixbuf(widget, aud_active_skin, obj,
+                             button->pressed ? priv->skin_index2 : priv->skin_index1,
+                             button->pressed ? priv->px : priv->nx,
+                             button->pressed ? priv->py : priv->ny,
+                             0, 0, priv->w, priv->h);
+            break;
+        case TYPE_TOGGLE:
+            if (button->inside)
+                skin_draw_pixbuf(widget, aud_active_skin, obj,
+                                 button->pressed ? priv->skin_index2 : priv->skin_index1,
+                                 button->pressed ? priv->ppx : priv->pnx,
+                                 button->pressed ? priv->ppy : priv->pny,
+                                 0, 0, priv->w, priv->h);
+            else
+                skin_draw_pixbuf(widget, aud_active_skin, obj,
+                                 button->pressed ? priv->skin_index2 : priv->skin_index1,
+                                 button->pressed ? priv->px : priv->nx,
+                                 button->pressed ? priv->py : priv->ny,
+                                 0, 0, priv->w, priv->h);
+            break;
+        default:
+            break;
+    }
+
+    ui_skinned_widget_draw(widget, obj, priv->w, priv->h, priv->scaled);
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+GtkWidget* ui_skinned_button_new () {
+    UiSkinnedButton *button = g_object_new (ui_skinned_button_get_type (), NULL);
+
+    return GTK_WIDGET(button);
+}
+
+void ui_skinned_push_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, SkinPixmapId si) {
+
+    UiSkinnedButton *sbutton = UI_SKINNED_BUTTON(button);
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(sbutton);
+    priv->w = w;
+    priv->h = h;
+    sbutton->x = x;
+    sbutton->y = y;
+    priv->nx = nx;
+    priv->ny = ny;
+    priv->px = px;
+    priv->py = py;
+    sbutton->type = TYPE_PUSH;
+    priv->skin_index1 = si;
+    priv->skin_index2 = si;
+    priv->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(button), sbutton->x, sbutton->y);
+}
+
+void ui_skinned_toggle_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, gint pnx, gint pny, gint ppx, gint ppy, SkinPixmapId si) {
+
+    UiSkinnedButton *sbutton = UI_SKINNED_BUTTON(button);
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(sbutton);
+    priv->w = w;
+    priv->h = h;
+    sbutton->x = x;
+    sbutton->y = y;
+    priv->nx = nx;
+    priv->ny = ny;
+    priv->px = px;
+    priv->py = py;
+    priv->pnx = pnx;
+    priv->pny = pny;
+    priv->ppx = ppx;
+    priv->ppy = ppy;
+    sbutton->type = TYPE_TOGGLE;
+    priv->skin_index1 = si;
+    priv->skin_index2 = si;
+    priv->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(button), sbutton->x, sbutton->y);
+}
+
+void ui_skinned_small_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h) {
+
+    UiSkinnedButton *sbutton = UI_SKINNED_BUTTON(button);
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(sbutton);
+    priv->w = w;
+    priv->h = h;
+    sbutton->x = x;
+    sbutton->y = y;
+    sbutton->type = TYPE_SMALL;
+    priv->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(button), sbutton->x, sbutton->y);
+}
+
+static void button_pressed(UiSkinnedButton *button) {
+    button->button_down = TRUE;
+    ui_skinned_button_update_state(button);
+}
+
+static void button_released(UiSkinnedButton *button) {
+    button->button_down = FALSE;
+    if(button->hover) ui_skinned_button_clicked(button);
+    ui_skinned_button_update_state(button);
+}
+
+static void ui_skinned_button_update_state(UiSkinnedButton *button) {
+    ui_skinned_button_set_pressed(button, button->button_down); 
+}
+
+static void ui_skinned_button_set_pressed (UiSkinnedButton *button, gboolean pressed) {
+    if (pressed != button->pressed) {
+        button->pressed = pressed;
+        gtk_widget_queue_draw(GTK_WIDGET(button));
+    }
+}
+
+static gboolean ui_skinned_button_button_press(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedButton *button;
+
+    if (event->type == GDK_BUTTON_PRESS) {
+        button = UI_SKINNED_BUTTON(widget);
+
+        if (event->button == 1)
+            ui_skinned_button_pressed (button);
+        else if (event->button == 3) {
+            event->x = event->x + button->x;
+            event->y = event->y + button->y;
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_button_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedButton *button;
+    if (event->button == 1) {
+            button = UI_SKINNED_BUTTON(widget);
+            ui_skinned_button_released(button);
+    }
+    return TRUE;
+}
+
+static void ui_skinned_button_pressed(UiSkinnedButton *button) {
+    g_return_if_fail(UI_SKINNED_IS_BUTTON(button));
+    g_signal_emit(button, button_signals[PRESSED], 0);
+}
+
+static void ui_skinned_button_released(UiSkinnedButton *button) {
+    g_return_if_fail(UI_SKINNED_IS_BUTTON(button));
+    g_signal_emit(button, button_signals[RELEASED], 0);
+}
+
+static void ui_skinned_button_clicked(UiSkinnedButton *button) {
+    g_return_if_fail(UI_SKINNED_IS_BUTTON(button));
+    button->inside = !button->inside;
+    g_signal_emit(button, button_signals[CLICKED], 0);
+}
+
+static gboolean ui_skinned_button_enter_notify(GtkWidget *widget, GdkEventCrossing *event) {
+    UiSkinnedButton *button;
+
+    button = UI_SKINNED_BUTTON(widget);
+    button->hover = TRUE;
+    if(button->button_down) ui_skinned_button_set_pressed(button, TRUE);
+
+    return FALSE;
+}
+
+static gboolean ui_skinned_button_leave_notify(GtkWidget *widget, GdkEventCrossing *event) {
+    UiSkinnedButton *button;
+
+    button = UI_SKINNED_BUTTON (widget);
+    button->hover = FALSE;
+    if(button->button_down) ui_skinned_button_set_pressed(button, FALSE);
+
+    return FALSE;
+}
+
+static void ui_skinned_button_toggle_scaled(UiSkinnedButton *button) {
+    GtkWidget *widget = GTK_WIDGET (button);
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    priv->scaled = !priv->scaled;
+
+    gtk_widget_set_size_request(widget, priv->w*(priv->scaled ? cfg.scale_factor : 1), priv->h*(priv->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(widget);
+}
+
+static void ui_skinned_button_redraw(UiSkinnedButton *button) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    if (priv->move_x || priv->move_y)
+        gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(GTK_WIDGET(button))), GTK_WIDGET(button),
+                       button->x+priv->move_x, button->y+priv->move_y);
+
+    gtk_widget_queue_draw(GTK_WIDGET(button));
+}
+
+
+void ui_skinned_set_push_button_data(GtkWidget *button, gint nx, gint ny, gint px, gint py) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(button);
+    if (nx > -1) priv->nx = nx;
+    if (ny > -1) priv->ny = ny;
+    if (px > -1) priv->px = px;
+    if (py > -1) priv->py = py;
+    gtk_widget_queue_draw(button);
+}
+
+void ui_skinned_button_set_skin_index(GtkWidget *button, SkinPixmapId si) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    priv->skin_index1 = priv->skin_index2 = si;
+}
+
+void ui_skinned_button_set_skin_index1(GtkWidget *button, SkinPixmapId si) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    priv->skin_index1 = si;
+}
+
+void ui_skinned_button_set_skin_index2(GtkWidget *button, SkinPixmapId si) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    priv->skin_index2 = si;
+}
+
+void ui_skinned_button_move_relative(GtkWidget *button, gint x, gint y) {
+    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
+    priv->move_x += x;
+    priv->move_y += y;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_button.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,74 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_BUTTON_H
+#define AUDACIOUS_UI_SKINNED_BUTTON_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#define UI_SKINNED_BUTTON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), ui_skinned_button_get_type(), UiSkinnedButton))
+#define UI_SKINNED_BUTTON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  ui_skinned_button_get_type(), UiSkinnedButtonClass))
+#define UI_SKINNED_IS_BUTTON(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ui_skinned_button_get_type()))
+
+typedef struct _UiSkinnedButton		UiSkinnedButton;
+typedef struct _UiSkinnedButtonClass	UiSkinnedButtonClass;
+
+enum {
+    TYPE_NOT_SET,
+    TYPE_PUSH,
+    TYPE_TOGGLE,
+    TYPE_SMALL
+};
+
+struct _UiSkinnedButton {
+    GtkWidget widget;
+
+    GdkWindow *event_window;
+    gboolean button_down;
+    gboolean pressed;
+    gboolean hover;
+    gboolean inside;
+    gint type;
+    gint x, y;
+};
+
+struct _UiSkinnedButtonClass {
+    GtkWidgetClass          parent_class;
+    void (* pressed)       (UiSkinnedButton *button);
+    void (* released)      (UiSkinnedButton *button);
+    void (* clicked)       (UiSkinnedButton *button);
+    void (* right_clicked) (UiSkinnedButton *button);
+    void (* scaled)        (UiSkinnedButton *button);
+    void (* redraw)        (UiSkinnedButton *button);
+};
+
+GType ui_skinned_button_get_type(void) G_GNUC_CONST;
+GtkWidget* ui_skinned_button_new();
+void ui_skinned_push_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, SkinPixmapId si);
+void ui_skinned_set_push_button_data(GtkWidget *button, gint nx, gint ny, gint px, gint py);
+void ui_skinned_toggle_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, gint pnx, gint pny, gint ppx, gint ppy, SkinPixmapId si);
+void ui_skinned_small_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h);
+void ui_skinned_button_set_skin_index(GtkWidget *button, SkinPixmapId si);
+void ui_skinned_button_set_skin_index1(GtkWidget *button, SkinPixmapId si);
+void ui_skinned_button_set_skin_index2(GtkWidget *button, SkinPixmapId si);
+void ui_skinned_button_move_relative(GtkWidget *button, gint x, gint y);
+
+#endif /* AUDACIOUS_UI_SKINNED_BUTTON_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_equalizer_graph.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,307 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ */
+
+#include "ui_skin.h"
+#include "ui_skinned_equalizer_graph.h"
+#include "main.h"
+#include "equalizer_flow.h"
+
+#define UI_TYPE_SKINNED_EQUALIZER_GRAPH           (ui_skinned_equalizer_graph_get_type())
+
+enum {
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+static void ui_skinned_equalizer_graph_class_init         (UiSkinnedEqualizerGraphClass *klass);
+static void ui_skinned_equalizer_graph_init               (UiSkinnedEqualizerGraph *equalizer_graph);
+static void ui_skinned_equalizer_graph_destroy            (GtkObject *object);
+static void ui_skinned_equalizer_graph_realize            (GtkWidget *widget);
+static void ui_skinned_equalizer_graph_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_equalizer_graph_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_equalizer_graph_expose         (GtkWidget *widget, GdkEventExpose *event);
+static void ui_skinned_equalizer_graph_toggle_scaled  (UiSkinnedEqualizerGraph *equalizer_graph);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint equalizer_graph_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_equalizer_graph_get_type() {
+    static GType equalizer_graph_type = 0;
+    if (!equalizer_graph_type) {
+        static const GTypeInfo equalizer_graph_info = {
+            sizeof (UiSkinnedEqualizerGraphClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_equalizer_graph_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedEqualizerGraph),
+            0,
+            (GInstanceInitFunc) ui_skinned_equalizer_graph_init,
+        };
+        equalizer_graph_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedEqualizerGraph_", &equalizer_graph_info, 0);
+    }
+
+    return equalizer_graph_type;
+}
+
+static void ui_skinned_equalizer_graph_class_init(UiSkinnedEqualizerGraphClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_equalizer_graph_destroy;
+
+    widget_class->realize = ui_skinned_equalizer_graph_realize;
+    widget_class->expose_event = ui_skinned_equalizer_graph_expose;
+    widget_class->size_request = ui_skinned_equalizer_graph_size_request;
+    widget_class->size_allocate = ui_skinned_equalizer_graph_size_allocate;
+
+    klass->scaled = ui_skinned_equalizer_graph_toggle_scaled;
+
+    equalizer_graph_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedEqualizerGraphClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+static void ui_skinned_equalizer_graph_init(UiSkinnedEqualizerGraph *equalizer_graph) {
+    equalizer_graph->width = 113;
+    equalizer_graph->height = 19;
+}
+
+GtkWidget* ui_skinned_equalizer_graph_new(GtkWidget *fixed, gint x, gint y) {
+    UiSkinnedEqualizerGraph *equalizer_graph = g_object_new (ui_skinned_equalizer_graph_get_type (), NULL);
+
+    equalizer_graph->x = x;
+    equalizer_graph->y = y;
+    equalizer_graph->skin_index = SKIN_EQMAIN;
+    equalizer_graph->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(equalizer_graph), equalizer_graph->x, equalizer_graph->y);
+
+    return GTK_WIDGET(equalizer_graph);
+}
+
+static void ui_skinned_equalizer_graph_destroy(GtkObject *object) {
+    UiSkinnedEqualizerGraph *equalizer_graph;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_GRAPH (object));
+
+    equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_equalizer_graph_realize(GtkWidget *widget) {
+    UiSkinnedEqualizerGraph *equalizer_graph;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_GRAPH(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_equalizer_graph_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedEqualizerGraph *equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH(widget);
+
+    requisition->width = equalizer_graph->width*(equalizer_graph->scaled ? cfg.scale_factor : 1);
+    requisition->height = equalizer_graph->height*(equalizer_graph->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_equalizer_graph_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedEqualizerGraph *equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH (widget);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (equalizer_graph->scaled ? cfg.scale_factor : 1);
+    widget->allocation.y *= (equalizer_graph->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    equalizer_graph->x = widget->allocation.x/(equalizer_graph->scaled ? cfg.scale_factor : 1);
+    equalizer_graph->y = widget->allocation.y/(equalizer_graph->scaled ? cfg.scale_factor : 1);
+}
+
+void
+init_spline(gfloat * x, gfloat * y, gint n, gfloat * y2)
+{
+    gint i, k;
+    gfloat p, qn, sig, un, *u;
+
+    u = (gfloat *) g_malloc(n * sizeof(gfloat));
+
+    y2[0] = u[0] = 0.0;
+
+    for (i = 1; i < n - 1; i++) {
+        sig = ((gfloat) x[i] - x[i - 1]) / ((gfloat) x[i + 1] - x[i - 1]);
+        p = sig * y2[i - 1] + 2.0;
+        y2[i] = (sig - 1.0) / p;
+        u[i] =
+            (((gfloat) y[i + 1] - y[i]) / (x[i + 1] - x[i])) -
+            (((gfloat) y[i] - y[i - 1]) / (x[i] - x[i - 1]));
+        u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
+    }
+    qn = un = 0.0;
+
+    y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0);
+    for (k = n - 2; k >= 0; k--)
+        y2[k] = y2[k] * y2[k + 1] + u[k];
+    g_free(u);
+}
+
+gfloat
+eval_spline(gfloat xa[], gfloat ya[], gfloat y2a[], gint n, gfloat x)
+{
+    gint klo, khi, k;
+    gfloat h, b, a;
+
+    klo = 0;
+    khi = n - 1;
+    while (khi - klo > 1) {
+        k = (khi + klo) >> 1;
+        if (xa[k] > x)
+            khi = k;
+        else
+            klo = k;
+    }
+    h = xa[khi] - xa[klo];
+    a = (xa[khi] - x) / h;
+    b = (x - xa[klo]) / h;
+    return (a * ya[klo] + b * ya[khi] +
+            ((a * a * a - a) * y2a[klo] +
+             (b * b * b - b) * y2a[khi]) * (h * h) / 6.0);
+}
+
+static gboolean ui_skinned_equalizer_graph_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_GRAPH (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedEqualizerGraph *equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH (widget);
+    g_return_val_if_fail (equalizer_graph->width > 0 && equalizer_graph->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, equalizer_graph->width, equalizer_graph->height);
+
+    guint32 cols[19], rowstride;
+    gint i, y, ymin, ymax, py = 0;
+    gfloat x[] = { 0, 11, 23, 35, 47, 59, 71, 83, 97, 109 }, yf[10];
+    guchar* pixels, *p;
+    gint n_channels;
+    /*
+     * This avoids the init_spline() function to be inlined.
+     * Inlining the function caused troubles when compiling with
+     * `-O' (at least on FreeBSD).
+     */
+    void (*__init_spline) (gfloat *, gfloat *, gint, gfloat *) = init_spline;
+
+    skin_draw_pixbuf(widget, aud_active_skin, obj, equalizer_graph->skin_index, 0, 294, 0, 0,
+                     equalizer_graph->width, equalizer_graph->height);
+    skin_draw_pixbuf(widget, aud_active_skin, obj, equalizer_graph->skin_index, 0, 314,
+                     0, 9 + ((cfg.equalizer_preamp * 9) / 20),
+                     equalizer_graph->width, 1);
+
+    skin_get_eq_spline_colors(aud_active_skin, cols);
+
+    __init_spline(x, cfg.equalizer_bands, AUD_EQUALIZER_NBANDS, yf);
+    for (i = 0; i < 109; i++) {
+        y = 9 -
+            (gint) ((eval_spline(x, cfg.equalizer_bands, yf, AUD_EQUALIZER_NBANDS, i) *
+                     9.0) / EQUALIZER_MAX_GAIN);
+        if (y < 0)
+            y = 0;
+        if (y > 18)
+            y = 18;
+        if (!i)
+            py = y;
+        if (y < py) {
+            ymin = y;
+            ymax = py;
+        }
+        else {
+            ymin = py;
+            ymax = y;
+        }
+        py = y;
+
+        pixels = gdk_pixbuf_get_pixels(obj);
+        rowstride = gdk_pixbuf_get_rowstride(obj);
+        n_channels = gdk_pixbuf_get_n_channels(obj); 
+
+        for (y = ymin; y <= ymax; y++) 
+        {
+            p = pixels + (y * rowstride) + (( i + 2) * n_channels); 
+            p[0] = (cols[y] & 0xff0000) >> 16;
+            p[1] = (cols[y] & 0x00ff00) >> 8;
+            p[2] = (cols[y] & 0x0000ff);
+            /* do we really need to treat the alpha channel? */
+            /*if (n_channels == 4)
+                  p[3] = cols[y] >> 24;*/
+        }
+    }
+
+    ui_skinned_widget_draw(widget, obj, equalizer_graph->width, equalizer_graph->height, equalizer_graph->scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static void ui_skinned_equalizer_graph_toggle_scaled(UiSkinnedEqualizerGraph *equalizer_graph) {
+    GtkWidget *widget = GTK_WIDGET (equalizer_graph);
+
+    equalizer_graph->scaled = !equalizer_graph->scaled;
+    gtk_widget_set_size_request(widget, equalizer_graph->width*(equalizer_graph->scaled ? cfg.scale_factor : 1),
+                                        equalizer_graph->height*(equalizer_graph->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(GTK_WIDGET(equalizer_graph));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_equalizer_graph.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_EQUALIZER_GRAPH_H
+#define AUDACIOUS_UI_SKINNED_EQUALIZER_GRAPH_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_EQUALIZER_GRAPH(obj)          GTK_CHECK_CAST (obj, ui_skinned_equalizer_graph_get_type (), UiSkinnedEqualizerGraph)
+#define UI_SKINNED_EQUALIZER_GRAPH_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_equalizer_graph_get_type (), UiSkinnedEqualizerGraphClass)
+#define UI_SKINNED_IS_EQUALIZER_GRAPH(obj)       GTK_CHECK_TYPE (obj, ui_skinned_equalizer_graph_get_type ())
+
+typedef struct _UiSkinnedEqualizerGraph        UiSkinnedEqualizerGraph;
+typedef struct _UiSkinnedEqualizerGraphClass   UiSkinnedEqualizerGraphClass;
+
+struct _UiSkinnedEqualizerGraph {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    SkinPixmapId     skin_index;
+    gboolean         scaled;
+};
+
+struct _UiSkinnedEqualizerGraphClass {
+    GtkWidgetClass          parent_class;
+    void (* scaled)        (UiSkinnedEqualizerGraph *eq_graph);
+};
+
+GtkWidget* ui_skinned_equalizer_graph_new(GtkWidget *fixed, gint x, gint y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_EQUALIZER_GRAPH_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_equalizer_slider.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,392 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ */
+
+#include "ui_skin.h"
+#include "ui_skinned_equalizer_slider.h"
+#include "ui_equalizer.h"
+#include "ui_main.h"
+#include "equalizer_flow.h"
+#include <glib/gi18n.h>
+
+#define UI_TYPE_SKINNED_EQUALIZER_SLIDER           (ui_skinned_equalizer_slider_get_type())
+#define UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UI_TYPE_SKINNED_EQUALIZER_SLIDER, UiSkinnedEqualizerSliderPrivate))
+typedef struct _UiSkinnedEqualizerSliderPrivate UiSkinnedEqualizerSliderPrivate;
+
+enum {
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+struct _UiSkinnedEqualizerSliderPrivate {
+    SkinPixmapId     skin_index;
+    gboolean         scaled;
+    gint             position;
+    gint             width, height;
+    gboolean         pressed;
+    gint             drag_y;
+    gfloat           value; /* store gain as is to prevent truncation --asphyx */
+};
+
+static void ui_skinned_equalizer_slider_class_init         (UiSkinnedEqualizerSliderClass *klass);
+static void ui_skinned_equalizer_slider_init               (UiSkinnedEqualizerSlider *equalizer_slider);
+static void ui_skinned_equalizer_slider_destroy            (GtkObject *object);
+static void ui_skinned_equalizer_slider_realize            (GtkWidget *widget);
+static void ui_skinned_equalizer_slider_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_equalizer_slider_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_equalizer_slider_expose         (GtkWidget *widget, GdkEventExpose *event);
+static gboolean ui_skinned_equalizer_slider_button_press   (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_equalizer_slider_button_release (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_equalizer_slider_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
+static gboolean ui_skinned_equalizer_slider_scroll         (GtkWidget *widget, GdkEventScroll *event);
+static void ui_skinned_equalizer_slider_toggle_scaled      (UiSkinnedEqualizerSlider *equalizer_slider);
+void ui_skinned_equalizer_slider_set_mainwin_text          (UiSkinnedEqualizerSlider * es);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint equalizer_slider_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_equalizer_slider_get_type() {
+    static GType equalizer_slider_type = 0;
+    if (!equalizer_slider_type) {
+        static const GTypeInfo equalizer_slider_info = {
+            sizeof (UiSkinnedEqualizerSliderClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_equalizer_slider_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedEqualizerSlider),
+            0,
+            (GInstanceInitFunc) ui_skinned_equalizer_slider_init,
+        };
+        equalizer_slider_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedEqualizerSlider_", &equalizer_slider_info, 0);
+    }
+
+    return equalizer_slider_type;
+}
+
+static void ui_skinned_equalizer_slider_class_init(UiSkinnedEqualizerSliderClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_equalizer_slider_destroy;
+
+    widget_class->realize = ui_skinned_equalizer_slider_realize;
+    widget_class->expose_event = ui_skinned_equalizer_slider_expose;
+    widget_class->size_request = ui_skinned_equalizer_slider_size_request;
+    widget_class->size_allocate = ui_skinned_equalizer_slider_size_allocate;
+    widget_class->button_press_event = ui_skinned_equalizer_slider_button_press;
+    widget_class->button_release_event = ui_skinned_equalizer_slider_button_release;
+    widget_class->motion_notify_event = ui_skinned_equalizer_slider_motion_notify;
+    widget_class->scroll_event = ui_skinned_equalizer_slider_scroll;
+
+    klass->scaled = ui_skinned_equalizer_slider_toggle_scaled;
+
+    equalizer_slider_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedEqualizerSliderClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    g_type_class_add_private (gobject_class, sizeof (UiSkinnedEqualizerSliderPrivate));
+}
+
+static void ui_skinned_equalizer_slider_init(UiSkinnedEqualizerSlider *equalizer_slider) {
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(equalizer_slider);
+    priv->pressed = FALSE;
+}
+
+GtkWidget* ui_skinned_equalizer_slider_new(GtkWidget *fixed, gint x, gint y) {
+    UiSkinnedEqualizerSlider *es = g_object_new (ui_skinned_equalizer_slider_get_type (), NULL);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(es);
+
+    es->x = x;
+    es->y = y;
+    priv->width = 14;
+    priv->height = 63;
+    priv->skin_index = SKIN_EQMAIN;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(es), es->x, es->y);
+
+    return GTK_WIDGET(es);
+}
+
+static void ui_skinned_equalizer_slider_destroy(GtkObject *object) {
+    UiSkinnedEqualizerSlider *equalizer_slider;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (object));
+
+    equalizer_slider = UI_SKINNED_EQUALIZER_SLIDER (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_equalizer_slider_realize(GtkWidget *widget) {
+    UiSkinnedEqualizerSlider *equalizer_slider;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    equalizer_slider = UI_SKINNED_EQUALIZER_SLIDER(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+                             GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_equalizer_slider_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
+
+    requisition->width = priv->width*(priv->scaled ? cfg.scale_factor : 1);
+    requisition->height = priv->height*(priv->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_equalizer_slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedEqualizerSlider *equalizer_slider = UI_SKINNED_EQUALIZER_SLIDER (widget);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(equalizer_slider);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (priv->scaled ? cfg.scale_factor : 1);
+    widget->allocation.y *= (priv->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    equalizer_slider->x = widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1);
+    equalizer_slider->y = widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1);
+}
+
+static gboolean ui_skinned_equalizer_slider_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedEqualizerSlider *es = UI_SKINNED_EQUALIZER_SLIDER (widget);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(es);
+    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->width, priv->height);
+
+    gint frame;
+    frame = 27 - ((priv->position * 27) / 50);
+    if (frame < 14)
+        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, (frame * 15) + 13, 164, 0, 0, priv->width, priv->height);
+    else
+        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, ((frame - 14) * 15) + 13, 229, 0, 0, priv->width, priv->height);
+
+    if (priv->pressed)
+        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, 0, 176, 1, priv->position, 11, 11);
+    else
+        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, 0, 164, 1, priv->position, 11, 11);
+
+    ui_skinned_widget_draw(widget, obj, priv->width, priv->height, priv->scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static gboolean ui_skinned_equalizer_slider_button_press(GtkWidget *widget, GdkEventButton *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedEqualizerSlider *es = UI_SKINNED_EQUALIZER_SLIDER (widget);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(es);
+
+    gint y;
+
+    if (event->type == GDK_BUTTON_PRESS) {
+        if (event->button == 1) {
+            priv->pressed = TRUE;
+            y = event->y/(priv->scaled ? cfg.scale_factor : 1);
+
+            if (y >= priv->position && y < priv->position + 11)
+                priv->drag_y = y - priv->position;
+            else {
+                priv->position = y - 5;
+                priv->drag_y = 5;
+                if (priv->position < 0)
+                    priv->position = 0;
+                if (priv->position > 50)
+                    priv->position = 50;
+                if (priv->position >= 24 && priv->position <= 26)
+                    priv->position = 25;
+                
+                priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 );
+                equalizerwin_eq_changed();
+            }
+
+            ui_skinned_equalizer_slider_set_mainwin_text(es);
+            gtk_widget_queue_draw(widget);
+        }
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_equalizer_slider_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
+
+    if (event->button == 1) {
+        priv->pressed = FALSE;
+        mainwin_release_info_text();
+        gtk_widget_queue_draw(widget);
+    }
+    return TRUE;
+}
+
+static gboolean ui_skinned_equalizer_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+    UiSkinnedEqualizerSlider *es = UI_SKINNED_EQUALIZER_SLIDER(widget);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
+
+    if (priv->pressed) {
+        gint y;
+
+        y = event->y/(priv->scaled ? cfg.scale_factor : 1);
+        priv->position = y - priv->drag_y;
+
+        if (priv->position < 0)
+            priv->position = 0;
+        if (priv->position > 50)
+            priv->position = 50;
+        if (priv->position >= 24 && priv->position <= 26)
+            priv->position = 25;
+        
+        priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 );
+        ui_skinned_equalizer_slider_set_mainwin_text(es);
+        equalizerwin_eq_changed();
+        gtk_widget_queue_draw(widget);
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_equalizer_slider_scroll(GtkWidget *widget, GdkEventScroll *event) {
+    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
+
+    if (event->direction == GDK_SCROLL_UP) {
+        priv->position -= 2;
+
+        if (priv->position < 0)
+            priv->position = 0;
+    }
+    else {
+        priv->position += 2;
+
+        if (priv->position > 50)
+            priv->position = 50;
+    }
+
+    priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 );
+    equalizerwin_eq_changed();
+    gtk_widget_queue_draw(widget);
+    return TRUE;
+}
+
+static void ui_skinned_equalizer_slider_toggle_scaled(UiSkinnedEqualizerSlider *equalizer_slider) {
+    GtkWidget *widget = GTK_WIDGET (equalizer_slider);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(equalizer_slider);
+
+    priv->scaled = !priv->scaled;
+
+    gtk_widget_set_size_request(widget, priv->width*(priv->scaled ? cfg.scale_factor : 1),
+    priv->height*(priv->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(GTK_WIDGET(equalizer_slider));
+}
+
+void ui_skinned_equalizer_slider_set_position(GtkWidget *widget, gfloat pos) {
+    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget));
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
+
+    if (priv->pressed)
+        return;
+
+    priv->value = (pos > EQUALIZER_MAX_GAIN) ? EQUALIZER_MAX_GAIN : ((pos < -EQUALIZER_MAX_GAIN) ? -EQUALIZER_MAX_GAIN : pos);
+    priv->position = 25 - (gint) ((pos * 25.0) / EQUALIZER_MAX_GAIN);
+
+    if (priv->position < 0)
+        priv->position = 0;
+
+    if (priv->position > 50)
+        priv->position = 50;
+
+    if (priv->position >= 24 && priv->position <= 26)
+        priv->position = 25;
+
+    gtk_widget_queue_draw(widget);
+}
+
+gfloat ui_skinned_equalizer_slider_get_position(GtkWidget *widget) {
+    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), -1);
+    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
+    return priv->value;
+}
+
+void ui_skinned_equalizer_slider_set_mainwin_text(UiSkinnedEqualizerSlider * es) {
+    gint band = 0;
+    const gchar *bandname[11] = { N_("PREAMP"), N_("60HZ"), N_("170HZ"),
+        N_("310HZ"), N_("600HZ"), N_("1KHZ"),
+        N_("3KHZ"), N_("6KHZ"), N_("12KHZ"),
+        N_("14KHZ"), N_("16KHZ")
+    };
+    gchar *tmp;
+
+    if (es->x > 21)
+        band = ((es->x - 78) / 18) + 1;
+
+    tmp =
+        g_strdup_printf("EQ: %s: %+.1f DB", _(bandname[band]),
+                        ui_skinned_equalizer_slider_get_position(GTK_WIDGET(es)));
+    mainwin_lock_info_text(tmp);
+    g_free(tmp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_equalizer_slider.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,60 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_EQUALIZER_SLIDER_H
+#define AUDACIOUS_UI_SKINNED_EQUALIZER_SLIDER_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_EQUALIZER_SLIDER(obj)          GTK_CHECK_CAST (obj, ui_skinned_equalizer_slider_get_type (), UiSkinnedEqualizerSlider)
+#define UI_SKINNED_EQUALIZER_SLIDER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_equalizer_slider_get_type (),  UiSkinnedEqualizerSliderClass)
+#define UI_SKINNED_IS_EQUALIZER_SLIDER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_equalizer_slider_get_type ())
+
+typedef struct _UiSkinnedEqualizerSlider        UiSkinnedEqualizerSlider;
+typedef struct _UiSkinnedEqualizerSliderClass   UiSkinnedEqualizerSliderClass;
+
+struct _UiSkinnedEqualizerSlider {
+    GtkWidget   widget;
+    gint        x, y;
+};
+
+struct _UiSkinnedEqualizerSliderClass {
+    GtkWidgetClass    parent_class;
+    void (* scaled)  (UiSkinnedEqualizerSlider *equalizer_slider);
+};
+
+GtkWidget* ui_skinned_equalizer_slider_new(GtkWidget *fixed, gint x, gint y);
+GtkType ui_skinned_equalizer_slider_get_type(void);
+void ui_skinned_equalizer_slider_set_position(GtkWidget *widget, gfloat pos);
+gfloat ui_skinned_equalizer_slider_get_position(GtkWidget *widget);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_EQUALIZER_SLIDER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_horizontal_slider.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,386 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skinned_horizontal_slider.h"
+#include "main.h"
+#include <math.h>
+
+#define UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_horizontal_slider_get_type(), UiSkinnedHorizontalSliderPrivate))
+typedef struct _UiSkinnedHorizontalSliderPrivate UiSkinnedHorizontalSliderPrivate;
+
+enum {
+    MOTION,
+    RELEASE,
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+struct _UiSkinnedHorizontalSliderPrivate {
+    SkinPixmapId     skin_index;
+    gboolean         scaled;
+    gint             frame, frame_offset, frame_height, min, max;
+    gint             knob_width, knob_height;
+    gint             position;
+    gint             width, height;
+    gint             (*frame_cb) (gint);
+};
+
+static void ui_skinned_horizontal_slider_class_init         (UiSkinnedHorizontalSliderClass *klass);
+static void ui_skinned_horizontal_slider_init               (UiSkinnedHorizontalSlider *horizontal_slider);
+static void ui_skinned_horizontal_slider_destroy            (GtkObject *object);
+static void ui_skinned_horizontal_slider_realize            (GtkWidget *widget);
+static void ui_skinned_horizontal_slider_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_horizontal_slider_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_horizontal_slider_expose         (GtkWidget *widget, GdkEventExpose *event);
+static gboolean ui_skinned_horizontal_slider_button_press   (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_horizontal_slider_button_release (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_horizontal_slider_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
+static void ui_skinned_horizontal_slider_toggle_scaled  (UiSkinnedHorizontalSlider *horizontal_slider);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint horizontal_slider_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_horizontal_slider_get_type() {
+    static GType horizontal_slider_type = 0;
+    if (!horizontal_slider_type) {
+        static const GTypeInfo horizontal_slider_info = {
+            sizeof (UiSkinnedHorizontalSliderClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_horizontal_slider_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedHorizontalSlider),
+            0,
+            (GInstanceInitFunc) ui_skinned_horizontal_slider_init,
+        };
+        horizontal_slider_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedHorizontalSlider_", &horizontal_slider_info, 0);
+    }
+
+    return horizontal_slider_type;
+}
+
+static void ui_skinned_horizontal_slider_class_init(UiSkinnedHorizontalSliderClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_horizontal_slider_destroy;
+
+    widget_class->realize = ui_skinned_horizontal_slider_realize;
+    widget_class->expose_event = ui_skinned_horizontal_slider_expose;
+    widget_class->size_request = ui_skinned_horizontal_slider_size_request;
+    widget_class->size_allocate = ui_skinned_horizontal_slider_size_allocate;
+    widget_class->button_press_event = ui_skinned_horizontal_slider_button_press;
+    widget_class->button_release_event = ui_skinned_horizontal_slider_button_release;
+    widget_class->motion_notify_event = ui_skinned_horizontal_slider_motion_notify;
+
+    klass->motion = NULL;
+    klass->release = NULL;
+    klass->scaled = ui_skinned_horizontal_slider_toggle_scaled;
+
+    horizontal_slider_signals[MOTION] = 
+        g_signal_new ("motion", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedHorizontalSliderClass, motion), NULL, NULL,
+                      gtk_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+    horizontal_slider_signals[RELEASE] = 
+        g_signal_new ("release", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedHorizontalSliderClass, release), NULL, NULL,
+                      gtk_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+    horizontal_slider_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedHorizontalSliderClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    g_type_class_add_private (gobject_class, sizeof (UiSkinnedHorizontalSliderPrivate));
+}
+
+static void ui_skinned_horizontal_slider_init(UiSkinnedHorizontalSlider *horizontal_slider) {
+    horizontal_slider->pressed = FALSE;
+}
+
+GtkWidget* ui_skinned_horizontal_slider_new(GtkWidget *fixed, gint x, gint y, gint w, gint h, gint knx, gint kny,
+                                            gint kpx, gint kpy, gint kw, gint kh, gint fh,
+                                            gint fo, gint min, gint max, gint(*fcb) (gint), SkinPixmapId si) {
+
+    UiSkinnedHorizontalSlider *hs = g_object_new (ui_skinned_horizontal_slider_get_type (), NULL);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(hs);
+
+    hs->x = x;
+    hs->y = y;
+    priv->width = w;
+    priv->height = h;
+    hs->knob_nx = knx;
+    hs->knob_ny = kny;
+    hs->knob_px = kpx;
+    hs->knob_py = kpy;
+    priv->knob_width = kw;
+    priv->knob_height = kh;
+    priv->frame_height = fh;
+    priv->frame_offset = fo;
+    priv->min = min;
+    priv->position = min;
+    priv->max = max;
+    priv->frame_cb = fcb;
+    if (priv->frame_cb)
+        priv->frame = priv->frame_cb(0);
+    priv->skin_index = si;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y);
+
+    return GTK_WIDGET(hs);
+}
+
+static void ui_skinned_horizontal_slider_destroy(GtkObject *object) {
+    UiSkinnedHorizontalSlider *horizontal_slider;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (object));
+
+    horizontal_slider = UI_SKINNED_HORIZONTAL_SLIDER (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_horizontal_slider_realize(GtkWidget *widget) {
+    UiSkinnedHorizontalSlider *horizontal_slider;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    horizontal_slider = UI_SKINNED_HORIZONTAL_SLIDER(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_horizontal_slider_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
+
+    requisition->width = priv->width*(priv->scaled ? cfg.scale_factor : 1);
+    requisition->height = priv->height*(priv->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_horizontal_slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedHorizontalSlider *horizontal_slider = UI_SKINNED_HORIZONTAL_SLIDER (widget);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(horizontal_slider);
+
+    widget->allocation = *allocation;
+    widget->allocation.x = ceil(widget->allocation.x*(priv->scaled ? cfg.scale_factor : 1));
+    widget->allocation.y = ceil(widget->allocation.y*(priv->scaled ? cfg.scale_factor : 1));
+
+    if (priv->knob_height == priv->height)
+        priv->knob_height = ceil(allocation->height/(priv->scaled ? cfg.scale_factor : 1));
+    priv->width = ceil(allocation->width/(priv->scaled ? cfg.scale_factor : 1));
+    priv->height = ceil(allocation->height/(priv->scaled ? cfg.scale_factor : 1));
+
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    horizontal_slider->x = ceil(widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1));
+    horizontal_slider->y = ceil(widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1));
+}
+
+static gboolean ui_skinned_horizontal_slider_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER (widget);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(hs);
+    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+
+    if (priv->position > priv->max) priv->position = priv->max;
+    else if (priv->position < priv->min) priv->position = priv->min;
+
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->width, priv->height);
+
+    skin_draw_pixbuf(widget, aud_active_skin, obj,
+                     priv->skin_index, priv->frame_offset,
+                     priv->frame * priv->frame_height,
+                     0, 0, priv->width, priv->height);
+    if (hs->pressed)
+        skin_draw_pixbuf(widget, aud_active_skin, obj,
+                         priv->skin_index, hs->knob_px,
+                         hs->knob_py, priv->position,
+                         ((priv->height - priv->knob_height) / 2),
+                         priv->knob_width, priv->knob_height);
+    else
+        skin_draw_pixbuf(widget, aud_active_skin, obj,
+                         priv->skin_index, hs->knob_nx,
+                         hs->knob_ny, priv->position,
+                         ((priv->height - priv->knob_height) / 2),
+                         priv->knob_width, priv->knob_height);
+
+    ui_skinned_widget_draw(widget, obj, priv->width, priv->height, priv->scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static gboolean ui_skinned_horizontal_slider_button_press(GtkWidget *widget, GdkEventButton *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER (widget);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(hs);
+
+    if (event->type == GDK_BUTTON_PRESS) {
+        if (event->button == 1) {
+            gint x;
+
+            x = event->x - (priv->knob_width / (priv->scaled ? 1 : cfg.scale_factor));
+            hs->pressed = TRUE;
+
+            priv->position = x/(priv->scaled ? cfg.scale_factor : 1);
+            if (priv->position < priv->min)
+                priv->position = priv->min;
+            if (priv->position > priv->max)
+                priv->position = priv->max;
+            if (priv->frame_cb)
+                priv->frame = priv->frame_cb(priv->position);
+
+            g_signal_emit_by_name(widget, "motion", priv->position);
+            gtk_widget_queue_draw(widget);
+        } else if (event->button == 3) {
+            if (hs->pressed) {
+                hs->pressed = FALSE;
+                g_signal_emit_by_name(widget, "release", priv->position);
+                gtk_widget_queue_draw(widget);
+            }
+            event->x = event->x + hs->x;
+            event->y = event->y + hs->y;
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+static gboolean ui_skinned_horizontal_slider_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER(widget);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
+
+    if (hs->pressed) {
+        hs->pressed = FALSE;
+        g_signal_emit_by_name(widget, "release", priv->position);
+        gtk_widget_queue_draw(widget);
+    }
+    return TRUE;
+}
+
+static gboolean ui_skinned_horizontal_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER(widget);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
+
+    if (hs->pressed) {
+        gint x;
+
+        x = event->x - (priv->knob_width / (priv->scaled ? 1 : cfg.scale_factor));
+        priv->position = x/(priv->scaled ? cfg.scale_factor : 1);
+
+        if (priv->position < priv->min)
+            priv->position = priv->min;
+
+        if (priv->position > priv->max)
+            priv->position = priv->max;
+
+        if (priv->frame_cb)
+            priv->frame = priv->frame_cb(priv->position);
+
+        g_signal_emit_by_name(widget, "motion", priv->position);
+        gtk_widget_queue_draw(widget);
+    }
+
+    return TRUE;
+}
+
+static void ui_skinned_horizontal_slider_toggle_scaled(UiSkinnedHorizontalSlider *horizontal_slider) {
+    GtkWidget *widget = GTK_WIDGET (horizontal_slider);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(horizontal_slider);
+
+    priv->scaled = !priv->scaled;
+
+    gtk_widget_set_size_request(widget,
+        priv->width*(priv->scaled ? cfg.scale_factor : 1),
+        priv->height*(priv->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(GTK_WIDGET(horizontal_slider));
+}
+
+void ui_skinned_horizontal_slider_set_position(GtkWidget *widget, gint pos) {
+    g_return_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget));
+    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER(widget);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
+
+    if (pos == priv->position || hs->pressed)
+        return;
+
+    priv->position = pos;
+
+    if (priv->frame_cb)
+        priv->frame = priv->frame_cb(priv->position);
+
+    gtk_widget_queue_draw(widget);
+}
+
+gint ui_skinned_horizontal_slider_get_position(GtkWidget *widget) {
+    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), -1);
+    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
+    return priv->position;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_horizontal_slider.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,69 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_HORIZONTAL_SLIDER_H
+#define AUDACIOUS_UI_SKINNED_HORIZONTAL_SLIDER_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_HORIZONTAL_SLIDER(obj)          GTK_CHECK_CAST (obj, ui_skinned_horizontal_slider_get_type (), UiSkinnedHorizontalSlider)
+#define UI_SKINNED_HORIZONTAL_SLIDER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_horizontal_slider_get_type (), UiSkinnedHorizontalSliderClass)
+#define UI_SKINNED_IS_HORIZONTAL_SLIDER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_horizontal_slider_get_type ())
+
+typedef struct _UiSkinnedHorizontalSlider        UiSkinnedHorizontalSlider;
+typedef struct _UiSkinnedHorizontalSliderClass   UiSkinnedHorizontalSliderClass;
+
+struct _UiSkinnedHorizontalSlider {
+    GtkWidget   widget;
+    gboolean    pressed;
+    gint        x, y;
+    gint        knob_nx, knob_ny, knob_px, knob_py;
+};
+
+struct _UiSkinnedHorizontalSliderClass {
+    GtkWidgetClass    parent_class;
+    void (* motion)   (UiSkinnedHorizontalSlider *horizontal_slider);
+    void (* release)  (UiSkinnedHorizontalSlider *horizontal_slider);
+    void (* scaled)  (UiSkinnedHorizontalSlider *horizontal_slider);
+    void (* redraw)   (UiSkinnedHorizontalSlider *horizontal_slider);
+};
+GtkWidget* ui_skinned_horizontal_slider_new(GtkWidget *fixed, gint x, gint y, gint w, gint h, gint knx, gint kny,
+                                            gint kpx, gint kpy, gint kw, gint kh, gint fh,
+                                            gint fo, gint min, gint max, gint(*fcb) (gint), SkinPixmapId si);
+GtkType ui_skinned_horizontal_slider_get_type(void);
+void ui_skinned_horizontal_slider_set_position(GtkWidget *widget, gint pos);
+gint ui_skinned_horizontal_slider_get_position(GtkWidget *widget);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_HORIZONTAL_SLIDER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_menurow.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,331 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skinned_menurow.h"
+#include "main.h"
+
+enum {
+    DOUBLED,
+    CHANGE,
+    RELEASE,
+    LAST_SIGNAL
+};
+
+static void ui_skinned_menurow_class_init         (UiSkinnedMenurowClass *klass);
+static void ui_skinned_menurow_init               (UiSkinnedMenurow *menurow);
+static void ui_skinned_menurow_destroy            (GtkObject *object);
+static void ui_skinned_menurow_realize            (GtkWidget *widget);
+static void ui_skinned_menurow_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_menurow_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_menurow_expose         (GtkWidget *widget, GdkEventExpose *event);
+static MenuRowItem menurow_find_selected          (UiSkinnedMenurow * mr, gint x, gint y);
+static gboolean ui_skinned_menurow_button_press   (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_menurow_button_release (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_menurow_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
+static void ui_skinned_menurow_toggle_scaled  (UiSkinnedMenurow *menurow);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint menurow_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_menurow_get_type() {
+    static GType menurow_type = 0;
+    if (!menurow_type) {
+        static const GTypeInfo menurow_info = {
+            sizeof (UiSkinnedMenurowClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_menurow_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedMenurow),
+            0,
+            (GInstanceInitFunc) ui_skinned_menurow_init,
+        };
+        menurow_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedMenurow_", &menurow_info, 0);
+    }
+
+    return menurow_type;
+}
+
+static void ui_skinned_menurow_class_init(UiSkinnedMenurowClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_menurow_destroy;
+
+    widget_class->realize = ui_skinned_menurow_realize;
+    widget_class->expose_event = ui_skinned_menurow_expose;
+    widget_class->size_request = ui_skinned_menurow_size_request;
+    widget_class->size_allocate = ui_skinned_menurow_size_allocate;
+    widget_class->button_press_event = ui_skinned_menurow_button_press;
+    widget_class->button_release_event = ui_skinned_menurow_button_release;
+    widget_class->motion_notify_event = ui_skinned_menurow_motion_notify;
+
+    klass->scaled = ui_skinned_menurow_toggle_scaled;
+    klass->change = NULL;
+    klass->release = NULL;
+
+    menurow_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedMenurowClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+
+    menurow_signals[CHANGE] = 
+        g_signal_new ("change", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedMenurowClass, change), NULL, NULL,
+                      gtk_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+    menurow_signals[RELEASE] = 
+        g_signal_new ("release", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedMenurowClass, release), NULL, NULL,
+                      g_cclosure_marshal_VOID__UINT_POINTER, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
+
+}
+
+static void ui_skinned_menurow_init(UiSkinnedMenurow *menurow) {
+    menurow->scale_selected = cfg.scaled;
+    menurow->always_selected = cfg.always_on_top;
+}
+
+GtkWidget* ui_skinned_menurow_new(GtkWidget *fixed, gint x, gint y, gint nx, gint ny, gint sx, gint sy, SkinPixmapId si) {
+    UiSkinnedMenurow *menurow = g_object_new (ui_skinned_menurow_get_type (), NULL);
+
+    menurow->x = x;
+    menurow->y = y;
+    menurow->width = 8;
+    menurow->height = 43;
+    menurow->nx = nx;
+    menurow->ny = ny;
+    menurow->sx = sx;
+    menurow->sy = sy;
+    menurow->selected = MENUROW_NONE;
+
+    menurow->skin_index = si;
+
+    menurow->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(menurow), menurow->x, menurow->y);
+
+    return GTK_WIDGET(menurow);
+}
+
+static void ui_skinned_menurow_destroy(GtkObject *object) {
+    UiSkinnedMenurow *menurow;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_MENUROW (object));
+
+    menurow = UI_SKINNED_MENUROW (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_menurow_realize(GtkWidget *widget) {
+    UiSkinnedMenurow *menurow;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_MENUROW(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    menurow = UI_SKINNED_MENUROW(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_menurow_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW(widget);
+
+    requisition->width = menurow->width*(menurow->scaled ? cfg.scale_factor : 1);
+    requisition->height = menurow->height*(menurow->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_menurow_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW (widget);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (menurow->scaled ? cfg.scale_factor : 1);
+    widget->allocation.y *= (menurow->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    menurow->x = widget->allocation.x/(menurow->scaled ? cfg.scale_factor : 1);
+    menurow->y = widget->allocation.y/(menurow->scaled ? cfg.scale_factor : 1);
+}
+
+static gboolean ui_skinned_menurow_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_MENUROW (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW (widget);
+    g_return_val_if_fail (menurow->width > 0 && menurow->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, menurow->width, menurow->height);
+
+    if (menurow->selected == MENUROW_NONE) {
+        if (cfg.always_show_cb || menurow->pushed)
+            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
+                             menurow->nx, menurow->ny, 0, 0, 8, 43);
+        else
+            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
+                             menurow->nx + 8, menurow->ny, 0, 0, 8, 43);
+    }
+    else {
+        skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
+                         menurow->sx + ((menurow->selected - 1) * 8),
+                         menurow->sy, 0, 0, 8, 43);
+    }
+    if (cfg.always_show_cb || menurow->pushed) {
+        if (menurow->always_selected)
+            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
+                             menurow->sx + 8, menurow->sy + 10, 0, 10, 8, 8);
+        if (menurow->scale_selected)
+            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
+                             menurow->sx + 24, menurow->sy + 26, 0, 26, 8, 8);
+    }
+
+    ui_skinned_widget_draw(widget, obj, menurow->width, menurow->height, menurow->scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static MenuRowItem menurow_find_selected(UiSkinnedMenurow * mr, gint x, gint y) {
+    MenuRowItem ret = MENUROW_NONE;
+
+    x = x/(mr->scaled ? cfg.scale_factor : 1);
+    y = y/(mr->scaled ? cfg.scale_factor : 1);
+    if (x > 0 && x < 8) {
+        if (y >= 0 && y <= 10)
+            ret = MENUROW_OPTIONS;
+        if (y >= 10 && y <= 17)
+            ret = MENUROW_ALWAYS;
+        if (y >= 18 && y <= 25)
+            ret = MENUROW_FILEINFOBOX;
+        if (y >= 26 && y <= 33)
+            ret = MENUROW_SCALE;
+        if (y >= 34 && y <= 42)
+            ret = MENUROW_VISUALIZATION;
+    }
+    return ret;
+}
+
+static gboolean ui_skinned_menurow_button_press(GtkWidget *widget, GdkEventButton *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_MENUROW (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW (widget);
+
+    if (event->type == GDK_BUTTON_PRESS) {
+        if (event->button == 1) {
+
+        menurow->pushed = TRUE;
+        menurow->selected = menurow_find_selected(menurow, event->x, event->y);
+
+        gtk_widget_queue_draw(widget);
+        g_signal_emit_by_name(widget, "change", menurow->selected);
+        }
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_menurow_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW(widget);
+    if (menurow->pushed) {
+        menurow->pushed = FALSE;
+
+        if (menurow->selected == MENUROW_ALWAYS)
+            menurow->always_selected = !menurow->always_selected;
+
+        if (menurow->selected == MENUROW_SCALE)
+            menurow->scale_selected = !menurow->scale_selected;
+
+        if ((int)(menurow->selected) != -1)
+            g_signal_emit_by_name(widget, "release", menurow->selected, event);
+
+        menurow->selected = MENUROW_NONE;
+        gtk_widget_queue_draw(widget);
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_menurow_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_MENUROW (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW(widget);
+
+    if (menurow->pushed) {
+        menurow->selected = menurow_find_selected(menurow, event->x, event->y);
+
+        gtk_widget_queue_draw(widget);
+        g_signal_emit_by_name(widget, "change", menurow->selected);
+    }
+
+    return TRUE;
+}
+
+static void ui_skinned_menurow_toggle_scaled(UiSkinnedMenurow *menurow) {
+    GtkWidget *widget = GTK_WIDGET (menurow);
+
+    menurow->scaled = !menurow->scaled;
+    gtk_widget_set_size_request(widget, menurow->width* (menurow->scaled ? cfg.scale_factor : 1),
+    menurow->height * (menurow->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(GTK_WIDGET(menurow));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_menurow.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,77 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_MENUROW_H
+#define AUDACIOUS_UI_SKINNED_MENUROW_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_MENUROW(obj)          GTK_CHECK_CAST (obj, ui_skinned_menurow_get_type (), UiSkinnedMenurow)
+#define UI_SKINNED_MENUROW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_menurow_get_type (), UiSkinnedMenurowClass)
+#define UI_SKINNED_IS_MENUROW(obj)       GTK_CHECK_TYPE (obj, ui_skinned_menurow_get_type ())
+
+typedef struct _UiSkinnedMenurow        UiSkinnedMenurow;
+typedef struct _UiSkinnedMenurowClass   UiSkinnedMenurowClass;
+
+typedef enum {
+    MENUROW_NONE, MENUROW_OPTIONS, MENUROW_ALWAYS, MENUROW_FILEINFOBOX,
+    MENUROW_SCALE, MENUROW_VISUALIZATION
+} MenuRowItem;
+
+struct _UiSkinnedMenurow {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gboolean         scaled;
+    gint             nx, ny;
+    gint             sx, sy;
+    MenuRowItem      selected;
+    gboolean         always_selected;
+    gboolean         scale_selected;
+    gboolean         pushed;
+    SkinPixmapId     skin_index;
+};
+
+struct _UiSkinnedMenurowClass {
+    GtkWidgetClass          parent_class;
+    void (* scaled)        (UiSkinnedMenurow *menurow);
+    void (* change)         (UiSkinnedMenurow *menurow);
+    void (* release)        (UiSkinnedMenurow *menurow);
+};
+
+GtkWidget* ui_skinned_menurow_new (GtkWidget *fixed, gint x, gint y, gint nx, gint ny, gint sx, gint sy, SkinPixmapId si);
+GtkType ui_skinned_menurow_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_MENUROW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_monostereo.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,222 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skin.h"
+#include "ui_skinned_monostereo.h"
+#include "main.h"
+
+enum {
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+static void ui_skinned_monostereo_class_init         (UiSkinnedMonoStereoClass *klass);
+static void ui_skinned_monostereo_init               (UiSkinnedMonoStereo *monostereo);
+static void ui_skinned_monostereo_destroy            (GtkObject *object);
+static void ui_skinned_monostereo_realize            (GtkWidget *widget);
+static void ui_skinned_monostereo_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_monostereo_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_monostereo_expose         (GtkWidget *widget, GdkEventExpose *event);
+static void ui_skinned_monostereo_toggle_scaled      (UiSkinnedMonoStereo *monostereo);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint monostereo_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_monostereo_get_type() {
+    static GType monostereo_type = 0;
+    if (!monostereo_type) {
+        static const GTypeInfo monostereo_info = {
+            sizeof (UiSkinnedMonoStereoClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_monostereo_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedMonoStereo),
+            0,
+            (GInstanceInitFunc) ui_skinned_monostereo_init,
+        };
+        monostereo_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedMonoStereo_", &monostereo_info, 0);
+    }
+
+    return monostereo_type;
+}
+
+static void ui_skinned_monostereo_class_init(UiSkinnedMonoStereoClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_monostereo_destroy;
+
+    widget_class->realize = ui_skinned_monostereo_realize;
+    widget_class->expose_event = ui_skinned_monostereo_expose;
+    widget_class->size_request = ui_skinned_monostereo_size_request;
+    widget_class->size_allocate = ui_skinned_monostereo_size_allocate;
+
+    klass->scaled = ui_skinned_monostereo_toggle_scaled;
+
+    monostereo_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedMonoStereoClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+static void ui_skinned_monostereo_init(UiSkinnedMonoStereo *monostereo) {
+    monostereo->width = 56;
+    monostereo->height = 12;
+}
+
+GtkWidget* ui_skinned_monostereo_new(GtkWidget *fixed, gint x, gint y, SkinPixmapId si) {
+    UiSkinnedMonoStereo *monostereo = g_object_new (ui_skinned_monostereo_get_type (), NULL);
+
+    monostereo->x = x;
+    monostereo->y = y;
+    monostereo->skin_index = si;
+    monostereo->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(monostereo), monostereo->x, monostereo->y);
+
+    return GTK_WIDGET(monostereo);
+}
+
+static void ui_skinned_monostereo_destroy(GtkObject *object) {
+    UiSkinnedMonoStereo *monostereo;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_MONOSTEREO (object));
+
+    monostereo = UI_SKINNED_MONOSTEREO (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_monostereo_realize(GtkWidget *widget) {
+    UiSkinnedMonoStereo *monostereo;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_MONOSTEREO(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    monostereo = UI_SKINNED_MONOSTEREO(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_monostereo_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO(widget);
+
+    requisition->width = monostereo->width*(monostereo->scaled ? cfg.scale_factor : 1);
+    requisition->height = monostereo->height*(monostereo->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_monostereo_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO (widget);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (monostereo->scaled ? cfg.scale_factor : 1);
+    widget->allocation.y *= (monostereo->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    monostereo->x = widget->allocation.x/(monostereo->scaled ? cfg.scale_factor : 1);
+    monostereo->y = widget->allocation.y/(monostereo->scaled ? cfg.scale_factor : 1);
+}
+
+static gboolean ui_skinned_monostereo_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_MONOSTEREO (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO (widget);
+    g_return_val_if_fail (monostereo->width > 0 && monostereo->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, monostereo->width, monostereo->height);
+
+    switch (monostereo->num_channels) {
+    case 1:
+        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 29, 0, 0, 0, 27, 12);
+        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 0, 12, 27, 0, 29, 12);
+        break;
+    case 2:
+        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 29, 12, 0, 0, 27, 12);
+        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 0, 0, 27, 0, 29, 12);
+        break;
+    default:
+    case 0:
+        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 29, 12, 0, 0, 27, 12);
+        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 0, 12, 27, 0, 29, 12);
+        break;
+    }
+
+    ui_skinned_widget_draw(widget, obj, monostereo->width, monostereo->height, monostereo->scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static void ui_skinned_monostereo_toggle_scaled(UiSkinnedMonoStereo *monostereo) {
+    GtkWidget *widget = GTK_WIDGET (monostereo);
+
+    monostereo->scaled = !monostereo->scaled;
+    gtk_widget_set_size_request(widget, monostereo->width*(monostereo->scaled ? cfg.scale_factor : 1), monostereo->height*(monostereo->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(GTK_WIDGET(monostereo));
+}
+
+void ui_skinned_monostereo_set_num_channels(GtkWidget *widget, gint nch) {
+    g_return_if_fail (UI_SKINNED_IS_MONOSTEREO (widget));
+    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO (widget);
+
+    monostereo->num_channels = nch;
+    gtk_widget_queue_draw(widget);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_monostereo.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,66 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_MONOSTEREO_H
+#define AUDACIOUS_UI_SKINNED_MONOSTEREO_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_MONOSTEREO(obj)          GTK_CHECK_CAST (obj, ui_skinned_monostereo_get_type (), UiSkinnedMonoStereo)
+#define UI_SKINNED_MONOSTEREO_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_monostereo_get_type (), UiSkinnedMonoStereoClass)
+#define UI_SKINNED_IS_MONOSTEREO(obj)       GTK_CHECK_TYPE (obj, ui_skinned_monostereo_get_type ())
+
+typedef struct _UiSkinnedMonoStereo        UiSkinnedMonoStereo;
+typedef struct _UiSkinnedMonoStereoClass   UiSkinnedMonoStereoClass;
+
+struct _UiSkinnedMonoStereo {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gint             num_channels;
+    SkinPixmapId     skin_index;
+    gboolean         scaled;
+};
+
+struct _UiSkinnedMonoStereoClass {
+    GtkWidgetClass          parent_class;
+    void (* scaled)        (UiSkinnedMonoStereo *menurow);
+};
+
+GtkWidget* ui_skinned_monostereo_new (GtkWidget *fixed, gint x, gint y, SkinPixmapId si);
+GtkType ui_skinned_monostereo_get_type(void);
+void ui_skinned_monostereo_set_num_channels(GtkWidget *widget, gint nch);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_MONOSTEREO_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_number.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,234 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skinned_number.h"
+#include "main.h"
+#include "strings.h"
+#include <string.h>
+#include <ctype.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmarshal.h>
+
+#define UI_TYPE_SKINNED_NUMBER           (ui_skinned_number_get_type())
+
+enum {
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+static void ui_skinned_number_class_init         (UiSkinnedNumberClass *klass);
+static void ui_skinned_number_init               (UiSkinnedNumber *number);
+static void ui_skinned_number_destroy            (GtkObject *object);
+static void ui_skinned_number_realize            (GtkWidget *widget);
+static void ui_skinned_number_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_number_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_number_expose         (GtkWidget *widget, GdkEventExpose *event);
+static void ui_skinned_number_toggle_scaled  (UiSkinnedNumber *number);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint number_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_number_get_type() {
+    static GType number_type = 0;
+    if (!number_type) {
+        static const GTypeInfo number_info = {
+            sizeof (UiSkinnedNumberClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_number_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedNumber),
+            0,
+            (GInstanceInitFunc) ui_skinned_number_init,
+        };
+        number_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedNumber_", &number_info, 0);
+    }
+
+    return number_type;
+}
+
+static void ui_skinned_number_class_init(UiSkinnedNumberClass *klass) {
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_number_destroy;
+
+    widget_class->realize = ui_skinned_number_realize;
+    widget_class->expose_event = ui_skinned_number_expose;
+    widget_class->size_request = ui_skinned_number_size_request;
+    widget_class->size_allocate = ui_skinned_number_size_allocate;
+
+    klass->scaled = ui_skinned_number_toggle_scaled;
+
+    number_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedNumberClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+static void ui_skinned_number_init(UiSkinnedNumber *number) {
+    number->width = 9;
+    number->height = 13;
+}
+
+GtkWidget* ui_skinned_number_new(GtkWidget *fixed, gint x, gint y, SkinPixmapId si) {
+    UiSkinnedNumber *number = g_object_new (ui_skinned_number_get_type (), NULL);
+
+    number->x = x;
+    number->y = y;
+    number->num = 0;
+    number->skin_index = si;
+
+    number->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(number), number->x, number->y);
+
+    return GTK_WIDGET(number);
+}
+
+static void ui_skinned_number_destroy(GtkObject *object) {
+    UiSkinnedNumber *number;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_NUMBER (object));
+
+    number = UI_SKINNED_NUMBER (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_number_realize(GtkWidget *widget) {
+    UiSkinnedNumber *number;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_NUMBER(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    number = UI_SKINNED_NUMBER(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_number_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedNumber *number = UI_SKINNED_NUMBER(widget);
+
+    requisition->width = number->width * ( number->scaled ? cfg.scale_factor : 1 );
+    requisition->height = number->height*( number->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_number_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (number->scaled ? cfg.scale_factor: 1 );
+    widget->allocation.y *= (number->scaled ? cfg.scale_factor: 1 );
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    number->x = widget->allocation.x/(number->scaled ? cfg.scale_factor : 1);
+    number->y = widget->allocation.y/(number->scaled ? cfg.scale_factor : 1);
+}
+
+static gboolean ui_skinned_number_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_NUMBER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
+    g_return_val_if_fail (number->width > 0 && number->height > 0, FALSE);
+
+    GdkPixbuf *obj;
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, number->width, number->height);
+
+    if (number->num > 11 || number->num < 0)
+        number->num = 10;
+
+    skin_draw_pixbuf(widget, aud_active_skin, obj,
+                     number->skin_index, number->num * 9, 0,
+                     0, 0, number->width, number->height);
+
+    ui_skinned_widget_draw(widget, obj, number->width, number->height, number->scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static void ui_skinned_number_toggle_scaled(UiSkinnedNumber *number) {
+    GtkWidget *widget = GTK_WIDGET (number);
+    number->scaled = !number->scaled;
+
+    gtk_widget_set_size_request(widget, number->width * ( number->scaled ? cfg.scale_factor : 1),
+        number->height * ( number->scaled ? cfg.scale_factor : 1) );
+
+    gtk_widget_queue_draw(GTK_WIDGET(number));
+}
+
+void ui_skinned_number_set_number(GtkWidget *widget, gint num) {
+    g_return_if_fail(UI_SKINNED_IS_NUMBER(widget));
+    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
+
+    if (number->num == num)
+         return;
+
+    number->num = num;
+    gtk_widget_queue_draw(GTK_WIDGET(number));
+}
+
+void ui_skinned_number_set_size(GtkWidget *widget, gint width, gint height) {
+    g_return_if_fail(UI_SKINNED_IS_NUMBER(widget));
+    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
+
+    number->width = width;
+    number->height = height;
+
+    gtk_widget_set_size_request(widget, width*(number->scaled ? cfg.scale_factor : 1 ),
+    height*(number->scaled ? cfg.scale_factor : 1 ));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_number.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,61 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_NUMBER_H
+#define AUDACIOUS_UI_SKINNED_NUMBER_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_NUMBER(obj)          GTK_CHECK_CAST (obj, ui_skinned_number_get_type (), UiSkinnedNumber)
+#define UI_SKINNED_NUMBER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_number_get_type (), UiSkinnedNumberClass)
+#define UI_SKINNED_IS_NUMBER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_number_get_type ())
+
+typedef struct _UiSkinnedNumber        UiSkinnedNumber;
+typedef struct _UiSkinnedNumberClass   UiSkinnedNumberClass;
+
+struct _UiSkinnedNumber {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gint             num;
+    gboolean         scaled;
+    SkinPixmapId     skin_index;
+};
+
+struct _UiSkinnedNumberClass {
+    GtkWidgetClass          parent_class;
+    void (* scaled)        (UiSkinnedNumber *textbox);
+};
+
+GtkWidget* ui_skinned_number_new (GtkWidget *fixed, gint x, gint y, SkinPixmapId si);
+GtkType ui_skinned_number_get_type(void);
+void ui_skinned_number_set_number(GtkWidget *widget, gint num);
+void ui_skinned_number_set_size(GtkWidget *widget, gint width, gint height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_NUMBER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_playlist.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,1105 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ * Copyright (c) 2008 William Pitcock
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ *
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+/*
+ *  A note about Pango and some funky spacey fonts: Weirdly baselined
+ *  fonts, or fonts with weird ascents or descents _will_ display a
+ *  little bit weird in the playlist widget, but the display engine
+ *  won't make it look too bad, just a little deranged.  I honestly
+ *  don't think it's worth fixing (around...), it doesn't have to be
+ *  perfectly fitting, just the general look has to be ok, which it
+ *  IMHO is.
+ *
+ *  A second note: The numbers aren't perfectly aligned, but in the
+ *  end it looks better when using a single Pango layout for each
+ *  number.
+ */
+
+#include "ui_skinned_playlist.h"
+
+#include "debug.h"
+#include "input.h"
+#include "main.h"
+#include "playback.h"
+#include "playlist.h"
+#include "strings.h"
+#include "ui_fileinfopopup.h"
+#include "ui_manager.h"
+#include "ui_playlist.h"
+#include "ui_skin.h"
+#include "util.h"
+
+static PangoFontDescription *playlist_list_font = NULL;
+static gint ascent, descent, width_delta_digit_one;
+static gboolean has_slant;
+static guint padding;
+
+/* FIXME: the following globals should not be needed. */
+static gint width_approx_letters;
+static gint width_colon, width_colon_third;
+static gint width_approx_digits, width_approx_digits_half;
+
+#define UI_SKINNED_PLAYLIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_playlist_get_type(), UiSkinnedPlaylistPrivate))
+typedef struct _UiSkinnedPlaylistPrivate UiSkinnedPlaylistPrivate;
+
+enum {
+    REDRAW,
+    LAST_SIGNAL
+};
+
+struct _UiSkinnedPlaylistPrivate {
+    SkinPixmapId     skin_index;
+    gint             width, height;
+    gint             resize_width, resize_height;
+    gint             drag_pos;
+    gboolean         dragging, auto_drag_down, auto_drag_up;
+    gint             auto_drag_up_tag, auto_drag_down_tag;
+};
+
+static void ui_skinned_playlist_class_init         (UiSkinnedPlaylistClass *klass);
+static void ui_skinned_playlist_init               (UiSkinnedPlaylist *playlist);
+static void ui_skinned_playlist_destroy            (GtkObject *object);
+static void ui_skinned_playlist_realize            (GtkWidget *widget);
+static void ui_skinned_playlist_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_playlist_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_playlist_expose         (GtkWidget *widget, GdkEventExpose *event);
+static gboolean ui_skinned_playlist_button_press   (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_playlist_button_release (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_playlist_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
+static gboolean ui_skinned_playlist_leave_notify   (GtkWidget *widget, GdkEventCrossing *event);
+static void ui_skinned_playlist_redraw             (UiSkinnedPlaylist *playlist);
+static gboolean ui_skinned_playlist_popup_show     (gpointer data);
+static void ui_skinned_playlist_popup_hide         (GtkWidget *widget);
+static void ui_skinned_playlist_popup_timer_start  (GtkWidget *widget);
+static void ui_skinned_playlist_popup_timer_stop   (GtkWidget *widget);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint playlist_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_playlist_get_type() {
+    static GType playlist_type = 0;
+    if (!playlist_type) {
+        static const GTypeInfo playlist_info = {
+            sizeof (UiSkinnedPlaylistClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_playlist_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedPlaylist),
+            0,
+            (GInstanceInitFunc) ui_skinned_playlist_init,
+        };
+        playlist_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaylist_", &playlist_info, 0);
+    }
+
+    return playlist_type;
+}
+
+static void ui_skinned_playlist_class_init(UiSkinnedPlaylistClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_playlist_destroy;
+
+    widget_class->realize = ui_skinned_playlist_realize;
+    widget_class->expose_event = ui_skinned_playlist_expose;
+    widget_class->size_request = ui_skinned_playlist_size_request;
+    widget_class->size_allocate = ui_skinned_playlist_size_allocate;
+    widget_class->button_press_event = ui_skinned_playlist_button_press;
+    widget_class->button_release_event = ui_skinned_playlist_button_release;
+    widget_class->motion_notify_event = ui_skinned_playlist_motion_notify;
+    widget_class->leave_notify_event = ui_skinned_playlist_leave_notify;
+
+    klass->redraw = ui_skinned_playlist_redraw;
+
+    playlist_signals[REDRAW] = 
+        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedPlaylistClass, redraw), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    g_type_class_add_private (gobject_class, sizeof (UiSkinnedPlaylistPrivate));
+}
+
+static void ui_skinned_playlist_init(UiSkinnedPlaylist *playlist) {
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist);
+    playlist->pressed = FALSE;
+    priv->resize_width = 0;
+    priv->resize_height = 0;
+    playlist->prev_selected = -1;
+    playlist->prev_min = -1;
+    playlist->prev_max = -1;
+
+    g_object_set_data(G_OBJECT(playlist), "timer_id", GINT_TO_POINTER(0));
+    g_object_set_data(G_OBJECT(playlist), "timer_active", GINT_TO_POINTER(0));
+
+    GtkWidget *popup = fileinfopopup_create();
+    g_object_set_data(G_OBJECT(playlist), "popup", popup);
+    g_object_set_data(G_OBJECT(playlist), "popup_active", GINT_TO_POINTER(0));
+    g_object_set_data(G_OBJECT(playlist), "popup_position", GINT_TO_POINTER(-1));
+}
+
+GtkWidget* ui_skinned_playlist_new(GtkWidget *fixed, gint x, gint y, gint w, gint h) {
+
+    UiSkinnedPlaylist *hs = g_object_new (ui_skinned_playlist_get_type (), NULL);
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(hs);
+
+    hs->x = x;
+    hs->y = y;
+    priv->width = w;
+    priv->height = h;
+    priv->skin_index = SKIN_PLEDIT;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y);
+    gtk_widget_set_double_buffered(GTK_WIDGET(hs), TRUE);
+
+    return GTK_WIDGET(hs);
+}
+
+static void ui_skinned_playlist_destroy(GtkObject *object) {
+    UiSkinnedPlaylist *playlist;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_PLAYLIST (object));
+
+    playlist = UI_SKINNED_PLAYLIST (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_playlist_realize(GtkWidget *widget) {
+    UiSkinnedPlaylist *playlist;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_PLAYLIST(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    playlist = UI_SKINNED_PLAYLIST(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+                             GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_playlist_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
+
+    requisition->width = priv->width;
+    requisition->height = priv->height;
+}
+
+static void ui_skinned_playlist_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedPlaylist *playlist = UI_SKINNED_PLAYLIST (widget);
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist);
+
+    widget->allocation = *allocation;
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    playlist->x = widget->allocation.x;
+    playlist->y = widget->allocation.y;
+
+    if (priv->height != widget->allocation.height || priv->width != widget->allocation.width) {
+        priv->width = priv->width + priv->resize_width;
+        priv->height = priv->height + priv->resize_height;
+        priv->resize_width = 0;
+        priv->resize_height = 0;
+        gtk_widget_queue_draw(widget);
+    }
+}
+
+static gboolean ui_skinned_playlist_auto_drag_down_func(gpointer data) {
+    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(data);
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(data);
+
+    if (priv->auto_drag_down) {
+        ui_skinned_playlist_move_down(pl);
+        pl->first++;
+        playlistwin_update_list(playlist_get_active());
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean ui_skinned_playlist_auto_drag_up_func(gpointer data) {
+    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(data);
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(data);
+
+    if (priv->auto_drag_up) {
+        ui_skinned_playlist_move_up(pl);
+        pl->first--;
+        playlistwin_update_list(playlist_get_active());
+        return TRUE;
+
+    }
+    return FALSE;
+}
+
+void ui_skinned_playlist_move_up(UiSkinnedPlaylist * pl) {
+    GList *list;
+    Playlist *playlist = playlist_get_active();
+
+    if (!playlist)
+        return;
+
+    PLAYLIST_LOCK(playlist);
+    if ((list = playlist->entries) == NULL) {
+        PLAYLIST_UNLOCK(playlist);
+        return;
+    }
+    if (PLAYLIST_ENTRY(list->data)->selected) {
+        /* We are at the top */
+        PLAYLIST_UNLOCK(playlist);
+        return;
+    }
+    while (list) {
+        if (PLAYLIST_ENTRY(list->data)->selected)
+            glist_moveup(list);
+        list = g_list_next(list);
+    }
+    PLAYLIST_INCR_SERIAL(playlist);
+    PLAYLIST_UNLOCK(playlist);
+    if (pl->prev_selected != -1)
+        pl->prev_selected--;
+    if (pl->prev_min != -1)
+        pl->prev_min--;
+    if (pl->prev_max != -1)
+        pl->prev_max--;
+}
+
+void ui_skinned_playlist_move_down(UiSkinnedPlaylist * pl) {
+    GList *list;
+    Playlist *playlist = playlist_get_active();
+
+    if (!playlist)
+        return;
+
+    PLAYLIST_LOCK(playlist);
+
+    if (!(list = g_list_last(playlist->entries))) {
+        PLAYLIST_UNLOCK(playlist);
+        return;
+    }
+
+    if (PLAYLIST_ENTRY(list->data)->selected) {
+        /* We are at the bottom */
+        PLAYLIST_UNLOCK(playlist);
+        return;
+    }
+
+    while (list) {
+        if (PLAYLIST_ENTRY(list->data)->selected)
+            glist_movedown(list);
+        list = g_list_previous(list);
+    }
+
+    PLAYLIST_INCR_SERIAL(playlist);
+    PLAYLIST_UNLOCK(playlist);
+
+    if (pl->prev_selected != -1)
+        pl->prev_selected++;
+    if (pl->prev_min != -1)
+        pl->prev_min++;
+    if (pl->prev_max != -1)
+        pl->prev_max++;
+}
+
+static void
+playlist_list_draw_string(cairo_t *cr, UiSkinnedPlaylist *pl,
+                          PangoFontDescription * font,
+                          gint line,
+                          gint width,
+                          const gchar * text,
+                          guint ppos)
+{
+    guint plist_length_int;
+    Playlist *playlist = playlist_get_active();
+    PangoLayout *layout;
+
+    REQUIRE_LOCK(playlist->mutex);
+
+    cairo_new_path(cr);
+
+    if (cfg.show_numbers_in_pl) {
+        gchar *pos_string = g_strdup_printf(cfg.show_separator_in_pl == TRUE ? "%d" : "%d.", ppos);
+        plist_length_int =
+            gint_count_digits(playlist_get_length(playlist)) + !cfg.show_separator_in_pl + 1; /* cf.show_separator_in_pl will be 0 if false */
+
+        padding = plist_length_int;
+        padding = ((padding + 1) * width_approx_digits);
+
+        layout = gtk_widget_create_pango_layout(playlistwin, pos_string);
+        pango_layout_set_font_description(layout, playlist_list_font);
+        pango_layout_set_width(layout, plist_length_int * 100);
+
+        pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
+
+        cairo_move_to(cr, (width_approx_digits *
+                         (-1 + plist_length_int - strlen(pos_string))) +
+                        (width_approx_digits / 4), (line - 1) * pl->fheight +
+                        ascent + abs(descent));
+        pango_cairo_show_layout(cr, layout);
+
+        g_free(pos_string);
+        g_object_unref(layout);
+
+        if (!cfg.show_separator_in_pl)
+            padding -= (width_approx_digits * 1.5);
+    } else {
+        padding = 3;
+    }
+
+    width -= padding;
+
+    layout = gtk_widget_create_pango_layout(playlistwin, text);
+
+    pango_layout_set_font_description(layout, playlist_list_font);
+    pango_layout_set_width(layout, width * PANGO_SCALE);
+    pango_layout_set_single_paragraph_mode(layout, TRUE);
+    pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
+
+    cairo_move_to(cr, padding + (width_approx_letters / 4),
+                    (line - 1) * pl->fheight +
+                    ascent + abs(descent));
+    pango_cairo_show_layout(cr, layout);
+
+    g_object_unref(layout);
+}
+
+static gboolean ui_skinned_playlist_expose(GtkWidget *widget, GdkEventExpose *event) {
+    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget);
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(pl);
+    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
+
+    Playlist *playlist = playlist_get_active();
+    PlaylistEntry *entry;
+    GList *list;
+    PangoLayout *layout;
+    gchar *title;
+    gint width, height;
+    gint i, max_first;
+    guint padding, padding_dwidth, padding_plength;
+    guint max_time_len = 0;
+    gfloat queue_tailpadding = 0;
+    gint tpadding; 
+    gsize tpadding_dwidth = 0;
+    gint x, y;
+    guint tail_width;
+    guint tail_len;
+    gboolean in_selection = FALSE;
+
+    gchar tail[100];
+    gchar queuepos[255];
+    gchar length[40];
+
+    gchar **frags;
+    gchar *frag0;
+
+    gint plw_w, plw_h;
+
+    cairo_t *cr;
+    gint yc;
+    gint pos;
+    gdouble rounding_offset;
+
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_PLAYLIST (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    cr = gdk_cairo_create(widget->window);
+
+    width = priv->width;
+    height = priv->height;
+
+    plw_w = playlistwin_get_width();
+    plw_h = playlistwin_get_height();
+
+    gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMALBG));
+
+    cairo_rectangle(cr, 0, 0, width, height);
+    cairo_paint(cr);
+
+    if (!playlist_list_font) {
+        g_critical("Couldn't open playlist font");
+        return FALSE;
+    }
+
+    pl->fheight = (ascent + abs(descent));
+    pl->num_visible = height / pl->fheight;
+
+    rounding_offset = pl->fheight / 3;
+
+    max_first = playlist_get_length(playlist) - pl->num_visible;
+    max_first = MAX(max_first, 0);
+
+    pl->first = CLAMP(pl->first, 0, max_first);
+
+    PLAYLIST_LOCK(playlist);
+    list = playlist->entries;
+    list = g_list_nth(list, pl->first);
+
+    /* It sucks having to run the iteration twice but this is the only
+       way you can reliably get the maximum width so we can get our
+       playlist nice and aligned... -- plasmaroo */
+
+    for (i = pl->first;
+         list && i < pl->first + pl->num_visible;
+         list = g_list_next(list), i++) {
+        entry = list->data;
+
+        if (entry->length != -1)
+        {
+            g_snprintf(length, sizeof(length), "%d:%-2.2d",
+                       entry->length / 60000, (entry->length / 1000) % 60);
+            tpadding_dwidth = MAX(tpadding_dwidth, strlen(length));
+        }
+    }
+
+    /* Reset */
+    list = playlist->entries;
+    list = g_list_nth(list, pl->first);
+
+    for (i = pl->first;
+         list && i < pl->first + pl->num_visible;
+         list = g_list_next(list), i++) {
+        entry = list->data;
+
+        if (entry->selected && !in_selection) {
+            yc = ((i - pl->first) * pl->fheight);
+
+            cairo_new_path(cr);
+
+            cairo_move_to(cr, 0, yc + (rounding_offset * 2));
+            cairo_curve_to(cr, 0, yc + rounding_offset, 0, yc + 0.5, 0 + rounding_offset, yc + 0.5);
+
+            cairo_line_to(cr, 0 + width - (rounding_offset * 2), yc + 0.5);
+            cairo_curve_to(cr, 0 + width - rounding_offset, yc + 0.5,
+                        0 + width, yc + 0.5, 0 + width, yc + rounding_offset);
+
+            in_selection = TRUE;
+        }
+
+        if ((!entry->selected ||
+            (i == pl->first + pl->num_visible - 1) || !g_list_next(list))
+            && in_selection) {
+
+            if (!entry->selected)
+                yc = (((i - 1) - pl->first) * pl->fheight);
+            else /* last visible item */
+                yc = ((i - pl->first) * pl->fheight);
+
+            cairo_line_to(cr, 0 + width, yc + pl->fheight - (rounding_offset * 2));
+            cairo_curve_to (cr, 0 + width, yc + pl->fheight - rounding_offset,
+                        0 + width, yc + pl->fheight - 0.5,
+                        0 + width-rounding_offset, yc + pl->fheight - 0.5);
+
+            cairo_line_to (cr, 0 + (rounding_offset * 2), yc + pl->fheight - 0.5);
+            cairo_curve_to (cr, 0 + rounding_offset, yc + pl->fheight - 0.5,
+                        0, yc + pl->fheight - 0.5,
+                        0, yc + pl->fheight - rounding_offset);
+
+            cairo_close_path (cr);
+
+            gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_SELECTEDBG));
+
+            cairo_fill(cr);
+
+            in_selection = FALSE;
+        }
+    }
+
+    list = playlist->entries;
+    list = g_list_nth(list, pl->first);
+
+    /* now draw the text */
+    for (i = pl->first;
+         list && i < pl->first + pl->num_visible;
+         list = g_list_next(list), i++) {
+        entry = list->data;
+
+        /* FIXME: entry->title should NEVER be NULL, and there should
+           NEVER be a need to do a UTF-8 conversion. Playlist title
+           strings should be kept properly. */
+
+        if (!entry->title) {
+            gchar *realfn = g_filename_from_uri(entry->filename, NULL, NULL);
+            gchar *basename = g_path_get_basename(realfn ? realfn : entry->filename);
+            title = filename_to_utf8(basename);
+            g_free(basename); g_free(realfn);
+        }
+        else
+            title = str_assert_utf8(entry->title);
+
+        title = convert_title_text(title);
+
+        pos = playlist_get_queue_position(playlist, entry);
+
+        tail[0] = 0;
+        queuepos[0] = 0;
+        length[0] = 0;
+
+        if (pos != -1)
+            g_snprintf(queuepos, sizeof(queuepos), "%d", pos + 1);
+
+        if (entry->length != -1)
+        {
+            g_snprintf(length, sizeof(length), "%d:%-2.2d",
+                       entry->length / 60000, (entry->length / 1000) % 60);
+        }
+
+        strncat(tail, length, sizeof(tail) - 1);
+        tail_len = strlen(tail);
+
+        max_time_len = MAX(max_time_len, tail_len);
+
+        if (pos != -1 && tpadding_dwidth <= 0)
+            tail_width = width - (width_approx_digits * (strlen(queuepos) + 2.25));
+        else if (pos != -1)
+            tail_width = width - (width_approx_digits * (tpadding_dwidth + strlen(queuepos) + 4));
+        else if (tpadding_dwidth > 0)
+            tail_width = width - (width_approx_digits * (tpadding_dwidth + 2.5));
+        else
+            tail_width = width;
+
+        if (i == playlist_get_position_nolock(playlist))
+            gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT));
+        else
+            gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMAL));
+
+        playlist_list_draw_string(cr, pl, playlist_list_font,
+                                  i - pl->first, tail_width, title,
+                                  i + 1);
+
+        x = width - width_approx_digits * 2;
+        y = ((i - pl->first) - 1) * pl->fheight + ascent;
+
+        frags = NULL;
+        frag0 = NULL;
+
+        if ((strlen(tail) > 0) && (tail != NULL)) {
+            frags = g_strsplit(tail, ":", 0);
+            frag0 = g_strconcat(frags[0], ":", NULL);
+
+            layout = gtk_widget_create_pango_layout(playlistwin, frags[1]);
+            pango_layout_set_font_description(layout, playlist_list_font);
+            pango_layout_set_width(layout, tail_len * 100);
+            pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
+
+            cairo_new_path(cr);
+            cairo_move_to(cr, x - (0.5 * width_approx_digits), y + abs(descent));
+            pango_cairo_show_layout(cr, layout);
+            g_object_unref(layout);
+
+            layout = gtk_widget_create_pango_layout(playlistwin, frag0);
+            pango_layout_set_font_description(layout, playlist_list_font);
+            pango_layout_set_width(layout, tail_len * 100);
+            pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
+
+            cairo_move_to(cr, x - (0.75 * width_approx_digits), y + abs(descent));
+            pango_cairo_show_layout(cr, layout);
+            g_object_unref(layout);
+
+            g_free(frag0);
+            g_strfreev(frags);
+        }
+
+        if (pos != -1) {
+            if (tpadding_dwidth > 0)
+                queue_tailpadding = tpadding_dwidth + 1;
+            else
+                queue_tailpadding = -0.75;
+
+            cairo_rectangle(cr,
+                            x -
+                            (((queue_tailpadding +
+                               strlen(queuepos)) *
+                              width_approx_digits) +
+                             (width_approx_digits / 4)),
+                            y + abs(descent),
+                            (strlen(queuepos)) *
+                            width_approx_digits +
+                            (width_approx_digits / 2),
+                            pl->fheight - 2);
+
+            layout =
+                gtk_widget_create_pango_layout(playlistwin, queuepos);
+            pango_layout_set_font_description(layout, playlist_list_font);
+            pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
+
+            cairo_move_to(cr,
+                            x -
+                            ((queue_tailpadding +
+                              strlen(queuepos)) * width_approx_digits) +
+                            (width_approx_digits / 4),
+                            y + abs(descent));
+            pango_cairo_show_layout(cr, layout);
+
+            g_object_unref(layout);
+        }
+
+        cairo_stroke(cr);
+
+        g_free(title);
+    }
+
+
+    /*
+     * Drop target hovering over the playlist, so draw some hint where the
+     * drop will occur.
+     *
+     * This is (currently? unfixably?) broken when dragging files from Qt/KDE apps,
+     * probably due to DnD signaling problems (actually i have no clue).
+     *
+     */
+
+    if (pl->drag_motion) {
+        guint pos, plength, lpadding;
+
+        if (cfg.show_numbers_in_pl) {
+            lpadding = gint_count_digits(playlist_get_length(playlist)) + 1;
+            lpadding = ((lpadding + 1) * width_approx_digits);
+        }
+        else {
+            lpadding = 3;
+        };
+
+        /* We already hold the mutex and have the playlist locked, so call
+           the non-locking function. */
+        plength = playlist_get_length(playlist);
+
+        x = pl->drag_motion_x;
+        y = pl->drag_motion_y;
+
+        if ((x > pl->x) && !(x > priv->width)) {
+
+            if ((y > pl->y)
+                && !(y > (priv->height + pl->y))) {
+
+                pos = (y / pl->fheight) +
+                    pl->first;
+
+                if (pos > (plength)) {
+                    pos = plength;
+                }
+
+                gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT));
+
+                cairo_new_path(cr);
+
+                cairo_move_to(cr, 0, ((pos - pl->first) * pl->fheight));
+                cairo_rel_line_to(cr, priv->width - 1, 0);
+
+                cairo_set_line_width(cr, 1);
+                cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+                cairo_stroke(cr);
+            }
+
+        }
+
+        /* When dropping on the borders of the playlist, outside the text area,
+         * files get appended at the end of the list. Show that too.
+         */
+
+        if ((y < pl->y) || (y > priv->height + pl->y)) {
+            if ((y >= 0) || (y <= (priv->height + pl->y))) {
+                pos = plength;
+
+                gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT));
+
+                cairo_new_path(cr);
+
+                cairo_move_to(cr, 0, ((pos - pl->first) * pl->fheight));
+                cairo_rel_line_to(cr, priv->width - 1, 0);
+
+                cairo_set_line_width(cr, 1);
+                cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+                cairo_stroke(cr);
+            }
+        }
+    }
+
+    gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMAL));
+    cairo_set_line_width(cr, 1);
+    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+
+    if (cfg.show_numbers_in_pl)
+    {
+        padding_plength = playlist_get_length(playlist);
+
+        if (padding_plength == 0) {
+            padding_dwidth = 0;
+        }
+        else {
+            padding_dwidth = gint_count_digits(playlist_get_length(playlist));
+        }
+
+        padding =
+            (padding_dwidth *
+             width_approx_digits) + width_approx_digits;
+
+
+        /* For italic or oblique fonts we add another half of the
+         * approximate width */
+        if (has_slant)
+            padding += width_approx_digits_half;
+
+        if (cfg.show_separator_in_pl) {
+            cairo_new_path(cr);
+
+            cairo_move_to(cr, padding, 0);
+            cairo_rel_line_to(cr, 0, priv->height - 1);
+
+            cairo_stroke(cr);
+        }
+    }
+
+    if (tpadding_dwidth != 0)
+    {
+        tpadding = (tpadding_dwidth * width_approx_digits) + (width_approx_digits * 1.5);
+
+        if (has_slant)
+            tpadding += width_approx_digits_half;
+
+        if (cfg.show_separator_in_pl) {
+            cairo_new_path(cr);
+
+            cairo_move_to(cr, priv->width - tpadding, 0);
+            cairo_rel_line_to(cr, 0, priv->height - 1);
+
+            cairo_stroke(cr);
+        }
+    }
+
+    PLAYLIST_UNLOCK(playlist);
+
+    cairo_destroy(cr);
+
+    return FALSE;
+}
+
+gint ui_skinned_playlist_get_position(GtkWidget *widget, gint x, gint y) {
+    gint iy, length;
+    gint ret;
+    Playlist *playlist = playlist_get_active();
+    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget);
+
+    if (!pl->fheight)
+        return -1;
+
+    if ((length = playlist_get_length(playlist)) == 0)
+        return -1;
+    iy = y;
+
+    ret = (iy / pl->fheight) + pl->first;
+
+    if (ret > length - 1)
+        ret = -1;
+
+    return ret;
+}
+
+static gboolean ui_skinned_playlist_button_press(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget);
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
+
+    gint nr;
+    Playlist *playlist = playlist_get_active();
+
+    nr = ui_skinned_playlist_get_position(widget, event->x, event->y);
+    if (nr == -1)
+        return FALSE;
+
+    if (event->button == 3) {
+        ui_manager_popup_menu_show(GTK_MENU(playlistwin_popup_menu),
+                                   event->x_root, event->y_root + 5,
+                                   event->button, event->time);
+        GList* selection = playlist_get_selected(playlist);
+        if (g_list_find(selection, GINT_TO_POINTER(nr)) == NULL) {
+            playlist_select_all(playlist, FALSE);
+            playlist_select_range(playlist, nr, nr, TRUE);
+        }
+    } else if (event->button == 1) {
+        if (!(event->state & GDK_CONTROL_MASK))
+            playlist_select_all(playlist, FALSE);
+
+        if ((event->state & GDK_MOD1_MASK))
+            playlist_queue_position(playlist, nr);
+
+        if (event->state & GDK_SHIFT_MASK && pl->prev_selected != -1) {
+            playlist_select_range(playlist, pl->prev_selected, nr, TRUE);
+            pl->prev_min = pl->prev_selected;
+            pl->prev_max = nr;
+            priv->drag_pos = nr - pl->first;
+        }
+        else {
+            if (playlist_select_invert(playlist, nr)) {
+                if (event->state & GDK_CONTROL_MASK) {
+                    if (pl->prev_min == -1) {
+                        pl->prev_min = pl->prev_selected;
+                        pl->prev_max = pl->prev_selected;
+                    }
+                    if (nr < pl->prev_min)
+                        pl->prev_min = nr;
+                    else if (nr > pl->prev_max)
+                        pl->prev_max = nr;
+                }
+                else
+                    pl->prev_min = -1;
+                pl->prev_selected = nr;
+                priv->drag_pos = nr - pl->first;
+            }
+        }
+        if (event->type == GDK_2BUTTON_PRESS) {
+            /*
+             * Ungrab the pointer to prevent us from
+             * hanging on to it during the sometimes slow
+             * playback_initiate().
+             */
+            gdk_pointer_ungrab(GDK_CURRENT_TIME);
+            playlist_set_position(playlist, nr);
+            if (!playback_get_playing())
+                playback_initiate();
+        }
+
+        priv->dragging = TRUE;
+    }
+    playlistwin_update_list(playlist);
+    ui_skinned_playlist_popup_hide(widget);
+    ui_skinned_playlist_popup_timer_stop(widget);
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_playlist_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
+
+    priv->dragging = FALSE;
+    priv->auto_drag_down = FALSE;
+    priv->auto_drag_up = FALSE;
+    gtk_widget_queue_draw(widget);
+
+    ui_skinned_playlist_popup_hide(widget);
+    ui_skinned_playlist_popup_timer_stop(widget);
+    return TRUE;
+}
+
+static gboolean ui_skinned_playlist_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
+    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(widget);
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
+
+    gint nr, y, off, i;
+    if (priv->dragging) {
+        y = event->y;
+        nr = (y / pl->fheight);
+        if (nr < 0) {
+            nr = 0;
+            if (!priv->auto_drag_up) {
+                priv->auto_drag_up = TRUE;
+                priv->auto_drag_up_tag =
+                    g_timeout_add(100, ui_skinned_playlist_auto_drag_up_func, pl);
+            }
+        }
+        else if (priv->auto_drag_up)
+            priv->auto_drag_up = FALSE;
+
+        if (nr >= pl->num_visible) {
+            nr = pl->num_visible - 1;
+            if (!priv->auto_drag_down) {
+                priv->auto_drag_down = TRUE;
+                priv->auto_drag_down_tag =
+                    g_timeout_add(100, ui_skinned_playlist_auto_drag_down_func, pl);
+            }
+        }
+        else if (priv->auto_drag_down)
+            priv->auto_drag_down = FALSE;
+
+        off = nr - priv->drag_pos;
+        if (off) {
+            for (i = 0; i < abs(off); i++) {
+                if (off < 0)
+                    ui_skinned_playlist_move_up(pl);
+                else
+                    ui_skinned_playlist_move_down(pl);
+
+            }
+            playlistwin_update_list(playlist_get_active());
+        }
+        priv->drag_pos = nr;
+    } else if (cfg.show_filepopup_for_tuple) {
+        gint pos = ui_skinned_playlist_get_position(widget, event->x, event->y);
+        gint cur_pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_position"));
+        if (pos != cur_pos) {
+            g_object_set_data(G_OBJECT(widget), "popup_position", GINT_TO_POINTER(pos));
+            ui_skinned_playlist_popup_hide(widget);
+            ui_skinned_playlist_popup_timer_stop(widget);
+            if (pos != -1)
+                ui_skinned_playlist_popup_timer_start(widget);
+        }
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_playlist_leave_notify(GtkWidget *widget, GdkEventCrossing *event) {
+    ui_skinned_playlist_popup_hide(widget);
+    ui_skinned_playlist_popup_timer_stop(widget);
+
+    return FALSE;
+}
+
+static void ui_skinned_playlist_redraw(UiSkinnedPlaylist *playlist) {
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist);
+
+    if (priv->resize_height || priv->resize_width)
+        gtk_widget_set_size_request(GTK_WIDGET(playlist), priv->width+priv->resize_width, priv->height+priv->resize_height);
+
+    gtk_widget_queue_draw(GTK_WIDGET(playlist));
+}
+
+void ui_skinned_playlist_set_font(const gchar * font) {
+    /* Welcome to bad hack central 2k3 */
+    gchar *font_lower;
+    gint width_temp;
+    gint width_temp_0;
+
+    playlist_list_font = pango_font_description_from_string(font);
+
+    text_get_extents(font,
+                     "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ",
+                     &width_approx_letters, NULL, &ascent, &descent);
+
+    width_approx_letters = (width_approx_letters / 53);
+
+    /* Experimental: We don't weigh the 1 into total because it's width is almost always
+     * very different from the rest
+     */
+    text_get_extents(font, "023456789", &width_approx_digits, NULL, NULL,
+                     NULL);
+    width_approx_digits = (width_approx_digits / 9);
+
+    /* Precache some often used calculations */
+    width_approx_digits_half = width_approx_digits / 2;
+
+    /* FIXME: We assume that any other number is broader than the "1" */
+    text_get_extents(font, "1", &width_temp, NULL, NULL, NULL);
+    text_get_extents(font, "2", &width_temp_0, NULL, NULL, NULL);
+
+    if (abs(width_temp_0 - width_temp) < 2) {
+        width_delta_digit_one = 0;
+    }
+    else {
+        width_delta_digit_one = ((width_temp_0 - width_temp) / 2) + 2;
+    }
+
+    text_get_extents(font, ":", &width_colon, NULL, NULL, NULL);
+    width_colon_third = width_colon / 4;
+
+    font_lower = g_utf8_strdown(font, strlen(font));
+    /* This doesn't take any i18n into account, but i think there is none with TTF fonts
+     * FIXME: This can probably be retrieved trough Pango too
+     */
+    has_slant = g_strstr_len(font_lower, strlen(font_lower), "oblique")
+        || g_strstr_len(font_lower, strlen(font_lower), "italic");
+
+    g_free(font_lower);
+}
+
+void ui_skinned_playlist_resize_relative(GtkWidget *widget, gint w, gint h) {
+    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
+    priv->resize_width += w;
+    priv->resize_height += h;
+}
+
+static gboolean ui_skinned_playlist_popup_show(gpointer data) {
+    GtkWidget *widget = data;
+    gint pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_position"));
+
+    if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_active")) == 1 && pos != -1) {
+        Tuple *tuple;
+        Playlist *pl_active = playlist_get_active();
+        GtkWidget *popup = g_object_get_data(G_OBJECT(widget), "popup");
+
+        tuple = playlist_get_tuple(pl_active, pos);
+        if ((tuple == NULL) || (tuple_get_int(tuple, FIELD_LENGTH, NULL) < 1)) {
+           gchar *title = playlist_get_songtitle(pl_active, pos);
+           fileinfopopup_show_from_title(popup, title);
+           g_free(title);
+        } else {
+           fileinfopopup_show_from_tuple(popup , tuple);
+        }
+        g_object_set_data(G_OBJECT(widget), "popup_active" , GINT_TO_POINTER(1));
+    }
+
+    ui_skinned_playlist_popup_timer_stop(widget);
+    return FALSE;
+}
+
+static void ui_skinned_playlist_popup_hide(GtkWidget *widget) {
+    if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_active")) == 1) {
+        GtkWidget *popup = g_object_get_data(G_OBJECT(widget), "popup");
+        g_object_set_data(G_OBJECT(widget), "popup_active", GINT_TO_POINTER(0));
+        fileinfopopup_hide(popup, NULL);
+    }
+}
+
+static void ui_skinned_playlist_popup_timer_start(GtkWidget *widget) {
+    gint timer_id = g_timeout_add(cfg.filepopup_delay*100, ui_skinned_playlist_popup_show, widget);
+    g_object_set_data(G_OBJECT(widget), "timer_id", GINT_TO_POINTER(timer_id));
+    g_object_set_data(G_OBJECT(widget), "timer_active", GINT_TO_POINTER(1));
+}
+
+static void ui_skinned_playlist_popup_timer_stop(GtkWidget *widget) {
+    if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_active")) == 1)
+        g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_id")));
+
+    g_object_set_data(G_OBJECT(widget), "timer_id", GINT_TO_POINTER(0));
+    g_object_set_data(G_OBJECT(widget), "timer_active", GINT_TO_POINTER(0));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_playlist.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,77 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_PLAYLIST_H
+#define AUDACIOUS_UI_SKINNED_PLAYLIST_H
+
+#include <gtk/gtk.h>
+
+#include <cairo.h>
+#include <pango/pangocairo.h>
+
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_PLAYLIST(obj)          GTK_CHECK_CAST (obj, ui_skinned_playlist_get_type (), UiSkinnedPlaylist)
+#define UI_SKINNED_PLAYLIST_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_playlist_get_type (), UiSkinnedPlaylistClass)
+#define UI_SKINNED_IS_PLAYLIST(obj)       GTK_CHECK_TYPE (obj, ui_skinned_playlist_get_type ())
+
+typedef struct _UiSkinnedPlaylist        UiSkinnedPlaylist;
+typedef struct _UiSkinnedPlaylistClass   UiSkinnedPlaylistClass;
+
+struct _UiSkinnedPlaylist {
+    GtkWidget   widget;
+    gboolean    pressed;
+    gint        x, y;
+    gint        first;
+    gint        num_visible;
+    gint        prev_selected, prev_min, prev_max;
+    gboolean    drag_motion;
+    gint        drag_motion_x, drag_motion_y;
+    gint        fheight;
+};
+
+struct _UiSkinnedPlaylistClass {
+    GtkWidgetClass    parent_class;
+    void (* redraw)   (UiSkinnedPlaylist *playlist);
+};
+
+GtkWidget* ui_skinned_playlist_new(GtkWidget *fixed, gint x, gint y, gint w, gint h);
+GtkType ui_skinned_playlist_get_type(void);
+void ui_skinned_playlist_resize_relative(GtkWidget *widget, gint w, gint h);
+void ui_skinned_playlist_set_font(const gchar * font);
+void ui_skinned_playlist_move_up(UiSkinnedPlaylist *pl);
+void ui_skinned_playlist_move_down(UiSkinnedPlaylist *pl);
+gint ui_skinned_playlist_get_position(GtkWidget *widget, gint x, gint y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_PLAYLIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_playlist_slider.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,338 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skin.h"
+#include "ui_skinned_playlist_slider.h"
+#include "main.h"
+#include "ui_playlist.h"
+
+#define UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_playlist_slider_get_type(), UiSkinnedPlaylistSliderPrivate))
+typedef struct _UiSkinnedPlaylistSliderPrivate UiSkinnedPlaylistSliderPrivate;
+
+enum {
+    REDRAW,
+    LAST_SIGNAL
+};
+
+struct _UiSkinnedPlaylistSliderPrivate {
+    SkinPixmapId     skin_index;
+    gint             width, height;
+
+    gint             resize_height;
+    gint             move_x;
+    gint             prev_y;
+    gint             drag_y;
+};
+
+static void ui_skinned_playlist_slider_class_init         (UiSkinnedPlaylistSliderClass *klass);
+static void ui_skinned_playlist_slider_init               (UiSkinnedPlaylistSlider *playlist_slider);
+static void ui_skinned_playlist_slider_destroy            (GtkObject *object);
+static void ui_skinned_playlist_slider_realize            (GtkWidget *widget);
+static void ui_skinned_playlist_slider_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_playlist_slider_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_playlist_slider_expose         (GtkWidget *widget, GdkEventExpose *event);
+static void ui_skinned_playlist_slider_set_position       (GtkWidget *widget, gint y);
+static gboolean ui_skinned_playlist_slider_button_press   (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_playlist_slider_button_release (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_playlist_slider_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
+static void ui_skinned_playlist_slider_redraw             (UiSkinnedPlaylistSlider *playlist_slider);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint playlist_slider_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_playlist_slider_get_type() {
+    static GType playlist_slider_type = 0;
+    if (!playlist_slider_type) {
+        static const GTypeInfo playlist_slider_info = {
+            sizeof (UiSkinnedPlaylistSliderClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_playlist_slider_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedPlaylistSlider),
+            0,
+            (GInstanceInitFunc) ui_skinned_playlist_slider_init,
+        };
+        playlist_slider_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaylistSlider_", &playlist_slider_info, 0);
+    }
+
+    return playlist_slider_type;
+}
+
+static void ui_skinned_playlist_slider_class_init(UiSkinnedPlaylistSliderClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_playlist_slider_destroy;
+
+    widget_class->realize = ui_skinned_playlist_slider_realize;
+    widget_class->expose_event = ui_skinned_playlist_slider_expose;
+    widget_class->size_request = ui_skinned_playlist_slider_size_request;
+    widget_class->size_allocate = ui_skinned_playlist_slider_size_allocate;
+    widget_class->button_press_event = ui_skinned_playlist_slider_button_press;
+    widget_class->button_release_event = ui_skinned_playlist_slider_button_release;
+    widget_class->motion_notify_event = ui_skinned_playlist_slider_motion_notify;
+
+    klass->redraw = ui_skinned_playlist_slider_redraw;
+
+    playlist_slider_signals[REDRAW] = 
+        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedPlaylistSliderClass, redraw), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    g_type_class_add_private (gobject_class, sizeof (UiSkinnedPlaylistSliderPrivate));
+}
+
+static void ui_skinned_playlist_slider_init(UiSkinnedPlaylistSlider *playlist_slider) {
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider);
+    playlist_slider->pressed = FALSE;
+    priv->resize_height = 0;
+    priv->move_x = 0;
+    priv->drag_y = 0;
+    priv->prev_y = 0;
+}
+
+GtkWidget* ui_skinned_playlist_slider_new(GtkWidget *fixed, gint x, gint y, gint h) {
+
+    UiSkinnedPlaylistSlider *hs = g_object_new (ui_skinned_playlist_slider_get_type (), NULL);
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(hs);
+
+    hs->x = x;
+    hs->y = y;
+    priv->width = 8;
+    priv->height = h;
+    priv->skin_index = SKIN_PLEDIT;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y);
+
+    return GTK_WIDGET(hs);
+}
+
+static void ui_skinned_playlist_slider_destroy(GtkObject *object) {
+    UiSkinnedPlaylistSlider *playlist_slider;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER (object));
+
+    playlist_slider = UI_SKINNED_PLAYLIST_SLIDER (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_playlist_slider_realize(GtkWidget *widget) {
+    UiSkinnedPlaylistSlider *playlist_slider;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    playlist_slider = UI_SKINNED_PLAYLIST_SLIDER(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_playlist_slider_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
+
+    requisition->width = priv->width;
+    requisition->height = priv->height;
+}
+
+static void ui_skinned_playlist_slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedPlaylistSlider *playlist_slider = UI_SKINNED_PLAYLIST_SLIDER (widget);
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider);
+
+    widget->allocation = *allocation;
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    if (playlist_slider->x + priv->move_x == widget->allocation.x)
+        priv->move_x = 0;
+    playlist_slider->x = widget->allocation.x;
+    playlist_slider->y = widget->allocation.y;
+
+    if (priv->height != widget->allocation.height) {
+        priv->height = priv->height + priv->resize_height;
+        priv->resize_height = 0;
+        gtk_widget_queue_draw(widget);
+    }
+}
+
+static gboolean ui_skinned_playlist_slider_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER (widget);
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(ps);
+    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->width, priv->height);
+
+    gint num_visible;
+    num_visible = playlistwin_list_get_visible_count();
+
+
+    Playlist *playlist = playlist_get_active();
+
+    gint y;
+    if (playlist_get_length(playlist) > num_visible)
+        y = (playlistwin_list_get_first() * (priv->height - 19)) /
+            (playlist_get_length(playlist) - num_visible);
+    else
+        y = 0;
+
+    if (y < 0) y=0;
+    if (y > priv->height - 19) y = priv->height - 19;
+
+    priv->prev_y = y;
+
+    /* FIXME: uses aud_active_skin->pixmaps directly and may need calibration */
+    /* drawing background */
+    gint c;
+    for (c = 0; c < priv->height / 29; c++) {
+         gdk_pixbuf_copy_area(aud_active_skin->pixmaps[SKIN_PLEDIT].pixbuf,
+                              36, 42, priv->width, 29, obj, 0, c*29);
+    }
+
+    /* drawing knob */
+    skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, ps->pressed ? 61 : 52, 53, 0, y, priv->width, 18);
+
+    ui_skinned_widget_draw(widget, obj, priv->width, priv->height, FALSE);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static void ui_skinned_playlist_slider_set_position(GtkWidget *widget, gint y) {
+    gint pos;
+    Playlist *playlist = playlist_get_active();
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
+
+    y = CLAMP(y, 0, priv->height - 19);
+
+    pos = (y * (playlist_get_length(playlist) - playlistwin_list_get_visible_count())) / (priv->height - 19);
+    playlistwin_set_toprow(pos);
+
+    gtk_widget_queue_draw(widget);
+}
+
+static gboolean ui_skinned_playlist_slider_button_press(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER (widget);
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
+
+    if (event->button != 1 && event->button != 2)
+        return TRUE;
+
+    gint y = event->y;
+    if (event->type == GDK_BUTTON_PRESS) {
+        ps->pressed = TRUE;
+        if ((y >= priv->prev_y && y < priv->prev_y + 18)) {
+            priv->drag_y = y - priv->prev_y;
+        } else if (event->button == 2) {
+            ui_skinned_playlist_slider_set_position(widget, y);
+            priv->drag_y = 0;
+        } else {
+            gint n = playlistwin_list_get_visible_count() / 2;
+            if (y < priv->prev_y)
+                n *= -1;
+            playlistwin_scroll(n);
+        }
+        gtk_widget_queue_draw(widget);
+    }
+    return TRUE;
+}
+
+static gboolean ui_skinned_playlist_slider_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER(widget);
+
+    if (event->button == 1 || event->button == 2) {
+        ps->pressed = FALSE;
+        gtk_widget_queue_draw(widget);
+    }
+    return TRUE;
+}
+
+static gboolean ui_skinned_playlist_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
+    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER(widget);
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
+
+    if (ps->pressed) {
+        gint y = event->y - priv->drag_y;
+        ui_skinned_playlist_slider_set_position(widget, y);
+    }
+    return TRUE;
+}
+
+static void ui_skinned_playlist_slider_redraw(UiSkinnedPlaylistSlider *playlist_slider) {
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider);
+
+    if (priv->resize_height)
+        gtk_widget_set_size_request(GTK_WIDGET(playlist_slider), priv->width, priv->height+priv->resize_height);
+    if (priv->move_x)
+        gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(GTK_WIDGET(playlist_slider))), GTK_WIDGET(playlist_slider),
+                       playlist_slider->x+priv->move_x, playlist_slider->y);
+
+    gtk_widget_queue_draw(GTK_WIDGET(playlist_slider));
+}
+
+void ui_skinned_playlist_slider_move_relative(GtkWidget *widget, gint x) {
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
+    priv->move_x += x;
+}
+
+void ui_skinned_playlist_slider_resize_relative(GtkWidget *widget, gint h) {
+    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
+    priv->resize_height += h;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_playlist_slider.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H
+#define AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_PLAYLIST_SLIDER(obj)          GTK_CHECK_CAST (obj, ui_skinned_playlist_slider_get_type (), UiSkinnedPlaylistSlider)
+#define UI_SKINNED_PLAYLIST_SLIDER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_playlist_slider_get_type (), UiSkinnedPlaylistSliderClass)
+#define UI_SKINNED_IS_PLAYLIST_SLIDER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_playlist_slider_get_type ())
+
+typedef struct _UiSkinnedPlaylistSlider        UiSkinnedPlaylistSlider;
+typedef struct _UiSkinnedPlaylistSliderClass   UiSkinnedPlaylistSliderClass;
+
+struct _UiSkinnedPlaylistSlider {
+    GtkWidget   widget;
+    gboolean    pressed;
+    gint        x, y;
+};
+
+struct _UiSkinnedPlaylistSliderClass {
+    GtkWidgetClass    parent_class;
+    void (* redraw)   (UiSkinnedPlaylistSlider *playlist_slider);
+};
+
+GtkWidget* ui_skinned_playlist_slider_new(GtkWidget *fixed, gint x, gint y, gint h);
+GtkType ui_skinned_playlist_slider_get_type(void);
+void ui_skinned_playlist_slider_move_relative(GtkWidget *widget, gint x);
+void ui_skinned_playlist_slider_resize_relative(GtkWidget *widget, gint h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_playstatus.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,246 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skin.h"
+#include "ui_skinned_playstatus.h"
+#include "main.h"
+
+#define UI_TYPE_SKINNED_PLAYSTATUS           (ui_skinned_playstatus_get_type())
+
+enum {
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+static void ui_skinned_playstatus_class_init         (UiSkinnedPlaystatusClass *klass);
+static void ui_skinned_playstatus_init               (UiSkinnedPlaystatus *playstatus);
+static void ui_skinned_playstatus_destroy            (GtkObject *object);
+static void ui_skinned_playstatus_realize            (GtkWidget *widget);
+static void ui_skinned_playstatus_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_playstatus_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_playstatus_expose         (GtkWidget *widget, GdkEventExpose *event);
+static void ui_skinned_playstatus_toggle_scaled      (UiSkinnedPlaystatus *playstatus);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint playstatus_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_playstatus_get_type() {
+    static GType playstatus_type = 0;
+    if (!playstatus_type) {
+        static const GTypeInfo playstatus_info = {
+            sizeof (UiSkinnedPlaystatusClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_playstatus_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedPlaystatus),
+            0,
+            (GInstanceInitFunc) ui_skinned_playstatus_init,
+        };
+        playstatus_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaystatus_", &playstatus_info, 0);
+    }
+
+    return playstatus_type;
+}
+
+static void ui_skinned_playstatus_class_init(UiSkinnedPlaystatusClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_playstatus_destroy;
+
+    widget_class->realize = ui_skinned_playstatus_realize;
+    widget_class->expose_event = ui_skinned_playstatus_expose;
+    widget_class->size_request = ui_skinned_playstatus_size_request;
+    widget_class->size_allocate = ui_skinned_playstatus_size_allocate;
+
+    klass->scaled = ui_skinned_playstatus_toggle_scaled;
+
+    playstatus_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedPlaystatusClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+static void ui_skinned_playstatus_init(UiSkinnedPlaystatus *playstatus) {
+    playstatus->width = 11;
+    playstatus->height = 9;
+}
+
+GtkWidget* ui_skinned_playstatus_new(GtkWidget *fixed, gint x, gint y) {
+    UiSkinnedPlaystatus *playstatus = g_object_new (ui_skinned_playstatus_get_type (), NULL);
+
+    playstatus->x = x;
+    playstatus->y = y;
+
+    playstatus->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(playstatus), playstatus->x, playstatus->y);
+
+    return GTK_WIDGET(playstatus);
+}
+
+static void ui_skinned_playstatus_destroy(GtkObject *object) {
+    UiSkinnedPlaystatus *playstatus;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (object));
+
+    playstatus = UI_SKINNED_PLAYSTATUS (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_playstatus_realize(GtkWidget *widget) {
+    UiSkinnedPlaystatus *playstatus;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    playstatus = UI_SKINNED_PLAYSTATUS(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_playstatus_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS(widget);
+
+    requisition->width = playstatus->width*(playstatus->scaled ? cfg.scale_factor : 1);
+    requisition->height = playstatus->height*(playstatus->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_skinned_playstatus_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (playstatus->scaled ? cfg.scale_factor : 1);
+    widget->allocation.y *= (playstatus->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    playstatus->x = widget->allocation.x/(playstatus->scaled ? cfg.scale_factor : 1);
+    playstatus->y = widget->allocation.y/(playstatus->scaled ? cfg.scale_factor : 1);
+}
+
+static gboolean ui_skinned_playstatus_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
+    g_return_val_if_fail (playstatus->width > 0 && playstatus->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, playstatus->width, playstatus->height);
+
+    if (playstatus->status == STATUS_STOP && playstatus->buffering == TRUE)
+        playstatus->buffering = FALSE;
+    if (playstatus->status == STATUS_PLAY && playstatus->buffering == TRUE)
+        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 39, 0, 0, 0, 3, playstatus->height);
+    else if (playstatus->status == STATUS_PLAY)
+        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 36, 0, 0, 0, 3, playstatus->height);
+    else
+        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 27, 0, 0, 0, 2, playstatus->height);
+    switch (playstatus->status) {
+    case STATUS_STOP:
+        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 18, 0, 2, 0, 9, playstatus->height);
+        break;
+    case STATUS_PAUSE:
+        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 9, 0, 2, 0, 9, playstatus->height);
+        break;
+    case STATUS_PLAY:
+        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 1, 0, 3, 0, 8, playstatus->height);
+        break;
+    }
+
+    ui_skinned_widget_draw(widget, obj, playstatus->width, playstatus->height, playstatus->scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static void ui_skinned_playstatus_toggle_scaled(UiSkinnedPlaystatus *playstatus) {
+    GtkWidget *widget = GTK_WIDGET (playstatus);
+
+    playstatus->scaled = !playstatus->scaled;
+    gtk_widget_set_size_request(widget, playstatus->width*(playstatus->scaled ? cfg.scale_factor : 1), playstatus->height*(playstatus->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(GTK_WIDGET(playstatus));
+}
+
+void ui_skinned_playstatus_set_status(GtkWidget *widget, PStatus status) {
+    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget));
+    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
+
+    playstatus->status = status;
+    gtk_widget_queue_draw(widget);
+}
+
+void ui_skinned_playstatus_set_buffering(GtkWidget *widget, gboolean status) {
+    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget));
+    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
+
+    playstatus->buffering = status;
+    gtk_widget_queue_draw(widget);
+}
+
+void ui_skinned_playstatus_set_size(GtkWidget *widget, gint width, gint height) {
+    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget));
+    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
+
+    playstatus->width = width;
+    playstatus->height = height;
+
+    gtk_widget_set_size_request(widget, width*(playstatus->scaled ? cfg.scale_factor : 1), height*(playstatus->scaled ? cfg.scale_factor : 1));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_playstatus.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,71 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_PLAYSTATUS_H
+#define AUDACIOUS_UI_SKINNED_PLAYSTATUS_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_PLAYSTATUS(obj)          GTK_CHECK_CAST (obj, ui_skinned_playstatus_get_type (), UiSkinnedPlaystatus)
+#define UI_SKINNED_PLAYSTATUS_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_playstatus_get_type (), UiSkinnedPlaystatusClass)
+#define UI_SKINNED_IS_PLAYSTATUS(obj)       GTK_CHECK_TYPE (obj, ui_skinned_playstatus_get_type ())
+
+typedef struct _UiSkinnedPlaystatus        UiSkinnedPlaystatus;
+typedef struct _UiSkinnedPlaystatusClass   UiSkinnedPlaystatusClass;
+
+typedef enum {
+    STATUS_STOP, STATUS_PAUSE, STATUS_PLAY
+} PStatus;
+
+struct _UiSkinnedPlaystatus {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gboolean         scaled;
+    PStatus          status;
+    gboolean         buffering;
+};
+
+struct _UiSkinnedPlaystatusClass {
+    GtkWidgetClass          parent_class;
+    void (* scaled)        (UiSkinnedPlaystatus *menurow);
+};
+
+GtkWidget* ui_skinned_playstatus_new (GtkWidget *fixed, gint x, gint y);
+GtkType ui_skinned_playstatus_get_type(void);
+void ui_skinned_playstatus_set_status(GtkWidget *widget, PStatus status);
+void ui_skinned_playstatus_set_buffering(GtkWidget *widget, gboolean status);
+void ui_skinned_playstatus_set_size(GtkWidget *widget, gint width, gint height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_PLAYSTATUS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_textbox.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,871 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skinned_textbox.h"
+
+#include <string.h>
+
+#include "main.h"
+#include "util.h"
+#include "strings.h"
+
+#define UI_SKINNED_TEXTBOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_textbox_get_type(), UiSkinnedTextboxPrivate))
+typedef struct _UiSkinnedTextboxPrivate UiSkinnedTextboxPrivate;
+
+#define TEXTBOX_SCROLL_SMOOTH_TIMEOUT  30
+#define TEXTBOX_SCROLL_WAIT            80
+
+enum {
+    CLICKED,
+    DOUBLE_CLICKED,
+    RIGHT_CLICKED,
+    DOUBLED,
+    REDRAW,
+    LAST_SIGNAL
+};
+
+struct _UiSkinnedTextboxPrivate {
+    SkinPixmapId     skin_index;
+    gboolean         scaled;
+    gboolean         scroll_back;
+    gint             nominal_y, nominal_height;
+    gint             scroll_timeout;
+    gint             font_ascent, font_descent;
+    PangoFontDescription *font;
+    gchar            *fontname;
+    gchar            *pixbuf_text;
+    gint             skin_id;
+    gint             drag_x, drag_off, offset;
+    gboolean         is_scrollable, is_dragging;
+    gint             pixbuf_width;
+    GdkPixbuf        *pixbuf;
+    gboolean         scroll_allowed, scroll_enabled;
+    gint             scroll_dummy;
+    gint             move_x, move_y;
+};
+
+static void ui_skinned_textbox_class_init         (UiSkinnedTextboxClass *klass);
+static void ui_skinned_textbox_init               (UiSkinnedTextbox *textbox);
+static void ui_skinned_textbox_destroy            (GtkObject *object);
+static void ui_skinned_textbox_realize            (GtkWidget *widget);
+static void ui_skinned_textbox_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_skinned_textbox_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_skinned_textbox_expose         (GtkWidget *widget, GdkEventExpose *event);
+static gboolean ui_skinned_textbox_button_press   (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_textbox_button_release (GtkWidget *widget, GdkEventButton *event);
+static gboolean ui_skinned_textbox_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
+static void ui_skinned_textbox_toggle_scaled      (UiSkinnedTextbox *textbox);
+static void ui_skinned_textbox_redraw             (UiSkinnedTextbox *textbox);
+static gboolean ui_skinned_textbox_should_scroll  (UiSkinnedTextbox *textbox);
+static void textbox_generate_xfont_pixmap         (UiSkinnedTextbox *textbox, const gchar *pixmaptext);
+static gboolean textbox_scroll                    (gpointer data);
+static void textbox_generate_pixmap               (UiSkinnedTextbox *textbox);
+static void textbox_handle_special_char           (gchar *c, gint * x, gint * y);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint textbox_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_skinned_textbox_get_type() {
+    static GType textbox_type = 0;
+    if (!textbox_type) {
+        static const GTypeInfo textbox_info = {
+            sizeof (UiSkinnedTextboxClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_skinned_textbox_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSkinnedTextbox),
+            0,
+            (GInstanceInitFunc) ui_skinned_textbox_init,
+        };
+        textbox_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedTextbox_", &textbox_info, 0);
+    }
+
+    return textbox_type;
+}
+
+static void ui_skinned_textbox_class_init(UiSkinnedTextboxClass *klass) {
+    GObjectClass *gobject_class;
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    gobject_class = G_OBJECT_CLASS(klass);
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_skinned_textbox_destroy;
+
+    widget_class->realize = ui_skinned_textbox_realize;
+    widget_class->expose_event = ui_skinned_textbox_expose;
+    widget_class->size_request = ui_skinned_textbox_size_request;
+    widget_class->size_allocate = ui_skinned_textbox_size_allocate;
+    widget_class->button_press_event = ui_skinned_textbox_button_press;
+    widget_class->button_release_event = ui_skinned_textbox_button_release;
+    widget_class->motion_notify_event = ui_skinned_textbox_motion_notify;
+
+    klass->clicked = NULL;
+    klass->double_clicked = NULL;
+    klass->right_clicked = NULL;
+    klass->scaled = ui_skinned_textbox_toggle_scaled;
+    klass->redraw = ui_skinned_textbox_redraw;
+
+    textbox_signals[CLICKED] = 
+        g_signal_new ("clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, clicked), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    textbox_signals[DOUBLE_CLICKED] = 
+        g_signal_new ("double-clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, double_clicked), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    textbox_signals[RIGHT_CLICKED] = 
+        g_signal_new ("right-clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, right_clicked), NULL, NULL,
+                      gtk_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+    textbox_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    textbox_signals[REDRAW] = 
+        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, redraw), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    g_type_class_add_private (gobject_class, sizeof (UiSkinnedTextboxPrivate));
+}
+
+static void ui_skinned_textbox_init(UiSkinnedTextbox *textbox) {
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+    priv->move_x = 0;
+    priv->move_y = 0;
+}
+
+GtkWidget* ui_skinned_textbox_new(GtkWidget *fixed, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si) {
+    UiSkinnedTextbox *textbox = g_object_new (ui_skinned_textbox_get_type (), NULL);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    textbox->height = aud_active_skin->properties.textbox_bitmap_font_height;
+    textbox->x = x;
+    textbox->y = y;
+    textbox->text = g_strdup("");
+    textbox->width = w;
+    priv->scroll_allowed = allow_scroll;
+    priv->scroll_enabled = TRUE;
+    priv->skin_index = si;
+    priv->nominal_y = y;
+    priv->nominal_height = textbox->height;
+    priv->scroll_timeout = 0;
+    priv->scroll_dummy = 0;
+
+    priv->scaled = FALSE;
+
+    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(textbox), textbox->x, textbox->y);
+
+    return GTK_WIDGET(textbox);
+}
+
+static void ui_skinned_textbox_destroy(GtkObject *object) {
+    UiSkinnedTextbox *textbox;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_SKINNED_IS_TEXTBOX (object));
+
+    textbox = UI_SKINNED_TEXTBOX (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_skinned_textbox_realize(GtkWidget *widget) {
+    UiSkinnedTextbox *textbox;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_SKINNED_IS_TEXTBOX(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    textbox = UI_SKINNED_TEXTBOX(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_OUTPUT;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+                             GDK_POINTER_MOTION_HINT_MASK;
+    attributes.visual = gtk_widget_get_visual(widget);
+    attributes.colormap = gtk_widget_get_colormap(widget);
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+
+    gdk_window_set_user_data(widget->window, widget);
+}
+
+static void ui_skinned_textbox_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    requisition->width = textbox->width*(priv->scaled ? cfg.scale_factor : 1);
+    requisition->height = textbox->height*(priv->scaled ?  cfg.scale_factor : 1 );
+}
+
+static void ui_skinned_textbox_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (priv->scaled ? cfg.scale_factor : 1);
+    widget->allocation.y *= (priv->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+
+    if (textbox->x + priv->move_x - widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1) <3);
+        priv->move_x = 0;
+    if (textbox->y + priv->move_y - widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1) <3);
+        priv->move_y = 0;
+    textbox->x = widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1);
+    textbox->y = widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1);
+
+    if (textbox->width - (guint) (widget->allocation.width / (priv->scaled ? cfg.scale_factor : 1)) > 2) {
+            textbox->width = (guint) (widget->allocation.width / (priv->scaled ? cfg.scale_factor : 1));
+            if (priv->pixbuf_text) g_free(priv->pixbuf_text);
+            priv->pixbuf_text = NULL;
+            priv->offset = 0;
+            gtk_widget_set_size_request(widget, textbox->width, textbox->height);
+            gtk_widget_queue_draw(GTK_WIDGET(textbox));
+    }
+}
+
+static gboolean ui_skinned_textbox_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+    g_return_val_if_fail (textbox->width > 0 && textbox->height > 0, FALSE);
+
+    GdkPixbuf *obj = NULL;
+    gint cw;
+
+    if (textbox->text && (!priv->pixbuf_text || strcmp(textbox->text, priv->pixbuf_text)))
+        textbox_generate_pixmap(textbox);
+
+    if (priv->pixbuf) {
+        if (skin_get_id() != priv->skin_id) {
+            priv->skin_id = skin_get_id();
+            textbox_generate_pixmap(textbox);
+        }
+        obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, textbox->width, textbox->height);
+
+        if (cfg.twoway_scroll) { // twoway scroll
+            cw = priv->pixbuf_width - priv->offset;
+            if (cw > textbox->width)
+                cw = textbox->width;
+            gdk_pixbuf_copy_area(priv->pixbuf, priv->offset, 0, cw, textbox->height, obj, 0, 0);
+            if (cw < textbox->width)
+                gdk_pixbuf_copy_area(priv->pixbuf, 0, 0, textbox->width - cw, textbox->height,
+                                     obj, textbox->width - cw, textbox->height);
+        } else { // oneway scroll
+            int cw1, cw2;
+
+            if (priv->offset >= priv->pixbuf_width)
+                priv->offset = 0;
+
+            if (priv->pixbuf_width - priv->offset > textbox->width) { // case1
+                cw1 = textbox->width;
+                gdk_pixbuf_copy_area(priv->pixbuf, priv->offset, 0, cw1, textbox->height,
+                                     obj, 0, 0);
+            } else { // case 2
+                cw1 = priv->pixbuf_width - priv->offset;
+                gdk_pixbuf_copy_area(priv->pixbuf, priv->offset, 0, cw1, textbox->height, obj, 0, 0);
+                cw2 = textbox->width - cw1;
+                gdk_pixbuf_copy_area(priv->pixbuf, 0, 0, cw2, textbox->height, obj, cw1, 0);
+            }
+        }
+
+        ui_skinned_widget_draw(widget, obj, textbox->width, textbox->height, priv->scaled);
+
+        g_object_unref(obj);
+    }
+
+    return FALSE;
+}
+
+static gboolean ui_skinned_textbox_button_press(GtkWidget *widget, GdkEventButton *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    if (event->type == GDK_BUTTON_PRESS) {
+        textbox = UI_SKINNED_TEXTBOX(widget);
+        if (event->button == 3 && !g_signal_has_handler_pending(widget, textbox_signals[RIGHT_CLICKED], 0, TRUE))
+            return FALSE;
+        else if (event->button == 1) {
+            if (priv->scroll_allowed) {
+                if ((priv->pixbuf_width > textbox->width) && priv->is_scrollable) {
+                    priv->is_dragging = TRUE;
+                    priv->drag_off = priv->offset;
+                    priv->drag_x = event->x;
+                }
+            } else
+                g_signal_emit(widget, textbox_signals[CLICKED], 0);
+
+        } else if (event->button == 3) {
+            g_signal_emit(widget, textbox_signals[RIGHT_CLICKED], 0, event);
+        } else
+            priv->is_dragging = FALSE;
+    } else if (event->type == GDK_2BUTTON_PRESS) {
+        if (event->button == 1) {
+           if (g_signal_has_handler_pending(widget, textbox_signals[DOUBLE_CLICKED], 0, TRUE))
+               g_signal_emit(widget, textbox_signals[DOUBLE_CLICKED], 0);
+           else
+               return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_textbox_button_release(GtkWidget *widget, GdkEventButton *event) {
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(widget);
+
+    if (event->button == 1) {
+        priv->is_dragging = FALSE;
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_textbox_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(widget);
+
+    if (priv->is_dragging) {
+        if (priv->scroll_allowed &&
+            priv->pixbuf_width > textbox->width) {
+            priv->offset = priv->drag_off - (event->x - priv->drag_x);
+
+            while (priv->offset < 0)
+                priv->offset = 0;
+
+            while (priv->offset > (priv->pixbuf_width - textbox->width))
+                priv->offset = (priv->pixbuf_width - textbox->width);
+
+            gtk_widget_queue_draw(widget);
+        }
+    }
+
+  return TRUE;
+}
+
+static void ui_skinned_textbox_toggle_scaled(UiSkinnedTextbox *textbox) {
+    GtkWidget *widget = GTK_WIDGET (textbox);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    priv->scaled = !priv->scaled;
+
+    gtk_widget_set_size_request(widget, textbox->width*(priv->scaled ? cfg.scale_factor : 1 ), 
+    textbox->height*(priv->scaled ? cfg.scale_factor : 1 ));
+
+    gtk_widget_queue_draw(GTK_WIDGET(textbox));
+}
+
+static void ui_skinned_textbox_redraw(UiSkinnedTextbox *textbox) {
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    if (priv->move_x || priv->move_y)
+        gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(GTK_WIDGET(textbox))), GTK_WIDGET(textbox),
+                       textbox->x+priv->move_x, textbox->y+priv->move_y);
+
+    gtk_widget_queue_draw(GTK_WIDGET(textbox));
+}
+
+static gboolean ui_skinned_textbox_should_scroll(UiSkinnedTextbox *textbox) {
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    if (!priv->scroll_allowed)
+        return FALSE;
+
+    if (priv->font) {
+        gint width;
+        text_get_extents(priv->fontname, textbox->text, &width, NULL, NULL, NULL);
+
+        if (width <= textbox->width)
+            return FALSE;
+        else
+            return TRUE;
+    }
+
+    if (g_utf8_strlen(textbox->text, -1) * aud_active_skin->properties.textbox_bitmap_font_width > textbox->width)
+        return TRUE;
+
+    return FALSE;
+}
+
+void ui_skinned_textbox_set_xfont(GtkWidget *widget, gboolean use_xfont, const gchar * fontname) {
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    gint ascent, descent;
+
+    g_return_if_fail(textbox != NULL);
+
+    if (priv->font) {
+        pango_font_description_free(priv->font);
+        priv->font = NULL;
+    }
+
+    textbox->y = priv->nominal_y;
+    textbox->height = priv->nominal_height;
+
+    /* Make sure the pixmap is regenerated */
+    if (priv->pixbuf_text) {
+        g_free(priv->pixbuf_text);
+        priv->pixbuf_text = NULL;
+    }
+
+    if (!use_xfont || strlen(fontname) == 0)
+        return;
+
+    priv->font = pango_font_description_from_string(fontname);
+    priv->fontname = g_strdup(fontname);
+
+    text_get_extents(fontname,
+                     "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ",
+                     NULL, NULL, &ascent, &descent);
+    priv->font_ascent = ascent;
+    priv->font_descent = descent;
+
+
+    if (priv->font == NULL)
+        return;
+
+    textbox->height = priv->font_ascent;
+    if (textbox->height > priv->nominal_height)
+        textbox->y -= (textbox->height - priv->nominal_height) / 2;
+    else
+        textbox->height = priv->nominal_height;
+}
+
+void ui_skinned_textbox_set_text(GtkWidget *widget, const gchar *text) {
+    g_return_if_fail(text != NULL);
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    if (!strcmp(textbox->text, text))
+         return;
+    if (textbox->text)
+        g_free(textbox->text);
+
+    textbox->text = str_assert_utf8(text);
+    priv->scroll_back = FALSE;
+    gtk_widget_queue_draw(GTK_WIDGET(textbox));
+}
+
+static void textbox_generate_xfont_pixmap(UiSkinnedTextbox *textbox, const gchar *pixmaptext) {
+    /* FIXME: should operate directly on priv->pixbuf, it shouldn't use pixmap */
+    gint length, i;
+    GdkGC *gc, *maskgc;
+    GdkColor *c, pattern;
+    GdkBitmap *mask;
+    PangoLayout *layout;
+    gint width;
+    GdkPixmap *pixmap;
+
+    g_return_if_fail(textbox != NULL);
+    g_return_if_fail(pixmaptext != NULL);
+    g_return_if_fail(textbox->height > 0);
+
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    length = g_utf8_strlen(pixmaptext, -1);
+
+    text_get_extents(priv->fontname, pixmaptext, &width, NULL, NULL, NULL);
+
+    priv->pixbuf_width = MAX(width, textbox->width);
+    pixmap = gdk_pixmap_new(mainwin->window, priv->pixbuf_width,
+                                   textbox->height,
+                                   gdk_rgb_get_visual()->depth);
+    gc = gdk_gc_new(pixmap);
+    c = skin_get_color(aud_active_skin, SKIN_TEXTBG);
+    for (i = 0; i < textbox->height; i++) {
+        gdk_gc_set_foreground(gc, &c[6 * i / textbox->height]);
+        gdk_draw_line(pixmap, gc, 0, i, priv->pixbuf_width, i);
+    }
+
+    mask = gdk_pixmap_new(mainwin->window, priv->pixbuf_width, textbox->height, 1);
+    maskgc = gdk_gc_new(mask);
+    pattern.pixel = 0;
+    gdk_gc_set_foreground(maskgc, &pattern);
+
+    gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, priv->pixbuf_width, textbox->height);
+    pattern.pixel = 1;
+    gdk_gc_set_foreground(maskgc, &pattern);
+
+    gdk_gc_set_foreground(gc, skin_get_color(aud_active_skin, SKIN_TEXTFG));
+
+    layout = gtk_widget_create_pango_layout(mainwin, pixmaptext);
+    pango_layout_set_font_description(layout, priv->font);
+
+    gdk_draw_layout(pixmap, gc, 0, (priv->font_descent / 2), layout);
+    g_object_unref(layout);
+
+    g_object_unref(maskgc);
+
+    gdk_gc_set_clip_mask(gc, mask);
+    c = skin_get_color(aud_active_skin, SKIN_TEXTFG);
+    for (i = 0; i < textbox->height; i++) {
+        gdk_gc_set_foreground(gc, &c[6 * i / textbox->height]);
+        gdk_draw_line(pixmap, gc, 0, i, priv->pixbuf_width, i);
+    }
+    priv->pixbuf = gdk_pixbuf_get_from_drawable(NULL, pixmap, gdk_colormap_get_system(), 0, 0, 0, 0, priv->pixbuf_width, textbox->height);
+    g_object_unref(mask);
+    g_object_unref(gc);
+}
+
+static gboolean textbox_scroll(gpointer data) {
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(data);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    if (!priv->is_dragging) {
+        if (priv->scroll_dummy < TEXTBOX_SCROLL_WAIT)
+            priv->scroll_dummy++;
+        else {
+            if(cfg.twoway_scroll) {
+                if (priv->scroll_back)
+                    priv->offset -= 1;
+                else
+                    priv->offset += 1;
+
+                if (priv->offset >= (priv->pixbuf_width - textbox->width)) {
+                    priv->scroll_back = TRUE;
+                    priv->scroll_dummy = 0;
+                    priv->offset = priv->pixbuf_width - textbox->width;
+                }
+                if (priv->offset <= 0) {
+                    priv->scroll_back = FALSE;
+                    priv->scroll_dummy = 0;
+                    priv->offset = 0;
+                }
+            }
+            else { // oneway scroll
+                priv->scroll_back = FALSE;
+                priv->offset += 1;
+            }
+            gtk_widget_queue_draw(GTK_WIDGET(textbox));
+        }
+    }
+    return TRUE;
+}
+
+static void textbox_generate_pixmap(UiSkinnedTextbox *textbox) {
+    gint length, i, x, y, wl;
+    gchar *pixmaptext;
+    gchar *tmp, *stxt;
+
+    g_return_if_fail(textbox != NULL);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    if (priv->pixbuf) {
+        g_object_unref(priv->pixbuf);
+        priv->pixbuf = NULL;
+    }
+
+    /*
+     * Don't reset the offset if only text after the last '(' has
+     * changed.  This is a hack to avoid visual noice on vbr files
+     * where we guess the length.
+     */
+    if (!(priv->pixbuf_text && strrchr(textbox->text, '(') &&
+          !strncmp(priv->pixbuf_text, textbox->text,
+                   strrchr(textbox->text, '(') - textbox->text)))
+        priv->offset = 0;
+
+    g_free(priv->pixbuf_text);
+    priv->pixbuf_text = g_strdup(textbox->text);
+
+    /*
+     * wl is the number of (partial) letters visible. Only makes
+     * sense when using skinned font.
+     */
+    wl = textbox->width / 5;
+    if (wl * 5 != textbox->width)
+        wl++;
+
+    length = g_utf8_strlen(textbox->text, -1);
+
+    priv->is_scrollable = FALSE;
+
+    priv->is_scrollable = ui_skinned_textbox_should_scroll(textbox);
+
+    if (priv->is_scrollable) {
+        if(!cfg.twoway_scroll) {
+            pixmaptext = g_strdup_printf("%s *** ", priv->pixbuf_text);
+            length += 5;
+        } else
+            pixmaptext = g_strdup(priv->pixbuf_text);
+    } else
+    if (!priv->font && length <= wl) {
+        gint pad = wl - length;
+        gchar *padchars = g_strnfill(pad, ' ');
+
+        pixmaptext = g_strconcat(priv->pixbuf_text, padchars, NULL);
+        g_free(padchars);
+        length += pad;
+    } else
+        pixmaptext = g_strdup(priv->pixbuf_text);
+
+    if (priv->is_scrollable) {
+        if (priv->scroll_enabled && !priv->scroll_timeout) {
+            gint tag;
+            tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT;
+            priv->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
+        }
+    } else {
+        if (priv->scroll_timeout) {
+            g_source_remove(priv->scroll_timeout);
+            priv->scroll_timeout = 0;
+        }
+        priv->offset = 0;
+    }
+
+    if (priv->font) {
+        textbox_generate_xfont_pixmap(textbox, pixmaptext);
+        g_free(pixmaptext);
+        return;
+    }
+
+    priv->pixbuf_width = length * aud_active_skin->properties.textbox_bitmap_font_width;
+    priv->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
+                                  priv->pixbuf_width, aud_active_skin->properties.textbox_bitmap_font_height);
+
+    for (tmp = stxt = g_utf8_strup(pixmaptext, -1), i = 0;
+         tmp != NULL && i < length; i++, tmp = g_utf8_next_char(tmp)) {
+        gchar c = *tmp;
+        x = y = -1;
+        if (c >= 'A' && c <= 'Z') {
+            x = aud_active_skin->properties.textbox_bitmap_font_width * (c - 'A');
+            y = 0;
+        }
+        else if (c >= '0' && c <= '9') {
+            x = aud_active_skin->properties.textbox_bitmap_font_width * (c - '0');
+            y = aud_active_skin->properties.textbox_bitmap_font_height;
+        }
+        else
+            textbox_handle_special_char(tmp, &x, &y);
+
+        skin_draw_pixbuf(GTK_WIDGET(textbox), aud_active_skin,
+                         priv->pixbuf, priv->skin_index,
+                         x, y, i * aud_active_skin->properties.textbox_bitmap_font_width, 0,
+                         aud_active_skin->properties.textbox_bitmap_font_width, 
+                         aud_active_skin->properties.textbox_bitmap_font_height);
+    }
+    g_free(stxt);
+    g_free(pixmaptext);
+}
+
+void ui_skinned_textbox_set_scroll(GtkWidget *widget, gboolean scroll) {
+    g_return_if_fail(widget != NULL);
+    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
+
+    priv->scroll_enabled = scroll;
+    if (priv->scroll_enabled && priv->is_scrollable && priv->scroll_allowed) {
+        gint tag;
+        tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT;
+        if (priv->scroll_timeout) {
+            g_source_remove(priv->scroll_timeout);
+            priv->scroll_timeout = 0;
+        }
+        priv->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
+
+    } else {
+
+        if (priv->scroll_timeout) {
+            g_source_remove(priv->scroll_timeout);
+            priv->scroll_timeout = 0;
+        }
+
+        priv->offset = 0;
+        gtk_widget_queue_draw(GTK_WIDGET(textbox));
+    }
+}
+
+static void textbox_handle_special_char(gchar *c, gint * x, gint * y) {
+    gint tx, ty;
+
+    switch (*c) {
+    case '"':
+        tx = 26;
+        ty = 0;
+        break;
+    case '\r':
+        tx = 10;
+        ty = 1;
+        break;
+    case ':':
+    case ';':
+        tx = 12;
+        ty = 1;
+        break;
+    case '(':
+        tx = 13;
+        ty = 1;
+        break;
+    case ')':
+        tx = 14;
+        ty = 1;
+        break;
+    case '-':
+        tx = 15;
+        ty = 1;
+        break;
+    case '`':
+    case '\'':
+        tx = 16;
+        ty = 1;
+        break;
+    case '!':
+        tx = 17;
+        ty = 1;
+        break;
+    case '_':
+        tx = 18;
+        ty = 1;
+        break;
+    case '+':
+        tx = 19;
+        ty = 1;
+        break;
+    case '\\':
+        tx = 20;
+        ty = 1;
+        break;
+    case '/':
+        tx = 21;
+        ty = 1;
+        break;
+    case '[':
+        tx = 22;
+        ty = 1;
+        break;
+    case ']':
+        tx = 23;
+        ty = 1;
+        break;
+    case '^':
+        tx = 24;
+        ty = 1;
+        break;
+    case '&':
+        tx = 25;
+        ty = 1;
+        break;
+    case '%':
+        tx = 26;
+        ty = 1;
+        break;
+    case '.':
+    case ',':
+        tx = 27;
+        ty = 1;
+        break;
+    case '=':
+        tx = 28;
+        ty = 1;
+        break;
+    case '$':
+        tx = 29;
+        ty = 1;
+        break;
+    case '#':
+        tx = 30;
+        ty = 1;
+        break;
+    case '?':
+        tx = 3;
+        ty = 2;
+        break;
+    case '*':
+        tx = 4;
+        ty = 2;
+        break;
+    default:
+        tx = 29;
+        ty = 0;
+        break;
+    }
+
+    const gchar *change[] = {"Ą", "A", "Ę", "E", "Ć", "C", "Ł", "L", "Ó", "O", "Ś", "S", "Ż", "Z", "Ź", "Z",
+                             "Ń", "N", "Ü", "U", NULL};
+    int i;
+    for (i = 0; change[i]; i+=2) {
+         if (!strncmp(c, change[i], strlen(change[i]))) {
+             tx = (*change[i+1] - 'A');
+             break;
+         }
+    }
+
+    /* those are commonly included into skins */
+    if (!strncmp(c, "Å", strlen("Å"))) {
+        tx = 0;
+        ty = 2;
+    } else if (!strncmp(c, "Ö", strlen("Ö"))) {
+        tx = 1;
+        ty = 2;
+    } else if (!strncmp(c, "Ä", strlen("Ä"))) {
+        tx = 2;
+        ty = 2;
+    }
+
+    *x = tx * aud_active_skin->properties.textbox_bitmap_font_width;
+    *y = ty * aud_active_skin->properties.textbox_bitmap_font_height;
+}
+
+void ui_skinned_textbox_move_relative(GtkWidget *widget, gint x, gint y) {
+    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(widget);
+    priv->move_x += x;
+    priv->move_y += y;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_textbox.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,71 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007 Tomasz Moń
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_TEXTBOX_H
+#define AUDACIOUS_UI_SKINNED_TEXTBOX_H
+
+#include <gtk/gtk.h>
+#include "ui_skin.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SKINNED_TEXTBOX(obj)          GTK_CHECK_CAST (obj, ui_skinned_textbox_get_type (), UiSkinnedTextbox)
+#define UI_SKINNED_TEXTBOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_textbox_get_type (), UiSkinnedTextboxClass)
+#define UI_SKINNED_IS_TEXTBOX(obj)       GTK_CHECK_TYPE (obj, ui_skinned_textbox_get_type ())
+
+typedef struct _UiSkinnedTextbox        UiSkinnedTextbox;
+typedef struct _UiSkinnedTextboxClass   UiSkinnedTextboxClass;
+
+struct _UiSkinnedTextbox {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gchar            *text;
+};
+
+struct _UiSkinnedTextboxClass {
+    GtkWidgetClass          parent_class;
+    void (* clicked)        (UiSkinnedTextbox *textbox);
+    void (* double_clicked) (UiSkinnedTextbox *textbox);
+    void (* right_clicked)  (UiSkinnedTextbox *textbox);
+    void (* scaled)         (UiSkinnedTextbox *textbox);
+    void (* redraw)         (UiSkinnedTextbox *textbox);
+};
+
+GtkWidget* ui_skinned_textbox_new (GtkWidget *fixed, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si);
+GtkType ui_skinned_textbox_get_type(void);
+void ui_skinned_textbox_set_xfont(GtkWidget *widget, gboolean use_xfont, const gchar * fontname);
+void ui_skinned_textbox_set_text(GtkWidget *widget, const gchar *text);
+void ui_skinned_textbox_set_scroll(GtkWidget *widget, gboolean scroll);
+void ui_skinned_textbox_move_relative(GtkWidget *widget, gint x, gint y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SKINNED_TEXTBOX_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_window.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,286 @@
+/*
+ * Audacious: A cross-platform multimedia player
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "platform/smartinclude.h"
+#include "ui_skin.h"
+
+#include <gtk/gtkmain.h>
+#include <glib-object.h>
+#include <glib/gmacros.h>
+#include <gtk/gtkmarshal.h>
+#include <gtk/gtkwindow.h>
+#include <string.h>
+
+#include "main.h"
+#include "ui_dock.h"
+#include "ui_skinned_window.h"
+#include "ui_playlist.h"
+
+static void ui_skinned_window_class_init(SkinnedWindowClass *klass);
+static void ui_skinned_window_init(GtkWidget *widget);
+static GtkWindowClass *parent = NULL;
+
+GType
+ui_skinned_window_get_type(void)
+{
+  static GType window_type = 0;
+
+  if (!window_type)
+    {
+      static const GTypeInfo window_info =
+      {
+        sizeof (SkinnedWindowClass),
+        NULL,           /* base_init */
+        NULL,           /* base_finalize */
+        (GClassInitFunc) ui_skinned_window_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data */
+        sizeof (SkinnedWindow),
+        0,              /* n_preallocs */
+        (GInstanceInitFunc) ui_skinned_window_init
+      };
+
+      window_type =
+        g_type_register_static (GTK_TYPE_WINDOW, "SkinnedWindow_",
+                                &window_info, 0);
+    }
+
+  return window_type;
+}
+
+static void
+ui_skinned_window_map(GtkWidget *widget)
+{
+    (* GTK_WIDGET_CLASS (parent)->map) (widget);
+
+    SkinnedWindow *window = SKINNED_WINDOW(widget);
+    if (window->type == WINDOW_MAIN)
+        gtk_widget_shape_combine_mask(widget, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
+    else if (window->type == WINDOW_EQ)
+        gtk_widget_shape_combine_mask(widget, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
+
+    gtk_window_set_keep_above(GTK_WINDOW(widget), cfg.always_on_top);
+}
+
+static gboolean
+ui_skinned_window_motion_notify_event(GtkWidget *widget,
+                                      GdkEventMotion *event)
+{
+    if (dock_is_moving(GTK_WINDOW(widget)))
+        dock_move_motion(GTK_WINDOW(widget), event);
+
+    return FALSE;
+}
+
+static gboolean ui_skinned_window_focus_in(GtkWidget *widget, GdkEventFocus *focus) {
+    gboolean val = GTK_WIDGET_CLASS (parent)->focus_in_event (widget, focus);
+    gtk_widget_queue_draw(widget);
+    return val;
+}
+
+static gboolean ui_skinned_window_focus_out(GtkWidget *widget, GdkEventFocus *focus) {
+    gboolean val = GTK_WIDGET_CLASS (parent)->focus_out_event (widget, focus);
+    gtk_widget_queue_draw(widget);
+    return val;
+}
+
+static gboolean ui_skinned_window_button_press(GtkWidget *widget, GdkEventButton *event) {
+    if (event->button == 1 && event->type == GDK_BUTTON_PRESS &&
+        (cfg.easy_move || cfg.equalizer_shaded || (event->y / cfg.scale_factor) < 14)) {
+         dock_move_press(get_dock_window_list(), GTK_WINDOW(widget),
+                         event, SKINNED_WINDOW(widget)->type == WINDOW_MAIN ? TRUE : FALSE);
+    }
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_window_button_release(GtkWidget *widget, GdkEventButton *event) {
+    if (dock_is_moving(GTK_WINDOW(widget)))
+       dock_move_release(GTK_WINDOW(widget));
+
+    return TRUE;
+}
+
+static gboolean ui_skinned_window_expose(GtkWidget *widget, GdkEventExpose *event) {
+    SkinnedWindow *window = SKINNED_WINDOW(widget);
+
+    GdkPixbuf *obj = NULL;
+
+    gint width = 0, height = 0;
+    switch (window->type) {
+        case WINDOW_MAIN:
+            width = aud_active_skin->properties.mainwin_width;
+            height = aud_active_skin->properties.mainwin_height;
+            break;
+        case WINDOW_EQ:
+            width = 275 * (cfg.scaled ? cfg.scale_factor : 1);
+            height = 116 * (cfg.scaled ? cfg.scale_factor : 1) ;
+            break;
+        case WINDOW_PLAYLIST:
+            width = playlistwin_get_width();
+            height = cfg.playlist_height;
+            break;
+        default:
+            return FALSE;
+    }
+    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+
+    gboolean focus = gtk_window_has_toplevel_focus(GTK_WINDOW(widget));
+
+    switch (window->type) {
+        case WINDOW_MAIN:
+            skin_draw_pixbuf(widget, aud_active_skin, obj,SKIN_MAIN, 0, 0, 0, 0, width, height);
+            skin_draw_mainwin_titlebar(aud_active_skin, obj, cfg.player_shaded, focus || !cfg.dim_titlebar);
+            break;
+        case WINDOW_EQ:
+            skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQMAIN, 0, 0, 0, 0, width, height);
+            if (focus || !cfg.dim_titlebar) {
+                if (!cfg.equalizer_shaded)
+                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQMAIN, 0, 134, 0, 0, width, 14);
+                else
+                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQ_EX, 0, 0, 0, 0, width, 14);
+            } else {
+                if (!cfg.equalizer_shaded)
+                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQMAIN, 0, 149, 0, 0, width, 14);
+                else
+                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQ_EX, 0, 15, 0, 0, width, 14);
+            }
+            break;
+        case WINDOW_PLAYLIST:
+            focus |= !cfg.dim_titlebar;
+            if (cfg.playlist_shaded) {
+                skin_draw_playlistwin_shaded(aud_active_skin, obj, width, focus);
+            } else {
+                skin_draw_playlistwin_frame(aud_active_skin, obj, width, cfg.playlist_height, focus);
+            }
+            break;
+    }
+
+    ui_skinned_widget_draw(GTK_WIDGET(window), obj, width, height,
+                           window->type != WINDOW_PLAYLIST && cfg.scaled);
+
+    g_object_unref(obj);
+
+    return FALSE;
+}
+
+static void
+ui_skinned_window_class_init(SkinnedWindowClass *klass)
+{
+    GtkWidgetClass *widget_class;
+
+    widget_class = (GtkWidgetClass*) klass;
+
+    parent = gtk_type_class(gtk_window_get_type());
+
+    widget_class->motion_notify_event = ui_skinned_window_motion_notify_event;
+    widget_class->expose_event = ui_skinned_window_expose;
+    widget_class->focus_in_event = ui_skinned_window_focus_in;
+    widget_class->focus_out_event = ui_skinned_window_focus_out;
+    widget_class->button_press_event = ui_skinned_window_button_press;
+    widget_class->button_release_event = ui_skinned_window_button_release;
+    widget_class->map = ui_skinned_window_map;
+}
+
+void
+ui_skinned_window_hide(SkinnedWindow *window)
+{
+    g_return_if_fail(SKINNED_CHECK_WINDOW(window));
+
+    gtk_window_get_position(GTK_WINDOW(window), &window->x, &window->y);
+    gtk_widget_hide(GTK_WIDGET(window));
+}
+
+void
+ui_skinned_window_show(SkinnedWindow *window)
+{
+    g_return_if_fail(SKINNED_CHECK_WINDOW(window));
+
+    gtk_window_move(GTK_WINDOW(window), window->x, window->y);
+    gtk_widget_show_all(GTK_WIDGET(window));
+}
+
+static void
+ui_skinned_window_init(GtkWidget *widget)
+{
+    SkinnedWindow *window;
+    window = SKINNED_WINDOW(widget);
+    window->x = -1;
+    window->y = -1;
+}
+
+GtkWidget *
+ui_skinned_window_new(const gchar *wmclass_name)
+{
+    GtkWidget *widget = g_object_new(ui_skinned_window_get_type(), NULL);
+    GtkWindow *window = GTK_WINDOW(widget);
+
+    window->type = SKINNED_WINDOW_TYPE;
+
+    if (wmclass_name)
+        gtk_window_set_wmclass(GTK_WINDOW(widget), wmclass_name, "Audacious");
+
+    gtk_widget_add_events(GTK_WIDGET(widget),
+                          GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK |
+                          GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+                          GDK_SCROLL_MASK | GDK_KEY_PRESS_MASK |
+                          GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK);
+    gtk_widget_realize(GTK_WIDGET(widget));
+
+    set_dock_window_list(dock_window_set_decorated(get_dock_window_list(),
+                                                   GTK_WINDOW(widget),
+                                                   cfg.show_wm_decorations));
+    gtk_widget_set_app_paintable(GTK_WIDGET(widget), TRUE);
+    gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
+    gtk_widget_shape_combine_mask(widget, NULL, 0, 0);
+
+    if (!strcmp(wmclass_name, "player"))
+        SKINNED_WINDOW(widget)->type = WINDOW_MAIN;
+    if (!strcmp(wmclass_name, "equalizer"))
+        SKINNED_WINDOW(widget)->type = WINDOW_EQ;
+    if (!strcmp(wmclass_name, "playlist"))
+        SKINNED_WINDOW(widget)->type = WINDOW_PLAYLIST;
+
+    /* GtkFixed hasn't got its GdkWindow, this means that it can be used to
+       display widgets while the logo below will be displayed anyway;
+       however fixed positions are not that great, cause the button sizes may (will)
+       vary depending on the gtk style used, so it's not possible to center
+       them unless a fixed width and heigth is forced (and this may bring to cutted
+       text if someone, i.e., uses a big font for gtk widgets);
+       other types of container most likely have their GdkWindow, this simply
+       means that the logo must be drawn on the container widget, instead of the
+       window; otherwise, it won't be displayed correctly */
+    SKINNED_WINDOW(widget)->fixed = gtk_fixed_new();
+    gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(SKINNED_WINDOW(widget)->fixed));
+    return widget;
+}
+
+void ui_skinned_window_draw_all(GtkWidget *widget) {
+    if (SKINNED_WINDOW(widget)->type == WINDOW_MAIN)
+        mainwin_refresh_hints();
+
+    gtk_widget_queue_draw(widget);
+    GList *iter;
+    for (iter = GTK_FIXED (SKINNED_WINDOW(widget)->fixed)->children; iter; iter = g_list_next (iter)) {
+         GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
+         GtkWidget *child = child_data->widget;
+         gtk_widget_queue_draw(child);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinned_window.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,64 @@
+/*
+ * Audacious: A cross-platform multimedia player
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINNED_WINDOW_H
+#define AUDACIOUS_UI_SKINNED_WINDOW_H
+
+#define SKINNED_WINDOW(obj)          GTK_CHECK_CAST (obj, ui_skinned_window_get_type (), SkinnedWindow)
+#define SKINNED_WINDOW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_window_get_type (), SkinnedWindowClass)
+#define SKINNED_CHECK_WINDOW(obj)    GTK_CHECK_TYPE (obj, ui_skinned_window_get_type ())
+#define SKINNED_TYPE_WINDOW          (ui_skinned_window_get_type())
+
+#ifdef GDK_WINDOWING_QUARTZ
+# define SKINNED_WINDOW_TYPE		GTK_WINDOW_POPUP
+#else
+# define SKINNED_WINDOW_TYPE		GTK_WINDOW_TOPLEVEL
+#endif
+
+enum {
+    WINDOW_MAIN,
+    WINDOW_EQ,
+    WINDOW_PLAYLIST
+};
+
+typedef struct _SkinnedWindow SkinnedWindow;
+typedef struct _SkinnedWindowClass SkinnedWindowClass;
+
+struct _SkinnedWindow
+{
+  GtkWindow window;
+
+  GtkWidget *canvas;
+  gint x,y;
+
+  gint type;
+  GtkWidget *fixed;
+};
+
+struct _SkinnedWindowClass
+{
+  GtkWindowClass        parent_class;
+};
+
+extern GType ui_skinned_window_get_type(void);
+extern GtkWidget *ui_skinned_window_new(const gchar *wmclass_name);
+extern void ui_skinned_window_draw_all(GtkWidget *widget);
+
+#endif /* AUDACIOUS_UI_SKINNED_WINDOW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinselector.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,404 @@
+/*  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "ui_skinselector.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "platform/smartinclude.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "main.h"
+#include "ui_skin.h"
+#include "util.h"
+
+#define EXTENSION_TARGETS 7
+
+static gchar *ext_targets[EXTENSION_TARGETS] = { "bmp", "xpm", "png", "svg",
+        "gif", "jpg", "jpeg" };
+
+#define THUMBNAIL_WIDTH  90
+#define THUMBNAIL_HEIGHT 40
+
+
+enum SkinViewCols {
+    SKIN_VIEW_COL_PREVIEW,
+    SKIN_VIEW_COL_FORMATTEDNAME,
+    SKIN_VIEW_COL_NAME,
+    SKIN_VIEW_N_COLS
+};
+
+
+GList *skinlist = NULL;
+
+
+
+static gchar *
+get_thumbnail_filename(const gchar * path)
+{
+    gchar *basename, *pngname, *thumbname;
+
+    g_return_val_if_fail(path != NULL, NULL);
+
+    basename = g_path_get_basename(path);
+    pngname = g_strconcat(basename, ".png", NULL);
+
+    thumbname = g_build_filename(aud_paths[BMP_PATH_SKIN_THUMB_DIR],
+                                 pngname, NULL);
+
+    g_free(basename);
+    g_free(pngname);
+
+    return thumbname;
+}
+
+
+static GdkPixbuf *
+skin_get_preview(const gchar * path)
+{
+    GdkPixbuf *preview = NULL;
+    gchar *dec_path, *preview_path;
+    gboolean is_archive = FALSE;
+    gint i = 0;
+    gchar buf[60];			/* gives us lots of room */
+
+    if (file_is_archive(path))
+    {
+        if (!(dec_path = archive_decompress(path)))
+            return NULL;
+
+        is_archive = TRUE;
+    }
+    else
+    {
+        dec_path = g_strdup(path);
+    }
+
+    for (i = 0; i < EXTENSION_TARGETS; i++)
+    {
+        sprintf(buf, "main.%s", ext_targets[i]);
+
+        if ((preview_path = find_path_recursively(dec_path, buf)) != NULL)
+            break;
+    }
+
+    if (preview_path)
+    {
+        preview = gdk_pixbuf_new_from_file(preview_path, NULL);
+        g_free(preview_path);
+    }
+
+    if (is_archive)
+        del_directory(dec_path);
+
+    g_free(dec_path);
+
+    return preview;
+}
+
+
+static GdkPixbuf *
+skin_get_thumbnail(const gchar * path)
+{
+    GdkPixbuf *scaled = NULL;
+    GdkPixbuf *preview;
+    gchar *thumbname;
+
+    g_return_val_if_fail(path != NULL, NULL);
+
+    if (g_str_has_suffix(path, "thumbs"))
+        return NULL;
+
+    thumbname = get_thumbnail_filename(path);
+
+    if (g_file_test(thumbname, G_FILE_TEST_EXISTS)) {
+        scaled = gdk_pixbuf_new_from_file(thumbname, NULL);
+        g_free(thumbname);
+        return scaled;
+    }
+
+    if (!(preview = skin_get_preview(path))) {
+        g_free(thumbname);
+        return NULL;
+    }
+
+    scaled = gdk_pixbuf_scale_simple(preview,
+                                     THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT,
+                                     GDK_INTERP_BILINEAR);
+    g_object_unref(preview);
+
+    gdk_pixbuf_save(scaled, thumbname, "png", NULL, NULL);
+    g_free(thumbname);
+
+    return scaled;
+}
+
+static void
+skinlist_add(const gchar * filename)
+{
+    SkinNode *node;
+    gchar *basename;
+
+    g_return_if_fail(filename != NULL);
+
+    node = g_slice_new0(SkinNode);
+    node->path = g_strdup(filename);
+
+    basename = g_path_get_basename(filename);
+
+    if (file_is_archive(filename)) {
+        node->name = archive_basename(basename);
+	node->desc = _("Archived Winamp 2.x skin");
+        g_free(basename);
+    }
+    else {
+        node->name = basename;
+	node->desc = _("Unarchived Winamp 2.x skin");
+    }
+
+    skinlist = g_list_prepend(skinlist, node);
+}
+
+static gboolean
+scan_skindir_func(const gchar * path, const gchar * basename, gpointer data)
+{
+    if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
+        if (file_is_archive(path)) {
+            skinlist_add(path);
+        }
+    }
+    else if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
+        skinlist_add(path);
+    }
+
+    return FALSE;
+}
+
+static void
+scan_skindir(const gchar * path)
+{
+    GError *error = NULL;
+
+    g_return_if_fail(path != NULL);
+
+    if (path[0] == '.')
+        return;
+
+    if (!dir_foreach(path, scan_skindir_func, NULL, &error)) {
+        g_warning("Failed to open directory (%s): %s", path, error->message);
+        g_error_free(error);
+        return;
+    }
+}
+
+static gint
+skinlist_compare_func(gconstpointer a, gconstpointer b)
+{
+    g_return_val_if_fail(a != NULL && SKIN_NODE(a)->name != NULL, 1);
+    g_return_val_if_fail(b != NULL && SKIN_NODE(b)->name != NULL, 1);
+    return strcasecmp(SKIN_NODE(a)->name, SKIN_NODE(b)->name);
+}
+
+static void
+skin_free_func(gpointer data)
+{
+    g_return_if_fail(data != NULL);
+    g_free(SKIN_NODE(data)->name);
+    g_free(SKIN_NODE(data)->path);
+    g_slice_free(SkinNode, data);
+}
+
+
+static void
+skinlist_clear(void)
+{
+    if (!skinlist)
+        return;
+
+    g_list_foreach(skinlist, (GFunc) skin_free_func, NULL);
+    g_list_free(skinlist);
+    skinlist = NULL;
+}
+
+void
+skinlist_update(void)
+{
+    gchar *skinsdir;
+
+    skinlist_clear();
+
+    scan_skindir(aud_paths[BMP_PATH_USER_SKIN_DIR]);
+    scan_skindir(DATA_DIR G_DIR_SEPARATOR_S "Skins");
+
+    skinsdir = getenv("SKINSDIR");
+    if (skinsdir) {
+        gchar **dir_list = g_strsplit(skinsdir, ":", 0);
+        gchar **dir;
+
+        for (dir = dir_list; *dir; dir++)
+            scan_skindir(*dir);
+        g_strfreev(dir_list);
+    }
+
+    skinlist = g_list_sort(skinlist, skinlist_compare_func);
+
+    g_assert(skinlist != NULL);
+}
+
+void
+skin_view_update(GtkTreeView * treeview, GtkWidget * refresh_button)
+{
+    GtkTreeSelection *selection = NULL;
+    GtkListStore *store;
+    GtkTreeIter iter, iter_current_skin;
+    gboolean have_current_skin = FALSE;
+    GtkTreePath *path;
+
+    GdkPixbuf *thumbnail;
+    gchar *formattedname;
+    gchar *name;
+    GList *entry;
+
+    gtk_widget_set_sensitive(GTK_WIDGET(treeview), FALSE);
+    gtk_widget_set_sensitive(GTK_WIDGET(refresh_button), FALSE);
+
+    store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
+
+    gtk_list_store_clear(store);
+
+    skinlist_update();
+
+    for (entry = skinlist; entry; entry = g_list_next(entry)) {
+        thumbnail = skin_get_thumbnail(SKIN_NODE(entry->data)->path);
+
+        formattedname = g_strdup_printf("<big><b>%s</b></big>\n<i>%s</i>",
+		SKIN_NODE(entry->data)->name, SKIN_NODE(entry->data)->desc);
+        name = SKIN_NODE(entry->data)->name;
+
+        gtk_list_store_append(store, &iter);
+        gtk_list_store_set(store, &iter,
+                           SKIN_VIEW_COL_PREVIEW, thumbnail,
+                           SKIN_VIEW_COL_FORMATTEDNAME, formattedname,
+                           SKIN_VIEW_COL_NAME, name, -1);
+        if (thumbnail)
+            g_object_unref(thumbnail);
+        g_free(formattedname);
+
+        if (g_strstr_len(aud_active_skin->path,
+                         strlen(aud_active_skin->path), name) ) {
+            iter_current_skin = iter;
+            have_current_skin = TRUE;
+        }
+    }
+
+    if (have_current_skin) {
+        selection = gtk_tree_view_get_selection(treeview);
+        gtk_tree_selection_select_iter(selection, &iter_current_skin);
+
+        path = gtk_tree_model_get_path(GTK_TREE_MODEL(store),
+		                               &iter_current_skin);
+        gtk_tree_view_scroll_to_cell(treeview, path, NULL, TRUE, 0.5, 0.5);
+        gtk_tree_path_free(path);
+    }
+
+    gtk_widget_set_sensitive(GTK_WIDGET(treeview), TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(refresh_button), TRUE);
+}
+
+
+static void
+skin_view_on_cursor_changed(GtkTreeView * treeview,
+                            gpointer data)
+{
+    GtkTreeModel *model;
+    GtkTreeSelection *selection;
+    GtkTreeIter iter;
+
+    GList *node;
+    gchar *name;
+    gchar *comp = NULL;
+
+    selection = gtk_tree_view_get_selection(treeview);
+    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
+        return;
+
+    gtk_tree_model_get(model, &iter, SKIN_VIEW_COL_NAME, &name, -1);
+
+    for (node = skinlist; node; node = g_list_next(node)) {
+        comp = SKIN_NODE(node->data)->path;
+        if (g_strrstr(comp, name))
+            break;
+    }
+
+    g_free(name);
+
+    aud_active_skin_load(comp);
+}
+
+
+void
+skin_view_realize(GtkTreeView * treeview)
+{
+    GtkListStore *store;
+    GtkTreeViewColumn *column;
+    GtkCellRenderer *renderer;
+    GtkTreeSelection *selection;
+
+    gtk_widget_show_all(GTK_WIDGET(treeview));
+    
+    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+
+    store = gtk_list_store_new(SKIN_VIEW_N_COLS, GDK_TYPE_PIXBUF,
+                               G_TYPE_STRING , G_TYPE_STRING);
+    gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
+
+    column = gtk_tree_view_column_new();
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+    gtk_tree_view_column_set_spacing(column, 16);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview),
+                                GTK_TREE_VIEW_COLUMN(column));
+
+    renderer = gtk_cell_renderer_pixbuf_new();
+    gtk_tree_view_column_pack_start(column, renderer, FALSE);
+    gtk_tree_view_column_set_attributes(column, renderer, "pixbuf",
+                                        SKIN_VIEW_COL_PREVIEW, NULL);
+
+    renderer = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, renderer, TRUE);
+    gtk_tree_view_column_set_attributes(column, renderer, "markup",
+                                        SKIN_VIEW_COL_FORMATTEDNAME, NULL);
+
+    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
+
+    g_signal_connect(treeview, "cursor-changed",
+                     G_CALLBACK(skin_view_on_cursor_changed), NULL);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_skinselector.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,45 @@
+/*  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SKINSELECTOR_H
+#define AUDACIOUS_UI_SKINSELECTOR_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#define SKIN_NODE(x)  ((SkinNode *)(x))
+struct _SkinNode {
+    gchar *name;
+    gchar *desc;
+    gchar *path;
+    GTime *time;
+};
+
+typedef struct _SkinNode SkinNode;
+
+extern GList *skinlist;
+
+void skinlist_update();
+void skin_view_realize(GtkTreeView * treeview);
+void skin_view_update(GtkTreeView * treeview, GtkWidget * refresh_button);
+
+#endif /* AUDACIOUS_UI_SKINSELECTOR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_svis.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,550 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007  Audacious development team.
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skin.h"
+#include "ui_svis.h"
+#include "ui_vis.h"
+#include "main.h"
+#include "util.h"
+#include "strings.h"
+#include "playback.h"
+#include <string.h>
+#include <ctype.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmarshal.h>
+#include <gtk/gtkimage.h>
+
+#define UI_TYPE_SVIS           (ui_svis_get_type())
+
+static gint svis_redraw_delays[] = { 1, 2, 4, 8 };
+
+/* FIXME: Are the svis_scope_colors correct? */
+static guint8 svis_scope_colors[] = { 20, 19, 18, 19, 20 };
+static guint8 svis_vu_normal_colors[] = { 17, 17, 17, 12, 12, 12, 2, 2 };
+
+#define DRAW_DS_PIXEL(ptr,value) \
+	*(ptr) = (value); \
+	*((ptr) + 1) = (value); \
+	*((ptr) + 76) = (value); \
+	*((ptr) + 77) = (value);
+
+#define SVIS_HEIGHT 5
+#define SVIS_WIDTH 38
+
+enum {
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+static void ui_svis_class_init         (UiSVisClass *klass);
+static void ui_svis_init               (UiSVis *svis);
+static void ui_svis_destroy            (GtkObject *object);
+static void ui_svis_realize            (GtkWidget *widget);
+static void ui_svis_unrealize          (GtkWidget *widget);
+static void ui_svis_map                (GtkWidget *widget);
+static void ui_svis_unmap              (GtkWidget *widget);
+static void ui_svis_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_svis_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_svis_expose         (GtkWidget *widget, GdkEventExpose *event);
+static void ui_svis_toggle_scaled      (UiSVis *svis);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint vis_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_svis_get_type() {
+    static GType vis_type = 0;
+    if (!vis_type) {
+        static const GTypeInfo vis_info = {
+            sizeof (UiSVisClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_svis_class_init,
+            NULL,
+            NULL,
+            sizeof (UiSVis),
+            0,
+            (GInstanceInitFunc) ui_svis_init,
+        };
+        vis_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSVis_", &vis_info, 0);
+    }
+
+    return vis_type;
+}
+
+static void ui_svis_class_init(UiSVisClass *klass) {
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_svis_destroy;
+
+    widget_class->realize = ui_svis_realize;
+    widget_class->unrealize = ui_svis_unrealize;
+    widget_class->map = ui_svis_map;
+    widget_class->unmap = ui_svis_unmap;
+    widget_class->expose_event = ui_svis_expose;
+    widget_class->size_request = ui_svis_size_request;
+    widget_class->size_allocate = ui_svis_size_allocate;
+
+    klass->scaled = ui_svis_toggle_scaled;
+
+    vis_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiSVisClass, scaled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+static void ui_svis_init(UiSVis *svis) {
+
+}
+
+GtkWidget* ui_svis_new(GtkWidget *fixed, gint x, gint y) {
+    UiSVis *svis = g_object_new (ui_svis_get_type (), NULL);
+
+    svis->x = x;
+    svis->y = y;
+
+    svis->width = SVIS_WIDTH;
+    svis->height = SVIS_HEIGHT;
+
+    svis->fixed = fixed;
+    svis->scaled = FALSE;
+
+    svis->visible_window = TRUE;
+    svis->event_window = NULL;
+
+    gtk_fixed_put(GTK_FIXED(svis->fixed), GTK_WIDGET(svis), svis->x, svis->y);
+
+    return GTK_WIDGET(svis);
+}
+
+static void ui_svis_destroy(GtkObject *object) {
+    UiSVis *svis;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_IS_SVIS (object));
+
+    svis = UI_SVIS (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_svis_realize(GtkWidget *widget) {
+    UiSVis *svis;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_IS_SVIS(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    svis = UI_SVIS(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
+
+    if (svis->visible_window)
+    {
+      attributes.visual = gtk_widget_get_visual(widget);
+      attributes.colormap = gtk_widget_get_colormap(widget);
+      attributes.wclass = GDK_INPUT_OUTPUT;
+      attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+      widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+      GTK_WIDGET_UNSET_FLAGS(widget, GTK_NO_WINDOW);
+      gdk_window_set_user_data(widget->window, widget);
+    }
+    else
+    {
+      widget->window = gtk_widget_get_parent_window (widget);
+      g_object_ref (widget->window);
+
+      attributes.wclass = GDK_INPUT_ONLY;
+      attributes_mask = GDK_WA_X | GDK_WA_Y;
+      svis->event_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+      GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
+      gdk_window_set_user_data(svis->event_window, widget);
+    }
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+}
+
+static void ui_svis_unrealize(GtkWidget *widget) {
+    UiSVis *svis;
+    svis = UI_SVIS(widget);
+
+    if ( svis->event_window != NULL )
+    {
+      gdk_window_set_user_data( svis->event_window , NULL );
+      gdk_window_destroy( svis->event_window );
+      svis->event_window = NULL;
+    }
+
+    if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+        (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void ui_svis_map(GtkWidget *widget)
+{
+    UiSVis *svis;
+    svis = UI_SVIS(widget);
+
+    if (svis->event_window != NULL)
+      gdk_window_show (svis->event_window);
+
+    if (GTK_WIDGET_CLASS (parent_class)->map)
+      (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+}
+
+static void ui_svis_unmap (GtkWidget *widget)
+{
+    UiSVis *svis;
+    svis = UI_SVIS(widget);
+
+    if (svis->event_window != NULL)
+      gdk_window_hide (svis->event_window);
+
+    if (GTK_WIDGET_CLASS (parent_class)->unmap)
+      (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+}
+
+static void ui_svis_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiSVis *svis = UI_SVIS(widget);
+
+    requisition->width = svis->width * (svis->scaled ? cfg.scale_factor : 1);
+    requisition->height = svis->height*(svis->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_svis_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiSVis *svis = UI_SVIS (widget);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (svis->scaled ? cfg.scale_factor : 1 );
+    widget->allocation.y *= (svis->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+    {
+        if (svis->event_window != NULL)
+            gdk_window_move_resize(svis->event_window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+        else
+            gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+    }
+
+    svis->x = widget->allocation.x/(svis->scaled ? cfg.scale_factor : 1);
+    svis->y = widget->allocation.y/(svis->scaled ? cfg.scale_factor : 1);
+}
+
+static gboolean ui_svis_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_IS_SVIS (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiSVis *svis = UI_SVIS (widget);
+
+    gint x, y, h;
+    guchar svis_color[24][3];
+    guchar rgb_data[SVIS_WIDTH * 2 * SVIS_HEIGHT * 2], *ptr, c;
+    guint32 colors[24];
+    GdkRgbCmap *cmap;
+
+    if (!GTK_WIDGET_VISIBLE(widget))
+        return FALSE;
+
+    if (!svis->visible_window)
+        return FALSE;
+
+    skin_get_viscolor(aud_active_skin, svis_color);
+    for (y = 0; y < 24; y++) {
+        colors[y] =
+            svis_color[y][0] << 16 | svis_color[y][1] << 8 | svis_color[y][2];
+    }
+    cmap = gdk_rgb_cmap_new(colors, 24);
+
+    if (!cfg.scaled) {
+      memset(rgb_data, 0, SVIS_WIDTH * SVIS_HEIGHT);
+      if (cfg.vis_type == VIS_ANALYZER  && !playback_get_paused() && playback_get_playing()){
+	for(y=0; y < SVIS_HEIGHT; y++){
+	  if (cfg.analyzer_type == ANALYZER_BARS){
+	    for(x=0;x< SVIS_WIDTH; x++){
+	      if(svis->data[x] > y << 1)
+		{
+		  rgb_data[x*3+ (SVIS_HEIGHT - y) * SVIS_WIDTH] = 23;
+		  rgb_data[x*3+1 + (SVIS_HEIGHT - y) * SVIS_WIDTH] = 23;
+		  
+		}
+	    }
+	  }
+	  else{
+	    for(x=0;x< SVIS_WIDTH; x++){
+	      if(svis->data[x] > y << 1)
+		{
+		  rgb_data[x + (SVIS_HEIGHT - y) * SVIS_WIDTH] = 23;
+		}
+	    }
+	  }
+	}
+      }
+	else if (cfg.vis_type == VIS_VOICEPRINT){
+	  switch (cfg.vu_mode) {
+	  case VU_NORMAL:
+	    for (y = 0; y < 2; y++) {
+	      ptr = rgb_data + ((y * 3) * 38);
+	      h = (svis->data[y] * 7) / 37;
+	      for (x = 0; x < h; x++, ptr += 5) {
+		c = svis_vu_normal_colors[x];
+		*(ptr) = c;
+		*(ptr + 1) = c;
+		*(ptr + 2) = c;
+		*(ptr + 38) = c;
+		*(ptr + 39) = c;
+		*(ptr + 40) = c;
+	      }
+	    }
+	    break;
+	  case VU_SMOOTH:
+	    for (y = 0; y < 2; y++) {
+	      ptr = rgb_data + ((y * 3) * SVIS_WIDTH);
+	      for (x = 0; x < svis->data[y]; x++, ptr++) {
+		c = 17 - ((x * 15) / 37);
+		*(ptr) = c;
+		*(ptr + 38) = c;
+	      }
+	    }
+	    break;
+	  }	  
+	}
+        else if (cfg.vis_type == VIS_SCOPE) {
+            for (x = 0; x < 38; x++) {
+                h = svis->data[x << 1] / 3;
+                ptr = rgb_data + ((4 - h) * 38) + x;
+                *ptr = svis_scope_colors[h];
+            }
+        }
+
+    }
+    else {            /*svis scaling, this needs some work, since a lot of stuff is hardcoded --majeru*/
+
+      memset(rgb_data, 0, SVIS_WIDTH * cfg.scale_factor * SVIS_HEIGHT * cfg.scale_factor);
+      if (cfg.vis_type == VIS_ANALYZER && !playback_get_paused() && playback_get_playing()){
+	  for(y=0; y < SVIS_HEIGHT; y++){
+            if (cfg.analyzer_type == ANALYZER_BARS){
+              for(x=0;x< SVIS_WIDTH; x++){
+                if(svis->data[x] > y << 1)
+                {
+                  ptr = rgb_data + x * 6 + (SVIS_HEIGHT * 2 - y * 2) * SVIS_WIDTH *2;
+                  DRAW_DS_PIXEL(ptr, 23);
+                  DRAW_DS_PIXEL(ptr + 2, 23);
+                }
+              }
+            }
+            else{
+              for(x=0;x< SVIS_WIDTH; x++){
+                if(svis->data[x] > y << 1)
+                {
+                  ptr = rgb_data + x * 2 + (SVIS_HEIGHT * 2 - y * 2) * SVIS_WIDTH * 2;
+                  DRAW_DS_PIXEL(ptr, 23);
+                }
+              }
+            }
+	  }
+        }
+	else if (cfg.vis_type == VIS_VOICEPRINT){
+	  switch (cfg.vu_mode) {
+	  case VU_NORMAL:
+	    for (y = 0; y < 2; y++) {
+	      ptr = rgb_data + ((y * 3) * 152);
+	      h = (svis->data[y] * 8) / 37;
+	      for (x = 0; x < h; x++, ptr += 10) {
+		c = svis_vu_normal_colors[x];
+		DRAW_DS_PIXEL(ptr, c);
+		DRAW_DS_PIXEL(ptr + 2, c);
+		DRAW_DS_PIXEL(ptr + 4, c);
+		DRAW_DS_PIXEL(ptr + 152, c);
+		DRAW_DS_PIXEL(ptr + 154, c);
+		DRAW_DS_PIXEL(ptr + 156, c);
+	      }
+	    }
+	    break;
+	  case VU_SMOOTH:
+	    for (y = 0; y < 2; y++) {
+	      ptr = rgb_data + ((y * 3) * 152);
+	      for (x = 0; x < svis->data[y]; x++, ptr += 2) {
+		c = 17 - ((x * 15) / 37);
+		DRAW_DS_PIXEL(ptr, c);
+		DRAW_DS_PIXEL(ptr + 152, c);
+	      }
+	    }
+	    break;
+	  }  
+	}
+        else if (cfg.vis_type == VIS_SCOPE) {
+            for (x = 0; x < 38; x++) {
+                h = svis->data[x << 1] / 3;
+                ptr = rgb_data + ((4 - h) * 152) + (x << 1);
+                *ptr = svis_scope_colors[h];
+                *(ptr + 1) = svis_scope_colors[h];
+                *(ptr + 76) = svis_scope_colors[h];
+                *(ptr + 77) = svis_scope_colors[h];
+            }
+        }
+
+
+    }
+
+    GdkPixmap *obj = NULL;
+    GdkGC *gc;
+    obj = gdk_pixmap_new(NULL, svis->width* ( svis->scaled ? cfg.scale_factor : 1), 
+        svis->height*(svis->scaled ? cfg.scale_factor : 1), gdk_rgb_get_visual()->depth);
+    gc = gdk_gc_new(obj);
+
+    if (!svis->scaled) {
+        gdk_draw_indexed_image(obj, gc, 0, 0, svis->width, svis->height,
+                               GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
+                               38, cmap);
+    } else {
+        gdk_draw_indexed_image(obj, gc,
+                               0 << 1, 0 << 1,
+                               svis->width << 1, svis->height << 1,
+                               GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
+                               76, cmap);
+    }
+
+    gdk_rgb_cmap_free(cmap);
+    gdk_draw_drawable (widget->window, gc, obj, 0, 0, 0, 0,
+                       svis->width*(svis->scaled ? cfg.scale_factor : 1), 
+                       svis->height*(svis->scaled ? cfg.scale_factor : 1));
+    g_object_unref(obj);
+    g_object_unref(gc);
+
+    return FALSE;
+}
+
+static void ui_svis_toggle_scaled(UiSVis *svis) {
+    GtkWidget *widget = GTK_WIDGET (svis);
+    svis->scaled = !svis->scaled;
+
+    gtk_widget_set_size_request(widget, svis->width* cfg.scale_factor, svis->height * cfg.scale_factor);
+
+    gtk_widget_queue_draw(widget);
+}
+
+void ui_svis_set_visible(GtkWidget *widget, gboolean window_is_visible)
+{
+    UiSVis *svis;
+    gboolean widget_is_visible;
+
+    g_return_if_fail(UI_IS_SVIS(widget));
+
+    svis = UI_SVIS (widget);
+    widget_is_visible = GTK_WIDGET_VISIBLE(widget);
+
+    svis->visible_window = window_is_visible;
+
+    if (GTK_WIDGET_REALIZED (widget))
+    {
+        if ( widget_is_visible )
+            gtk_widget_hide(widget);
+
+        gtk_widget_unrealize(widget);
+        gtk_widget_realize(widget);
+
+        if ( widget_is_visible )
+            gtk_widget_show(widget);
+    }
+
+    if (widget_is_visible)
+        gtk_widget_queue_resize(widget);
+}
+
+void ui_svis_clear_data(GtkWidget *widget) {
+    g_return_if_fail(UI_IS_SVIS(widget));
+
+    gint i;
+    UiSVis *svis = UI_SVIS (widget);
+
+    for (i = 0; i < 75; i++) {
+        svis->data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0;
+    }
+}
+
+void ui_svis_timeout_func(GtkWidget *widget, guchar * data) {
+    g_return_if_fail(UI_IS_SVIS(widget));
+
+    UiSVis *svis = UI_SVIS (widget);
+    static GTimer *timer = NULL;
+    gulong micros = 9999999;
+    gboolean falloff = FALSE;
+    gint i;
+
+    if (!timer) {
+        timer = g_timer_new();
+        g_timer_start(timer);
+    }
+    else {
+        g_timer_elapsed(timer, &micros);
+        if (micros > 14000)
+            g_timer_reset(timer);
+
+    }
+
+    if (cfg.vis_type == VIS_VOICEPRINT) {
+        if (micros > 14000)
+            falloff = TRUE;
+
+        for (i = 0; i < 2; i++) {
+            if (falloff || data) {
+                if (data && data[i] > svis->data[i])
+                    svis->data[i] = data[i];
+                else if (falloff) {
+                    if (svis->data[i] >= 2)
+                        svis->data[i] -= 2;
+                    else
+                        svis->data[i] = 0;
+                }
+            }
+
+        }
+    }
+    else if (data) {
+        for (i = 0; i < 75; i++)
+            svis->data[i] = data[i];
+    }
+
+    if (micros > 14000) {
+        if (!svis->refresh_delay) {
+            gtk_widget_queue_draw(widget);
+            svis->refresh_delay = svis_redraw_delays[cfg.vis_refresh];
+        }
+        svis->refresh_delay--;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_svis.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,64 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007  Audacious development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_SVIS_H
+#define AUDACIOUS_UI_SVIS_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_SVIS(obj)          GTK_CHECK_CAST (obj, ui_svis_get_type (), UiSVis)
+#define UI_SVIS_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_svis_get_type (), UiSVisClass)
+#define UI_IS_SVIS(obj)       GTK_CHECK_TYPE (obj, ui_svis_get_type ())
+
+typedef struct _UiSVis        UiSVis;
+typedef struct _UiSVisClass   UiSVisClass;
+
+struct _UiSVis {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gint             data[75];
+    gint             refresh_delay;
+    gboolean         scaled;
+    GtkWidget        *fixed;
+    gboolean         visible_window;
+    GdkWindow        *event_window;
+};
+
+struct _UiSVisClass {
+    GtkWidgetClass          parent_class;
+    void (* scaled)        (UiSVis *vis);
+};
+
+GtkWidget* ui_svis_new (GtkWidget *fixed, gint x, gint y);
+GtkType ui_svis_get_type(void);
+void ui_svis_clear_data(GtkWidget *widget);
+void ui_svis_timeout_func(GtkWidget *widget, guchar * data);
+void ui_svis_set_visible(GtkWidget *widget, gboolean window_is_visible);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_SVIS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_vis.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,724 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007  Audacious development team.
+ *
+ * Based on:
+ * BMP - Cross-platform multimedia player
+ * Copyright (C) 2003-2004  BMP development team.
+ * XMMS:
+ * Copyright (C) 1998-2003  XMMS development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#include "ui_skin.h"
+#include "ui_vis.h"
+#include "main.h"
+#include "util.h"
+#include "playback.h"
+
+static const gfloat vis_afalloff_speeds[] = { 0.34, 0.5, 1.0, 1.3, 1.6 };
+static const gfloat vis_pfalloff_speeds[] = { 1.2, 1.3, 1.4, 1.5, 1.6 };
+static const gint vis_redraw_delays[] = { 1, 2, 4, 8 };
+static const guint8 vis_scope_colors[] =
+    { 21, 21, 20, 20, 19, 19, 18, 19, 19, 20, 20, 21, 21 };
+static guchar voiceprint_data[76*16];
+
+enum {
+    DOUBLED,
+    LAST_SIGNAL
+};
+
+static void ui_vis_class_init         (UiVisClass *klass);
+static void ui_vis_init               (UiVis *vis);
+static void ui_vis_destroy            (GtkObject *object);
+static void ui_vis_realize            (GtkWidget *widget);
+static void ui_vis_unrealize          (GtkWidget *widget);
+static void ui_vis_map                (GtkWidget *widget);
+static void ui_vis_unmap              (GtkWidget *widget);
+static void ui_vis_size_request       (GtkWidget *widget, GtkRequisition *requisition);
+static void ui_vis_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
+static gboolean ui_vis_expose         (GtkWidget *widget, GdkEventExpose *event);
+static void ui_vis_toggle_scaled      (UiVis *vis);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint vis_signals[LAST_SIGNAL] = { 0 };
+
+GType ui_vis_get_type() {
+    static GType vis_type = 0;
+    if (!vis_type) {
+        static const GTypeInfo vis_info = {
+            sizeof (UiVisClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) ui_vis_class_init,
+            NULL,
+            NULL,
+            sizeof (UiVis),
+            0,
+            (GInstanceInitFunc) ui_vis_init,
+        };
+        vis_type = g_type_register_static (GTK_TYPE_WIDGET, "UiVis_", &vis_info, 0);
+    }
+
+    return vis_type;
+}
+
+static void ui_vis_class_init(UiVisClass *klass) {
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    object_class = (GtkObjectClass*) klass;
+    widget_class = (GtkWidgetClass*) klass;
+    parent_class = gtk_type_class (gtk_widget_get_type ());
+
+    object_class->destroy = ui_vis_destroy;
+
+    widget_class->realize = ui_vis_realize;
+    widget_class->unrealize = ui_vis_unrealize;
+    widget_class->map = ui_vis_map;
+    widget_class->unmap = ui_vis_unmap;
+    widget_class->expose_event = ui_vis_expose;
+    widget_class->size_request = ui_vis_size_request;
+    widget_class->size_allocate = ui_vis_size_allocate;
+
+    klass->doubled = ui_vis_toggle_scaled;
+
+    vis_signals[DOUBLED] = 
+        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                      G_STRUCT_OFFSET (UiVisClass, doubled), NULL, NULL,
+                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+static void ui_vis_init(UiVis *vis) {
+    memset(voiceprint_data, 0, 16*76);
+}
+
+GtkWidget* ui_vis_new(GtkWidget *fixed, gint x, gint y, gint width) {
+    UiVis *vis = g_object_new (ui_vis_get_type (), NULL);
+
+    vis->x = x;
+    vis->y = y;
+
+    vis->width = width;
+    vis->height = 16;
+
+    vis->fixed = fixed;
+    vis->scaled = FALSE;
+
+    vis->visible_window = TRUE;
+    vis->event_window = NULL;
+
+    gtk_fixed_put(GTK_FIXED(vis->fixed), GTK_WIDGET(vis), vis->x, vis->y);
+
+    return GTK_WIDGET(vis);
+}
+
+static void ui_vis_destroy(GtkObject *object) {
+    UiVis *vis;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (UI_IS_VIS (object));
+
+    vis = UI_VIS (object);
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void ui_vis_realize(GtkWidget *widget) {
+    UiVis *vis;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (UI_IS_VIS(widget));
+
+    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+    vis = UI_VIS(widget);
+
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.event_mask = gtk_widget_get_events(widget);
+    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
+
+    if (vis->visible_window)
+    {
+      attributes.visual = gtk_widget_get_visual(widget);
+      attributes.colormap = gtk_widget_get_colormap(widget);
+      attributes.wclass = GDK_INPUT_OUTPUT;
+      attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+      widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
+      GTK_WIDGET_UNSET_FLAGS(widget, GTK_NO_WINDOW);
+      gdk_window_set_user_data(widget->window, widget);
+    }
+    else
+    {
+      widget->window = gtk_widget_get_parent_window (widget);
+      g_object_ref (widget->window);
+
+      attributes.wclass = GDK_INPUT_ONLY;
+      attributes_mask = GDK_WA_X | GDK_WA_Y;
+      vis->event_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+      GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
+      gdk_window_set_user_data(vis->event_window, widget);
+    }
+
+    widget->style = gtk_style_attach(widget->style, widget->window);
+}
+
+static void ui_vis_unrealize(GtkWidget *widget) {
+    UiVis *vis;
+    vis = UI_VIS(widget);
+
+    if ( vis->event_window != NULL )
+    {
+      gdk_window_set_user_data( vis->event_window , NULL );
+      gdk_window_destroy( vis->event_window );
+      vis->event_window = NULL;
+    }
+
+    if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+        (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void ui_vis_map(GtkWidget *widget)
+{
+    UiVis *vis;
+    vis = UI_VIS(widget);
+
+    if (vis->event_window != NULL)
+      gdk_window_show (vis->event_window);
+
+    if (GTK_WIDGET_CLASS (parent_class)->map)
+      (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+}
+
+static void ui_vis_unmap (GtkWidget *widget)
+{
+    UiVis *vis;
+    vis = UI_VIS(widget);
+
+    if (vis->event_window != NULL)
+      gdk_window_hide (vis->event_window);
+
+    if (GTK_WIDGET_CLASS (parent_class)->unmap)
+      (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+}
+
+static void ui_vis_size_request(GtkWidget *widget, GtkRequisition *requisition) {
+    UiVis *vis = UI_VIS(widget);
+
+    requisition->width = vis->width*(vis->scaled ? cfg.scale_factor : 1);
+    requisition->height = vis->height*(vis->scaled ? cfg.scale_factor : 1);
+}
+
+static void ui_vis_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
+    UiVis *vis = UI_VIS (widget);
+
+    widget->allocation = *allocation;
+    widget->allocation.x *= (vis->scaled ? cfg.scale_factor : 1);
+    widget->allocation.y *= (vis->scaled ? cfg.scale_factor : 1);
+    if (GTK_WIDGET_REALIZED (widget))
+    {
+        if (vis->event_window != NULL)
+            gdk_window_move_resize(vis->event_window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+        else
+            gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
+    }
+
+    vis->x = widget->allocation.x/(vis->scaled ? cfg.scale_factor : 1);
+    vis->y = widget->allocation.y/(vis->scaled ? cfg.scale_factor : 1);
+}
+
+static gboolean ui_vis_expose(GtkWidget *widget, GdkEventExpose *event) {
+    g_return_val_if_fail (widget != NULL, FALSE);
+    g_return_val_if_fail (UI_IS_VIS (widget), FALSE);
+    g_return_val_if_fail (event != NULL, FALSE);
+
+    UiVis *vis = UI_VIS (widget);
+
+    gint x, y, n, h = 0, h2;
+    gfloat delta;
+    guchar skin_col[2][3];
+    guchar vis_color[24][3];
+    guchar vis_voice_color[256][3], voice_c[3];
+    guchar rgb_data[76 * 16 * 3 * 2 * 2], *ptr, c;
+    guint32 colors[24];
+    GdkColor *fgc, *bgc;
+    GdkRgbCmap *cmap;
+
+    if (!GTK_WIDGET_VISIBLE(widget))
+        return FALSE;
+
+    if (!vis->visible_window)
+        return FALSE;
+
+    skin_get_viscolor(aud_active_skin, vis_color);
+    for (y = 0; y < 24; y++) {
+        colors[y] =
+            vis_color[y][0] << 16 | vis_color[y][1] << 8 | vis_color[y][2];
+    }
+    cmap = gdk_rgb_cmap_new(colors, 24);
+
+    if (!vis->scaled) {
+      if(cfg.vis_type == VIS_VOICEPRINT /*&& cfg.voiceprint_mode != VOICEPRINT_NORMAL*/){
+	memset(rgb_data, 0, 76 * 16 * 3);
+      }
+      else{
+	memset(rgb_data, 0, 76 * 16);
+	for (y = 1; y < 16; y += 2) {
+	  ptr = rgb_data + (y * 76);
+	  for (x = 0; x < 76; x += 2, ptr += 2)
+	    *ptr = 1;
+      }
+      }
+    }
+    else{
+      if(cfg.vis_type == VIS_VOICEPRINT /*&& cfg.voiceprint_mode != VOICEPRINT_NORMAL*/){
+	memset(rgb_data, 0, 3 * 4 * 16 * 76);
+      }
+      else{
+	memset(rgb_data, 0, (guint)(76 * cfg.scale_factor) * 32);
+	for (y = 1; y < 16; y += 2) {
+	  ptr = rgb_data + (y * (guint)(76 * 4 * cfg.scale_factor));
+	  for (x = 0; x < 76; x += 2, ptr += 4) {
+	    *ptr = 1;
+	    *(ptr + 1) = 1;
+	    *(ptr + (guint)(76 * cfg.scale_factor)) = 1;
+	    *(ptr + (guint)(76 * cfg.scale_factor)+1) = 1;
+	}
+      }
+      }
+    }
+    if (cfg.vis_type == VIS_ANALYZER) {
+      for (x = 0; x < 75; x++) {
+	if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0)
+	  h = vis->data[x >> 2];
+	else if (cfg.analyzer_type == ANALYZER_LINES)
+	  h = vis->data[x];
+	if (h && (cfg.analyzer_type == ANALYZER_LINES ||
+		  (x % 4) != 3)) {
+	  if (!vis->scaled) {
+	    ptr = rgb_data + ((16 - h) * 76) + x;
+	    switch (cfg.analyzer_mode) {
+	    case ANALYZER_NORMAL:
+	      for (y = 0; y < h; y++, ptr += 76)
+		*ptr = 18 - h + y;
+	      break;
+	    case ANALYZER_FIRE:
+	      for (y = 0; y < h; y++, ptr += 76)
+		*ptr = y + 2;
+	      break;
+	    case ANALYZER_VLINES:
+	      for (y = 0; y < h; y++, ptr += 76)
+		*ptr = 18 - h;
+	      break;
+	    }
+	  }
+	  else{
+	    ptr = rgb_data + ((16 - h) * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
+	    switch (cfg.analyzer_mode) {
+	    case ANALYZER_NORMAL:
+	      for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
+		*ptr = 18 - h + y;
+		*(ptr + 1) = 18 - h + y;
+		*(ptr + (guint)(76 * cfg.scale_factor)) = 18 - h + y;
+		*(ptr + (guint)(76 * cfg.scale_factor)+1) = 18 - h + y;
+	      }
+	      break;
+	    case ANALYZER_FIRE:
+	      for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
+		*ptr = y + 2;
+		*(ptr + 1) = y + 2;
+		*(ptr + (guint)(76 * cfg.scale_factor)) = y + 2;
+		*(ptr + (guint)(76 * cfg.scale_factor)+1) = y + 2;
+	      }
+	      break;
+	    case ANALYZER_VLINES:
+	      for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
+		*ptr = 18 - h;
+		*(ptr + 1) = 18 - h;
+		*(ptr + (guint)(76 * cfg.scale_factor)) = 18 - h;
+		*(ptr + (guint)(76 * cfg.scale_factor)+1) = 18 - h;
+	      }
+	      
+	      break;
+	    }
+	  }
+	}
+      }
+      if (cfg.analyzer_peaks) {
+	for (x = 0; x < 75; x++) {
+	  if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0)
+	    h = vis->peak[x >> 2];
+	  else if (cfg.analyzer_type == ANALYZER_LINES)
+	    h = vis->peak[x];
+	  if (h && (cfg.analyzer_type == ANALYZER_LINES || (x % 4) != 3)){
+	    
+	    if (!vis->scaled) {
+	      rgb_data[(16 - h) * 76 + x] = 23;
+	    }
+	    else{
+	      ptr = rgb_data + (16 - h) * (guint)(76 * 4 * cfg.scale_factor) + (guint)(x * cfg.scale_factor);
+	      *ptr = 23;
+	      *(ptr + 1) = 23;
+	      *(ptr + (guint)(76 * cfg.scale_factor)) = 23;
+	      *(ptr + (guint)(76 * cfg.scale_factor)+1) = 23;
+	    }
+	  }
+	}
+      }
+    }
+    else if (cfg.vis_type == VIS_VOICEPRINT) {
+      if(!playback_get_paused() && playback_get_playing()){/*Don't scroll when it's paused or stopped*/
+	for (y = 0; y < 16; y ++)
+	  for (x = 75; x > 0; x--)
+	    voiceprint_data[x + y * 76] = voiceprint_data[x-1+y*76];
+	  for(y=0;y<16;y++)
+	    voiceprint_data[y * 76] = vis->data[y];
+      }
+      if(playback_get_playing()){ /*Only draw the data if we're playing*/
+	if(cfg.voiceprint_mode == VOICEPRINT_NORMAL){ 
+	  /* Create color gradient from the skin's background- and foreground color*/
+	  fgc = skin_get_color(aud_active_skin, SKIN_TEXTFG);
+	  bgc = skin_get_color(aud_active_skin, SKIN_TEXTBG);
+	  skin_col[0][0] = fgc->red   >> 8;
+	  skin_col[0][1] = fgc->green >> 8;
+	  skin_col[0][2] = fgc->blue  >> 8;
+	  skin_col[1][0] = bgc->red   >> 8;
+	  skin_col[1][1] = bgc->green >> 8;
+	  skin_col[1][2] = bgc->blue  >> 8;
+	  for(n=0;n<3;n++){
+	    for(x=0;x<256;x++){
+	      if(skin_col[0][n] > skin_col[1][n]){
+		delta = (gfloat)(skin_col[0][n] - skin_col[1][n]) / 256.0;
+		vis_voice_color[x][n] = skin_col[1][n] + (gfloat)(delta * x);
+	      }
+	      else if(skin_col[0][n] == skin_col[1][n]){
+		vis_voice_color[x][n] = skin_col[0][n];
+	      }
+	      else{
+		delta = (gfloat)(skin_col[1][n] - skin_col[0][n]) / 256.0;
+		vis_voice_color[x][n] = skin_col[1][n] - (gfloat)(delta * x);
+	      }
+	    }
+	  }
+	}
+	for (y = 0; y < 16; y ++){
+	  for (x = 0; x < 76; x++){
+	    guint8 d = voiceprint_data[x + y*76];
+	    
+	    if(cfg.voiceprint_mode == VOICEPRINT_NORMAL){
+	      voice_c[0] = vis_voice_color[d][0];
+	      voice_c[1] = vis_voice_color[d][1];
+	      voice_c[2] = vis_voice_color[d][2];
+	    }
+	    else if(cfg.voiceprint_mode == VOICEPRINT_FIRE){
+	      voice_c[0] = d < 64 ? (d * 2) : 255;
+	      voice_c[1] = d < 64 ? 0 : (d < 128 ? (d-64) * 2 : 255);
+	      voice_c[2] = d < 128 ? 0 : (d-128) * 2;
+	      /* Test for black->blue->green->red. Isn't pretty, though...
+		 voice_c[0] = d > 192 ? (d - 192) << 2 : 0;
+		 voice_c[1] = d > 64 ? (d < 128 ? (d - 64) << 2 : (d < 192 ? (192 - d) << 2 : 0)) : 0;
+		 voice_c[2] = d < 64 ? d << 2 : (d < 128 ? (128 - d) << 2 : 0);
+	      */
+	    }
+	    else if(cfg.voiceprint_mode == VOICEPRINT_ICE){	    
+	      voice_c[0] = d;
+	      voice_c[1] = d < 128 ? d * 2 : 255;
+	      voice_c[2] = d < 64 ? d * 4 : 255; 
+	    }
+	    if(!vis->scaled){
+	      for(n=0;n<3;n++)
+		rgb_data[x * 3 + y * 76*3+n] = voice_c[n];
+	    }
+	    else{
+	      ptr = rgb_data + (guint)(x * 3 * cfg.scale_factor) + (guint) (y * 76 * 3 * cfg.scale_factor);
+	      for(n=0;n<3;n++)
+		{
+		  *(ptr + n) = voice_c[n];
+		  *(ptr + n + 3) = voice_c[n];
+		  *(ptr + (guint)(n + 76 * cfg.scale_factor * 3)) = voice_c[n];
+		  *(ptr + (guint)(n + 3 + 76 * cfg.scale_factor * 3)) = voice_c[n];
+		}
+	    }
+	  }
+	}
+      }
+    }
+    if (cfg.vis_type == VIS_SCOPE) {
+      for (x = 0; x < 75; x++) {
+	switch (cfg.scope_mode) {
+	case SCOPE_DOT:
+	  h = vis->data[x];
+	  if (!vis->scaled) {
+	  ptr = rgb_data + ((14 - h) * 76) + x;
+	    *ptr = vis_scope_colors[h + 1];
+	  }else{
+	    ptr = rgb_data + ((14 - h) * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
+	    *ptr = vis_scope_colors[h + 1];
+	    *(ptr + 1) = vis_scope_colors[h + 1];
+	    *(ptr + (guint)(76 * cfg.scale_factor)) = vis_scope_colors[h + 1];
+	    *(ptr + (guint)(76 * cfg.scale_factor)+1) = vis_scope_colors[h + 1];
+	  }
+	  break;
+	case SCOPE_LINE:
+	  if (x != 74) {
+	    h = 14 - vis->data[x];
+	    h2 = 14 - vis->data[x + 1];
+	    if (h > h2) {
+	      y = h;
+	      h = h2;
+	      h2 = y;
+	    }
+	    if (!vis->scaled) {
+	    ptr = rgb_data + (h * 76) + x;
+	    for (y = h; y <= h2; y++, ptr += 76)
+	      *ptr = vis_scope_colors[y - 2];
+	    }
+	    else{
+	      ptr = rgb_data + (h * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
+	      for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
+		*ptr = vis_scope_colors[y - 2];
+		*(ptr + 1) = vis_scope_colors[y - 2];
+		*(ptr + (guint)(76 * cfg.scale_factor)) = vis_scope_colors[y - 2];
+		*(ptr + (guint)(76 * cfg.scale_factor)+1) = vis_scope_colors[y - 2];
+	      }
+	    }
+	  }
+	  else {
+	    h = 14 - vis->data[x];
+	    if (!vis->scaled) {
+	      ptr = rgb_data + (h * 76) + x;
+	      *ptr = vis_scope_colors[h + 1];
+	    }else{
+	      ptr = rgb_data + (h * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
+	      *ptr = vis_scope_colors[h + 1];
+	      *(ptr + 1) = vis_scope_colors[h + 1];
+	      *(ptr + (guint)(76 * cfg.scale_factor)) = vis_scope_colors[h + 1];
+	      *(ptr + (guint)(76 * cfg.scale_factor)+1) = vis_scope_colors[h + 1];
+	    }
+	  }
+	  break;
+	case SCOPE_SOLID:
+	  h = 14 - vis->data[x];
+	  h2 = 8;
+	  c = vis_scope_colors[(gint) vis->data[x]];
+	  if (h > h2) {
+	    y = h;
+	    h = h2;
+	    h2 = y;
+	  }
+	  if (!vis->scaled) {
+	    ptr = rgb_data + (h * 76) + x;
+	    for (y = h; y <= h2; y++, ptr += 76)
+	      *ptr = c;
+	  }else{
+	    ptr = rgb_data + (h * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
+	    for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
+	      *ptr = c;
+	      *(ptr + 1) = c;
+	      *(ptr + (guint)(76 * cfg.scale_factor)) = c;
+	      *(ptr + (guint)(76 * cfg.scale_factor)+1) = c;
+	    }
+	  }
+	  break;
+	}
+      }
+    }
+
+    GdkPixmap *obj = NULL;
+    GdkGC *gc;
+    obj = gdk_pixmap_new(NULL, vis->width*(vis->scaled ? cfg.scale_factor : 1), vis->height*(vis->scaled ? cfg.scale_factor : 1), gdk_rgb_get_visual()->depth);
+    gc = gdk_gc_new(obj);
+
+    if (!vis->scaled) {
+        if (cfg.vis_type == VIS_VOICEPRINT) {
+            gdk_draw_rgb_image(obj, gc, 0, 0, vis->width, vis->height,
+                               GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
+                               76 * 3);
+        } else {
+            gdk_draw_indexed_image(obj, gc, 0, 0, vis->width, vis->height,
+                                   GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
+                                   76 , cmap);
+        }
+    } else {
+        if (cfg.vis_type == VIS_VOICEPRINT) {
+            gdk_draw_rgb_image(obj, gc, 0 << 1, 0 << 1,
+                               vis->width << 1, vis->height << 1,
+                               GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
+                               76 * 2 * 3);
+        } else {
+            gdk_draw_indexed_image(obj, gc, 0 << 1, 0 << 1,
+                                   vis->width << 1, vis->height << 1,
+                                   GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
+                                   76 * 2 , cmap);
+        }
+    }
+
+    gdk_draw_drawable (widget->window, gc, obj, 0, 0, 0, 0,
+                       vis->width*(vis->scaled ? cfg.scale_factor : 1), vis->height*(vis->scaled ? cfg.scale_factor : 1));
+    g_object_unref(obj);
+    g_object_unref(gc);
+    gdk_rgb_cmap_free(cmap);
+    return FALSE;
+}
+
+static void ui_vis_toggle_scaled(UiVis *vis) {
+    GtkWidget *widget = GTK_WIDGET (vis);
+    vis->scaled = !vis->scaled;
+
+    gtk_widget_set_size_request(widget, vis->width*(vis->scaled ? cfg.scale_factor : 1), vis->height*(vis->scaled ? cfg.scale_factor : 1));
+
+    gtk_widget_queue_draw(GTK_WIDGET(vis));
+}
+
+void ui_vis_draw_pixel(GtkWidget *widget, guchar* texture, gint x, gint y, guint8 colour) {
+    UiVis *vis = UI_VIS (widget);
+    if (vis->scaled){
+        texture[y * 76 + x] = colour;
+        texture[y * 76 + x + 1] = colour;
+        texture[y * 76 * 4 + x] = colour;
+        texture[y * 76 * 4 + x + 1] = colour;
+    } else {
+        texture[y * 76 + x] = colour;
+    }
+}
+
+void ui_vis_set_visible(GtkWidget *widget, gboolean window_is_visible)
+{
+    UiVis *vis;
+    gboolean widget_is_visible;
+
+    g_return_if_fail(UI_IS_VIS(widget));
+
+    vis = UI_VIS (widget);
+    widget_is_visible = GTK_WIDGET_VISIBLE(widget);
+
+    vis->visible_window = window_is_visible;
+
+    if (GTK_WIDGET_REALIZED (widget))
+    {
+        if ( widget_is_visible )
+            gtk_widget_hide(widget);
+
+        gtk_widget_unrealize(widget);
+        gtk_widget_realize(widget);
+
+        if ( widget_is_visible )
+            gtk_widget_show(widget);
+    }
+
+    if (widget_is_visible)
+        gtk_widget_queue_resize(widget);
+}
+
+void ui_vis_clear_data(GtkWidget *widget) {
+    g_return_if_fail(UI_IS_VIS(widget));
+
+    gint i;
+    UiVis *vis = UI_VIS (widget);
+
+    memset(voiceprint_data, 0, 16*76);
+    for (i = 0; i < 75; i++) {
+        vis->data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0;
+        vis->peak[i] = 0;
+    }
+}
+
+void ui_vis_timeout_func(GtkWidget *widget, guchar * data) {
+    g_return_if_fail(UI_IS_VIS(widget));
+
+    UiVis *vis = UI_VIS (widget);
+    static GTimer *timer = NULL;
+    gulong micros = 9999999;
+    gboolean falloff = FALSE;
+    gint i;
+
+    if (!timer) {
+        timer = g_timer_new();
+        g_timer_start(timer);
+    }
+    else {
+      g_timer_elapsed(timer, &micros);
+      if (micros > 14000)
+	g_timer_reset(timer);
+    }
+    if (cfg.vis_type == VIS_ANALYZER) {
+        if (micros > 14000)
+            falloff = TRUE;
+        if (data || falloff) {
+            for (i = 0; i < 75; i++) {
+                if (data && data[i] > vis->data[i]) {
+                    vis->data[i] = data[i];
+                    if (vis->data[i] > vis->peak[i]) {
+                        vis->peak[i] = vis->data[i];
+                        vis->peak_speed[i] = 0.01;
+
+                    }
+                    else if (vis->peak[i] > 0.0) {
+                        vis->peak[i] -= vis->peak_speed[i];
+                        vis->peak_speed[i] *=
+                            vis_pfalloff_speeds[cfg.peaks_falloff];
+                        if (vis->peak[i] < vis->data[i])
+                            vis->peak[i] = vis->data[i];
+                        if (vis->peak[i] < 0.0)
+                            vis->peak[i] = 0.0;
+                    }
+                }
+                else if (falloff) {
+                    if (vis->data[i] > 0.0) {
+                        vis->data[i] -=
+                            vis_afalloff_speeds[cfg.analyzer_falloff];
+                        if (vis->data[i] < 0.0)
+                            vis->data[i] = 0.0;
+                    }
+                    if (vis->peak[i] > 0.0) {
+                        vis->peak[i] -= vis->peak_speed[i];
+                        vis->peak_speed[i] *=
+                            vis_pfalloff_speeds[cfg.peaks_falloff];
+                        if (vis->peak[i] < vis->data[i])
+                            vis->peak[i] = vis->data[i];
+                        if (vis->peak[i] < 0.0)
+                            vis->peak[i] = 0.0;
+                    }
+                }
+            }
+        }
+    }
+    else if (cfg.vis_type == VIS_VOICEPRINT && data){
+      for(i = 0; i < 16; i++)
+	{
+	  vis->data[i] = data[15 - i];
+	}
+    }
+    else if (data) {
+        for (i = 0; i < 75; i++)
+            vis->data[i] = data[i];
+    }
+
+    if (micros > 14000) {
+        if (!vis->refresh_delay) {
+            gtk_widget_queue_draw(widget);
+            vis->refresh_delay = vis_redraw_delays[cfg.vis_refresh];
+        }
+        vis->refresh_delay--;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/legacy/ui_vis.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,98 @@
+/*
+ * Audacious - a cross-platform multimedia player
+ * Copyright (c) 2007  Audacious development team.
+ *
+ * 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; under version 3 of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses>.
+ *
+ * The Audacious team does not consider modular code linking to
+ * Audacious or using our public API to be a derived work.
+ */
+
+#ifndef AUDACIOUS_UI_VIS_H
+#define AUDACIOUS_UI_VIS_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UI_VIS(obj)          GTK_CHECK_CAST (obj, ui_vis_get_type (), UiVis)
+#define UI_VIS_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_vis_get_type (), UiVisClass)
+#define UI_IS_VIS(obj)       GTK_CHECK_TYPE (obj, ui_vis_get_type ())
+
+typedef enum {
+    VIS_ANALYZER, VIS_SCOPE, VIS_VOICEPRINT, VIS_OFF
+} VisType;
+
+typedef enum {
+    ANALYZER_NORMAL, ANALYZER_FIRE, ANALYZER_VLINES
+} AnalyzerMode;
+
+typedef enum {
+    ANALYZER_LINES, ANALYZER_BARS
+} AnalyzerType;
+
+typedef enum {
+    SCOPE_DOT, SCOPE_LINE, SCOPE_SOLID
+} ScopeMode;
+typedef enum {
+  VOICEPRINT_NORMAL, VOICEPRINT_FIRE, VOICEPRINT_ICE
+} VoiceprintMode;
+
+
+typedef enum {
+    VU_NORMAL, VU_SMOOTH
+} VUMode;
+
+typedef enum {
+    REFRESH_FULL, REFRESH_HALF, REFRESH_QUARTER, REFRESH_EIGTH
+} RefreshRate;
+
+typedef enum {
+    FALLOFF_SLOWEST, FALLOFF_SLOW, FALLOFF_MEDIUM, FALLOFF_FAST,
+    FALLOFF_FASTEST
+} FalloffSpeed;
+
+typedef struct _UiVis        UiVis;
+typedef struct _UiVisClass   UiVisClass;
+
+struct _UiVis {
+    GtkWidget        widget;
+
+    gint             x, y, width, height;
+    gfloat           data[75], peak[75], peak_speed[75];
+    gint             refresh_delay;
+    gboolean         scaled;
+    GtkWidget        *fixed;
+    gboolean         visible_window;
+    GdkWindow        *event_window;
+};
+
+struct _UiVisClass {
+    GtkWidgetClass          parent_class;
+    void (* doubled)        (UiVis *vis);
+};
+
+GtkWidget* ui_vis_new (GtkWidget *fixed, gint x, gint y, gint width);
+GtkType ui_vis_get_type(void);
+void ui_vis_set_vis(GtkWidget *widget, gint num);
+void ui_vis_clear_data(GtkWidget *widget);
+void ui_vis_timeout_func(GtkWidget *widget, guchar * data);
+void ui_vis_set_visible(GtkWidget *widget, gboolean window_is_visible);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDACIOUS_UI_VIS_H */
--- a/src/audacious/main.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/main.c	Wed Aug 06 22:33:27 2008 +0300
@@ -58,8 +58,7 @@
 #include "playlist.h"
 #include "pluginenum.h"
 #include "signals.h"
-#include "ui_manager.h"
-#include "ui_skin.h"
+#include "legacy/ui_manager.h"
 #include "util.h"
 #include "vfs.h"
 
@@ -77,7 +76,6 @@
     gint session;
     gboolean play, stop, pause, fwd, rew, play_pause, show_jump_box;
     gboolean enqueue, mainwin, remote, activate;
-    gboolean load_skins;
     gboolean no_log;
     gboolean enqueue_to_temp;
     gboolean version;
@@ -288,37 +286,29 @@
 #ifdef USE_DBUS
     if (is_running)
     {
-        if (options.load_skins)
-        {
-            audacious_remote_set_skin(session, filenames[0]);
-            skin_install_skin(filenames[0]);
-        }
-        else
-        {
-            GList *i;
+        GList *i;
 
-            if (options.enqueue_to_temp)
-                audacious_remote_playlist_enqueue_to_temp(session, filenames[0]);
+        if (options.enqueue_to_temp)
+            audacious_remote_playlist_enqueue_to_temp(session, filenames[0]);
 
-            if (options.enqueue && options.play)
-                pos = audacious_remote_get_playlist_length(session);
+        if (options.enqueue && options.play)
+            pos = audacious_remote_get_playlist_length(session);
 
-            if (!options.enqueue)
-            {
-                audacious_remote_playlist_clear(session);
-                audacious_remote_stop(session);
-            }
+        if (!options.enqueue)
+        {
+            audacious_remote_playlist_clear(session);
+            audacious_remote_stop(session);
+        }
 
-            for (i = fns; i != NULL; i = i->next)
-                audacious_remote_playlist_add_url_string(session, i->data);
+        for (i = fns; i != NULL; i = i->next)
+            audacious_remote_playlist_add_url_string(session, i->data);
 
-            if (options.enqueue && options.play &&
-                audacious_remote_get_playlist_length(session) > pos)
-                audacious_remote_set_playlist_pos(session, pos);
+        if (options.enqueue && options.play &&
+            audacious_remote_get_playlist_length(session) > pos)
+            audacious_remote_set_playlist_pos(session, pos);
 
-            if (!options.enqueue)
-                audacious_remote_play(session);
-        }
+        if (!options.enqueue)
+            audacious_remote_play(session);
     }
     else /* !is_running */
 #endif
--- a/src/audacious/main.h	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/main.h	Wed Aug 06 22:33:27 2008 +0300
@@ -27,7 +27,7 @@
 #define AUDACIOUS_MAIN_H
 
 #ifdef _AUDACIOUS_CORE
-# include "ui_main.h"
+# include "legacy/ui_main.h"
 # ifdef USE_DBUS
 #  include "dbus-service.h"
 # endif
--- a/src/audacious/objects.xml	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/objects.xml	Wed Aug 06 22:33:27 2008 +0300
@@ -413,19 +413,6 @@
             <arg type="u" direction="out" name="qpos"/>
         </method>
 
-        <!-- Get skin -->
-        <method name="GetSkin">
-            <!-- Return filename of desired song -->
-            <arg type="s" direction="out" name="skin"/>
-        </method>
-
-        <!-- Set skin -->
-        <method name="SetSkin">
-            <annotation name="org.freedesktop.DBus.GLib.NoReply" value=""/>
-            <!-- Return filename of desired song -->
-            <arg type="s" name="skin"/>
-        </method>
-
         <!-- Get Info -->
         <method name="GetInfo">
             <arg type="i" direction="out" name="rate"/>
--- a/src/audacious/playlist.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/playlist.c	Wed Aug 06 22:33:27 2008 +0300
@@ -61,7 +61,7 @@
 #include "playlist_evmessages.h"
 #include "pluginenum.h"
 #include "strings.h"
-#include "ui_playlist.h"
+#include "legacy/ui_playlist.h"
 #include "util.h"
 #include "vfs.h"
 
@@ -1212,8 +1212,8 @@
 
     if (restart_playing)
         playback_initiate();
-
-    hook_call("playlist update", playlist);
+    else
+        hook_call("playlist update", playlist);
 }
 
 void
@@ -2437,9 +2437,10 @@
                     /* Entry disappeared while we looked it up.
                        Restart. */
                     node = playlist->entries;
-                else if ((entry->tuple != NULL || entry->title != NULL) && 
+                else if ((entry->tuple != NULL) ||
+			 (entry->title != NULL && 
                          tuple_get_int(entry->tuple, FIELD_LENGTH, NULL) > -1 &&
-                         tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1)
+                         tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1))
                 {
                     update_playlistwin = TRUE;
                     break; /* hmmm... --asphyx */
@@ -2488,9 +2489,10 @@
                         node = g_list_nth(playlist->entries,
                                           playlistwin_get_toprow());
                 }
-                else if ((entry->tuple != NULL || entry->title != NULL) && 
+                else if ((entry->tuple != NULL) ||
+			 (entry->title != NULL && 
                          tuple_get_int(entry->tuple, FIELD_LENGTH, NULL) > -1 &&
-                         tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1) {
+                         tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1)) {
                     update_playlistwin = TRUE;
                 }
             }
--- a/src/audacious/plugin.h	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/plugin.h	Wed Aug 06 22:33:27 2008 +0300
@@ -46,6 +46,7 @@
 #include "audacious/main.h"
 #include "audacious/preferences.h"
 #include "audacious/interface.h"
+#include "audacious/equalizer_preset.h"
 
 #define PLUGIN(x)         ((Plugin *)(x))
 #define INPUT_PLUGIN(x)   ((InputPlugin *)(x))
@@ -635,6 +636,13 @@
 
     void (*create_widgets)(GtkBox *box, PreferencesWidget *widgets, gint amt);
 
+    GList *(*equalizer_read_presets)(const gchar * basename);
+    void (*equalizer_write_preset_file)(GList * list, const gchar * basename);
+    GList *(*import_winamp_eqf)(VFSFile * file);
+    void (*save_preset_file)(EqualizerPreset *preset, const gchar * filename);
+    EqualizerPreset *(*equalizer_read_aud_preset)(const gchar * filename);
+    EqualizerPreset *(*load_preset_file)(const gchar *filename);
+
     /* VFS endianess helper functions */
     gboolean (*vfs_fget_le16)(guint16 *value, VFSFile *stream);
     gboolean (*vfs_fget_le32)(guint32 *value, VFSFile *stream);
@@ -994,6 +1002,13 @@
 
 #define aud_create_widgets          _audvt->create_widgets
 
+#define aud_equalizer_read_presets  _audvt->equalizer_read_presets
+#define aud_equalizer_write_preset_file _audvt->equalizer_write_preset_file
+#define aud_import_winamp_eqf       _audvt->import_winamp_eqf
+#define aud_save_preset_file        _audvt->save_preset_file
+#define aud_equalizer_read_aud_preset _audvt->equalizer_read_aud_preset
+#define aud_load_preset_file        _audvt->load_preset_file
+
 #include "audacious/auddrct.h"
 
 /* for multi-file plugins :( */
--- a/src/audacious/pluginenum.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/pluginenum.c	Wed Aug 06 22:33:27 2008 +0300
@@ -54,6 +54,7 @@
 #include "vfs_buffer.h"
 #include "vfs_buffered_file.h"
 #include "volumecontrol.h"
+#include "equalizer_preset.h"
 
 #include "ui_fileinfo.h"
 #include "ui_fileinfopopup.h"
@@ -388,6 +389,13 @@
     .calc_stereo_pcm = calc_stereo_pcm,
 
     .create_widgets = create_widgets,
+
+    .equalizer_read_presets = equalizer_read_presets,
+    .equalizer_write_preset_file = equalizer_write_preset_file,
+    .import_winamp_eqf = import_winamp_eqf,
+    .save_preset_file = save_preset_file,
+    .equalizer_read_aud_preset = equalizer_read_aud_preset,
+    .load_preset_file = load_preset_file,
 };
 
 /*****************************************************************/
@@ -625,14 +633,16 @@
 static void
 plugin2_dispose(GModule *module, const gchar *str, ...)
 {
-    gchar buf[4096];
+    gchar *buf;
     va_list va;
 
     va_start(va, str);
-    vsnprintf(buf, 4096, str, va);
+    buf = g_strdup_vprintf(str, va);
     va_end(va);
 
     g_message("*** %s\n", buf);
+    g_free(buf);
+    
     g_module_close(module);
 }
 
--- a/src/audacious/signals.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/signals.c	Wed Aug 06 22:33:27 2008 +0300
@@ -39,6 +39,8 @@
 #include "eggsmclient.h"
 #endif
 
+typedef void (*SignalHandler) (gint);
+
 gint linuxthread_signal_number = 0;
 
 static void
@@ -132,8 +134,6 @@
 /* for linuxthread */
 /********************************************************************************/
 
-typedef void (*SignalHandler) (gint);
-
 static void *
 signal_process_signals_linuxthread (void *data)
 {
--- a/src/audacious/ui_albumart.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_albumart.c	Wed Aug 06 22:33:27 2008 +0300
@@ -30,7 +30,6 @@
 
 #include "ui_fileinfopopup.h"
 #include "main.h"
-#include "ui_main.h"
 #include "playlist.h"
 #include "playback.h"
 
--- a/src/audacious/ui_dock.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,531 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team
- *
- *  Based on BMP:
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#include "ui_dock.h"
-
-#include <gdk/gdk.h>
-#include <stdlib.h>
-#include "main.h"
-#include "ui_skinned_window.h"
-
-#include "platform/smartinclude.h"
-
-static GList *dock_window_list = NULL;
-
-struct _DockedWindow {
-    GtkWindow *w;
-    gint offset_x, offset_y;
-};
-
-typedef struct _DockedWindow DockedWindow;
-
-
-static gint
-docked_list_compare(DockedWindow * a, DockedWindow * b)
-{
-    if (a->w == b->w)
-        return 0;
-    return 1;
-}
-
-static void
-snap_edge(gint * x, gint * y, gint w, gint h, gint bx, gint by,
-          gint bw, gint bh)
-{
-    gint sd = cfg.snap_distance;
-
-    if ((*x + w > bx - sd) && (*x + w < bx + sd) &&
-        (*y > by - h - sd) && (*y < by + bh + sd)) {
-        *x = bx - w;
-        if ((*y > by - sd) && (*y < by + sd))
-            *y = by;
-        if ((*y + h > by + bh - sd) && (*y + h < by + bh + sd))
-            *y = by + bh - h;
-    }
-    if ((*x > bx + bw - sd) && (*x < bx + bw + sd) &&
-        (*y > by - h - sd) && (*y < by + bh + sd)) {
-        *x = bx + bw;
-        if ((*y > by - sd) && (*y < by + sd))
-            *y = by;
-        if ((*y + h > by + bh - sd) && (*y + h < by + bh + sd))
-            *y = by + bh - h;
-    }
-}
-
-static void
-snap(gint * x, gint * y, gint w, gint h, gint bx, gint by, gint bw, gint bh)
-{
-    snap_edge(x, y, w, h, bx, by, bw, bh);
-    snap_edge(y, x, h, w, by, bx, bh, bw);
-}
-
-static void
-calc_snap_offset(GList * dlist, GList * wlist, gint x, gint y,
-                 gint * off_x, gint * off_y)
-{
-    gint nx, ny, nw, nh, sx, sy, sw, sh;
-    GtkWindow *w;
-    GList *dnode, *wnode;
-    DockedWindow temp, *dw;
-
-
-    *off_x = 0;
-    *off_y = 0;
-
-    if (!cfg.snap_windows)
-        return;
-
-    /*
-     * FIXME: Why not break out of the loop when we find someting
-     * to snap to?
-     */
-    for (dnode = dlist; dnode; dnode = g_list_next(dnode)) {
-        dw = dnode->data;
-        gtk_window_get_size(dw->w, &nw, &nh);
-
-        nx = dw->offset_x + *off_x + x;
-        ny = dw->offset_y + *off_y + y;
-
-        /* Snap to screen edges */
-        if (abs(nx) < cfg.snap_distance)
-            *off_x -= nx;
-        if (abs(ny) < cfg.snap_distance)
-            *off_y -= ny;
-        if (abs(nx + nw - gdk_screen_width()) < cfg.snap_distance)
-            *off_x -= nx + nw - gdk_screen_width();
-        if (abs(ny + nh - gdk_screen_height()) < cfg.snap_distance)
-            *off_y -= ny + nh - gdk_screen_height();
-
-        /* Snap to other windows */
-        for (wnode = wlist; wnode; wnode = g_list_next(wnode)) {
-            temp.w = wnode->data;
-            if (g_list_find_custom
-                (dlist, &temp, (GCompareFunc) docked_list_compare))
-                /* These windows are already docked */
-                continue;
-
-            w = GTK_WINDOW(wnode->data);
-            gtk_window_get_position(w, &sx, &sy);
-            gtk_window_get_size(w, &sw, &sh);
-
-            nx = dw->offset_x + *off_x + x;
-            ny = dw->offset_y + *off_y + y;
-
-            snap(&nx, &ny, nw, nh, sx, sy, sw, sh);
-
-            *off_x += nx - (dw->offset_x + *off_x + x);
-            *off_y += ny - (dw->offset_y + *off_y + y);
-        }
-    }
-}
-
-
-static gboolean
-is_docked(gint a_x, gint a_y, gint a_w, gint a_h,
-          gint b_x, gint b_y, gint b_w, gint b_h)
-{
-    if (((a_x == b_x + b_w) || (a_x + a_w == b_x)) &&
-        (b_y + b_h >= a_y) && (b_y <= a_y + a_h))
-        return TRUE;
-
-    if (((a_y == b_y + b_h) || (a_y + a_h == b_y)) &&
-        (b_x >= a_x - b_w) && (b_x <= a_x + a_w))
-        return TRUE;
-
-    return FALSE;
-}
-
-/*
- * Builds a list of all windows that are docked to the window "w".
- * Recursively adds all windows that are docked to the windows that are
- * docked to "w" and so on...
- * FIXME: init_off_?  ?
- */
-
-static GList *
-get_docked_list(GList * dlist, GList * wlist, GtkWindow * w,
-                gint init_off_x, gint init_off_y)
-{
-    GList *node;
-    DockedWindow *dwin, temp;
-    gint w_x, w_y, w_width, w_height;
-    gint t_x, t_y, t_width, t_height;
-
-
-    gtk_window_get_position(w, &w_x, &w_y);
-    gtk_window_get_size(w, &w_width, &w_height);
-    if (!dlist) {
-        dwin = g_new0(DockedWindow, 1);
-        dwin->w = w;
-        dlist = g_list_append(dlist, dwin);
-    }
-
-    for (node = wlist; node; node = g_list_next(node)) {
-        temp.w = node->data;
-        if (g_list_find_custom
-            (dlist, &temp, (GCompareFunc) docked_list_compare))
-            continue;
-
-        gtk_window_get_position(GTK_WINDOW(node->data), &t_x, &t_y);
-        gtk_window_get_size(GTK_WINDOW(node->data), &t_width, &t_height);
-        if (is_docked
-            (w_x, w_y, w_width, w_height, t_x, t_y, t_width, t_height)) {
-            dwin = g_new0(DockedWindow, 1);
-            dwin->w = node->data;
-
-            dwin->offset_x = t_x - w_x + init_off_x;
-            dwin->offset_y = t_y - w_y + init_off_y;
-
-            dlist = g_list_append(dlist, dwin);
-
-            dlist =
-                get_docked_list(dlist, wlist, dwin->w, dwin->offset_x,
-                                dwin->offset_y);
-        }
-    }
-    return dlist;
-}
-
-static void
-free_docked_list(GList * dlist)
-{
-    GList *node;
-
-    for (node = dlist; node; node = g_list_next(node))
-        g_free(node->data);
-    g_list_free(dlist);
-}
-
-static void
-docked_list_move(GList * list, gint x, gint y)
-{
-    GList *node;
-    DockedWindow *dw;
-
-    for (node = list; node; node = g_list_next(node)) {
-        dw = node->data;
-        gtk_window_move(dw->w, x + dw->offset_x, y + dw->offset_y);
-
-        SkinnedWindow *window = SKINNED_WINDOW(dw->w);
-        if (window) {
-            switch(window->type) {
-
-            case WINDOW_MAIN:
-                cfg.player_x = x + dw->offset_x;
-                cfg.player_y = y + dw->offset_y;
-                break;
-            case WINDOW_EQ:
-                cfg.equalizer_x = x + dw->offset_x;
-                cfg.equalizer_y = y + dw->offset_y;
-                break;
-            case WINDOW_PLAYLIST:
-                cfg.playlist_x = x + dw->offset_x;
-                cfg.playlist_y = y + dw->offset_y;
-                break;
-            }
-
-            window->x = x + dw->offset_x;
-            window->y = y + dw->offset_y;
-        }
-    }
-}
-
-static GList *
-shade_move_list(GList * list, GtkWindow * widget, gint offset)
-{
-    gint x, y, w, h;
-    GList *node;
-    DockedWindow *dw;
-
-    gtk_window_get_position(widget, &x, &y);
-    gtk_window_get_size(widget, &w, &h);
-
-
-    for (node = list; node;) {
-        gint dx, dy, dwidth, dheight;
-
-        dw = node->data;
-        gtk_window_get_position(dw->w, &dx, &dy);
-        gtk_window_get_size(dw->w, &dwidth, &dheight);
-        if (is_docked(x, y, w, h, dx, dy, dwidth, dheight) &&
-            ((dx + dwidth) > x && dx < (x + w))) {
-            list = g_list_remove_link(list, node);
-            g_list_free_1(node);
-
-            node = list = shade_move_list(list, dw->w, offset);
-        }
-        else
-            node = g_list_next(node);
-    }
-    gtk_window_move(widget, x, y + offset);
-    return list;
-}
-
-/*
- * Builds a list of the windows in the list of DockedWindows "winlist"
- * that are docked to the top or bottom of the window, and recursively
- * adds all windows that are docked to the top or bottom of that window,
- * and so on...
- * Note: The data in "winlist" is not copied.
- */
-static GList *
-find_shade_list(GtkWindow * widget, GList * winlist, GList * shade_list)
-{
-    gint x, y, w, h;
-    gint dx, dy, dwidth, dheight;
-    GList *node;
-
-    gtk_window_get_position(widget, &x, &y);
-    gtk_window_get_size(widget, &w, &h);
-    for (node = winlist; node; node = g_list_next(node)) {
-        DockedWindow *dw = node->data;
-        if (g_list_find_custom
-            (shade_list, dw, (GCompareFunc) docked_list_compare))
-            continue;
-        gtk_window_get_position(dw->w, &dx, &dy);
-        gtk_window_get_size(dw->w, &dwidth, &dheight);
-
-        /* FIXME. Is the is_docked() necessary? */
-        if (is_docked(x, y, w, h, dx, dy, dwidth, dheight) &&
-            ((dx + dwidth) > x && dx < (x + w))) {
-            shade_list = g_list_append(shade_list, dw);
-            shade_list = find_shade_list(dw->w, winlist, shade_list);
-        }
-    }
-    return shade_list;
-}
-
-void
-dock_window_resize(GtkWindow * widget, gint new_w, gint new_h, gint w, gint h)
-{
-    gdk_window_set_hints(GTK_WIDGET(widget)->window, 0, 0, MIN(w, new_w),
-                         MIN(h, new_h), MAX(w, new_w), MAX(h, new_h),
-                         GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
-    gdk_window_resize(GTK_WIDGET(widget)->window, new_w, new_h);
-    gdk_window_set_hints(GTK_WIDGET(widget)->window, 0, 0, new_w, new_h,
-                         new_w, new_h, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
-}
-
-void
-dock_shade(GList * window_list, GtkWindow * widget, gint new_h)
-{
-    gint x, y, w, h, off_y, orig_off_y;
-    GList *node, *docked_list, *slist;
-    DockedWindow *dw;
-
-    gtk_window_get_position(widget, &x, &y);
-    gtk_window_get_size(widget, &w, &h);
-
-    if (cfg.show_wm_decorations) {
-        dock_window_resize(widget, w, new_h, w, h);
-        return;
-    }
-
-    docked_list = get_docked_list(NULL, window_list, widget, 0, 0);
-    slist = find_shade_list(widget, docked_list, NULL);
-
-    off_y = new_h - h;
-    do {
-        orig_off_y = off_y;
-        for (node = slist; node; node = g_list_next(node)) {
-            gint dx, dy, dwidth, dheight;
-
-            dw = node->data;
-            if (dw->w == widget)
-                continue;
-            gtk_window_get_position(dw->w, &dx, &dy);
-            gtk_window_get_size(dw->w, &dwidth, &dheight);
-            if ((dy >= y) && ((dy + off_y + dheight) > gdk_screen_height()))
-                off_y -= (dy + off_y + dheight) - gdk_screen_height();
-            else if ((dy >= y) && ((dy + dheight) == gdk_screen_height()))
-                off_y = 0;
-
-            if (((dy >= y) && ((dy + off_y) < 0)))
-                off_y -= dy + off_y;
-            if ((dy < y) && ((dy + (off_y - (new_h - h))) < 0))
-                off_y -= dy + (off_y - (new_h - h));
-        }
-    } while (orig_off_y != off_y);
-    if (slist) {
-        GList *mlist = g_list_copy(slist);
-
-        /* Remove this widget from the list */
-        for (node = mlist; node; node = g_list_next(node)) {
-            dw = node->data;
-            if (dw->w == widget) {
-                mlist = g_list_remove_link(mlist, node);
-                g_list_free_1(node);
-                break;
-            }
-        }
-        for (node = mlist; node;) {
-            GList *temp;
-            gint dx, dy, dwidth, dheight;
-
-            dw = node->data;
-
-            gtk_window_get_position(dw->w, &dx, &dy);
-            gtk_window_get_size(dw->w, &dwidth, &dheight);
-            /*
-             * Find windows that are directly docked to this window,
-             * move it, and any windows docked to that window again
-             */
-            if (is_docked(x, y, w, h, dx, dy, dwidth, dheight) &&
-                ((dx + dwidth) > x && dx < (x + w))) {
-                mlist = g_list_remove_link(mlist, node);
-                g_list_free_1(node);
-                if (dy > y)
-                    temp = shade_move_list(mlist, dw->w, off_y);
-                else if (off_y - (new_h - h) != 0)
-                    temp = shade_move_list(mlist, dw->w, off_y - (new_h - h));
-                else
-                    temp = mlist;
-                node = mlist = temp;
-            }
-            else
-                node = g_list_next(node);
-        }
-        g_list_free(mlist);
-    }
-    g_list_free(slist);
-    free_docked_list(docked_list);
-    gtk_window_move(widget, x, y + off_y - (new_h - h));
-    dock_window_resize(widget, w, new_h, w, h);
-}
-
-void
-dock_move_press(GList * window_list, GtkWindow * w,
-                GdkEventButton * event, gboolean move_list)
-{
-    gint mx, my;
-    DockedWindow *dwin;
-
-    if (cfg.show_wm_decorations)
-        return;
-
-    gtk_window_present(w);
-    mx = event->x;
-    my = event->y;
-    gtk_object_set_data(GTK_OBJECT(w), "move_offset_x", GINT_TO_POINTER(mx));
-    gtk_object_set_data(GTK_OBJECT(w), "move_offset_y", GINT_TO_POINTER(my));
-    if (move_list)
-        gtk_object_set_data(GTK_OBJECT(w), "docked_list",
-                            get_docked_list(NULL, window_list, w, 0, 0));
-    else {
-        dwin = g_new0(DockedWindow, 1);
-        dwin->w = w;
-        gtk_object_set_data(GTK_OBJECT(w), "docked_list",
-                            g_list_append(NULL, dwin));
-    }
-    gtk_object_set_data(GTK_OBJECT(w), "window_list", window_list);
-    gtk_object_set_data(GTK_OBJECT(w), "is_moving", GINT_TO_POINTER(1));
-}
-
-void
-dock_move_motion(GtkWindow * w, GdkEventMotion * event)
-{
-    gint offset_x, offset_y, x, y;
-    GList *dlist;
-    GList *window_list;
-
-    if (!gtk_object_get_data(GTK_OBJECT(w), "is_moving"))
-        return;
-
-    offset_x =
-        GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(w), "move_offset_x"));
-    offset_y =
-        GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(w), "move_offset_y"));
-    dlist = gtk_object_get_data(GTK_OBJECT(w), "docked_list");
-    window_list = gtk_object_get_data(GTK_OBJECT(w), "window_list");
-
-    x = event->x_root - offset_x;
-    y = event->y_root - offset_y;
-
-    calc_snap_offset(dlist, window_list, x, y, &offset_x, &offset_y);
-    x += offset_x;
-    y += offset_y;
-
-    docked_list_move(dlist, x, y);
-}
-
-void
-dock_move_release(GtkWindow * w)
-{
-    GList *dlist;
-    gtk_object_remove_data(GTK_OBJECT(w), "is_moving");
-    gtk_object_remove_data(GTK_OBJECT(w), "move_offset_x");
-    gtk_object_remove_data(GTK_OBJECT(w), "move_offset_y");
-    if ((dlist = gtk_object_get_data(GTK_OBJECT(w), "docked_list")) != NULL)
-        free_docked_list(dlist);
-    gtk_object_remove_data(GTK_OBJECT(w), "docked_list");
-    gtk_object_remove_data(GTK_OBJECT(w), "window_list");
-}
-
-gboolean
-dock_is_moving(GtkWindow * w)
-{
-    if (gtk_object_get_data(GTK_OBJECT(w), "is_moving"))
-        return TRUE;
-    return FALSE;
-}
-
-GList *
-dock_add_window(GList * list, GtkWindow * window)
-{
-    return g_list_append(list, window);
-}
-
-GList *
-dock_remove_window(GList * list, GtkWindow * window)
-{
-    return g_list_remove(list, window);
-}
-
-GList *
-dock_window_set_decorated(GList * list, GtkWindow * window,
-                          gboolean decorated)
-{
-    if (gtk_window_get_decorated(window) == decorated)
-        return list;
-
-    if (decorated)
-        list = dock_remove_window(list, window);
-    else
-        list = dock_add_window(list, window);
-
-    gtk_window_set_decorated(window, decorated);
-
-    return list;
-}
-
-GList *
-get_dock_window_list() {
-    return dock_window_list;
-}
-
-void
-set_dock_window_list(GList * list) {
-    dock_window_list = list;
-}
--- a/src/audacious/ui_dock.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team
- *
- *  Based on BMP:
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_DOCK_H
-#define AUDACIOUS_UI_DOCK_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-void dock_set_uposition(GtkWindow * widget, gint x, gint y);
-GList *dock_add_window(GList * window_list, GtkWindow * window);
-GList *dock_remove_window(GList * window_list, GtkWindow * window);
-void dock_move_press(GList * window_list, GtkWindow * w,
-                     GdkEventButton * event, gboolean move_list);
-void dock_move_motion(GtkWindow * w, GdkEventMotion * event);
-void dock_move_release(GtkWindow * w);
-void dock_get_widget_pos(GtkWindow * w, gint * x, gint * y);
-gboolean dock_is_moving(GtkWindow * w);
-void dock_shade(GList * window_list, GtkWindow * widget, gint new_h);
-
-GList *dock_window_set_decorated(GList * list, GtkWindow * window,
-                                 gboolean decorated);
-void dock_window_resize(GtkWindow * widget, gint new_w, gint new_h, gint w, gint h);
-
-GList *get_dock_window_list();
-void set_dock_window_list(GList * list);
-
-#endif /* AUDACIOUS_UI_DOCK_H */
--- a/src/audacious/ui_equalizer.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1521 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  Based on BMP:
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-/*#define AUD_DEBUG*/
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include "ui_equalizer.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <stdio.h>
-#include <math.h>
-#include <string.h>
-
-#include "platform/smartinclude.h"
-#include "ui_skin.h"
-#include "input.h"
-#include "main.h"
-#include "ui_manager.h"
-#include "actions-equalizer.h"
-#include "playlist.h"
-#include "ui_playlist.h"
-#include "util.h"
-#include "output.h"
-#include "equalizer_flow.h"
-
-#include "rcfile.h"
-#include "vfs.h"
-
-#include "images/audacious_eq.xpm"
-
-#include "ui_dock.h"
-#include "ui_skinned_window.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_horizontal_slider.h"
-#include "ui_skinned_equalizer_slider.h"
-#include "ui_skinned_equalizer_graph.h"
-
-enum PresetViewCols {
-    PRESET_VIEW_COL_NAME,
-    PRESET_VIEW_N_COLS
-};
-
-struct _EqualizerPreset {
-    gchar *name;
-    gfloat preamp, bands[AUD_EQUALIZER_NBANDS];
-};
-
-typedef struct _EqualizerPreset EqualizerPreset;
-
-
-GtkWidget *equalizerwin;
-GtkWidget *equalizerwin_graph;
-
-static GtkWidget *equalizerwin_load_window = NULL;
-static GtkWidget *equalizerwin_load_auto_window = NULL;
-static GtkWidget *equalizerwin_save_window = NULL;
-static GtkWidget *equalizerwin_save_entry = NULL;
-static GtkWidget *equalizerwin_save_auto_window = NULL;
-static GtkWidget *equalizerwin_save_auto_entry = NULL;
-static GtkWidget *equalizerwin_delete_window = NULL;
-static GtkWidget *equalizerwin_delete_auto_window = NULL;
-
-static GtkWidget *equalizerwin_on, *equalizerwin_auto;
-
-static GtkWidget *equalizerwin_close, *equalizerwin_presets, *equalizerwin_shade;
-static GtkWidget *equalizerwin_preamp,*equalizerwin_bands[AUD_EQUALIZER_NBANDS];
-static GtkWidget *equalizerwin_volume, *equalizerwin_balance;
-
-static GList *equalizer_presets = NULL, *equalizer_auto_presets = NULL;
-
-EqualizerPreset *
-equalizer_preset_new(const gchar * name)
-{
-    EqualizerPreset *preset = g_new0(EqualizerPreset, 1);
-    preset->name = g_strdup(name);
-    return preset;
-}
-
-void
-equalizer_preset_free(EqualizerPreset * preset)
-{
-    if (!preset)
-        return;
-
-    g_free(preset->name);
-    g_free(preset);
-}
-
-void
-equalizerwin_set_scaled(gboolean ds)
-{
-    gint height;
-
-    if (cfg.equalizer_shaded)
-        height = 14;
-    else
-        height = 116;
-
-    if (cfg.scaled) {
-        dock_window_resize(GTK_WINDOW(equalizerwin), 275 * cfg.scale_factor, 
-            height * cfg.scale_factor, 275 * cfg.scale_factor, height * cfg.scale_factor);
-    } else {
-        dock_window_resize(GTK_WINDOW(equalizerwin), 275, height, 275, height);
-    }
-
-    GList *iter;
-    for (iter = GTK_FIXED (SKINNED_WINDOW(equalizerwin)->fixed)->children; iter; iter = g_list_next (iter)) {
-        GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
-        GtkWidget *child = child_data->widget;
-        g_signal_emit_by_name(child, "toggle-scaled");
-    }
-    gtk_widget_shape_combine_mask(equalizerwin, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
-}
-
-void
-equalizerwin_set_shade_menu_cb(gboolean shaded)
-{
-    cfg.equalizer_shaded = shaded;
-
-    if (shaded) {
-        dock_shade(get_dock_window_list(), GTK_WINDOW(equalizerwin),
-                   14 * EQUALIZER_SCALE_FACTOR);
-        ui_skinned_set_push_button_data(equalizerwin_shade, -1, 3, -1, 47);
-        ui_skinned_button_set_skin_index1(equalizerwin_shade, SKIN_EQ_EX);
-        ui_skinned_set_push_button_data(equalizerwin_close, 11, 38, 11, 47);
-        ui_skinned_button_set_skin_index(equalizerwin_close, SKIN_EQ_EX);
-        gtk_widget_show(equalizerwin_volume);
-        gtk_widget_show(equalizerwin_balance);
-    }
-    else {
-        dock_shade(get_dock_window_list(), GTK_WINDOW(equalizerwin),
-                   116 * EQUALIZER_SCALE_FACTOR);
-        ui_skinned_set_push_button_data(equalizerwin_shade, -1, 137, -1, 38);
-        ui_skinned_button_set_skin_index1(equalizerwin_shade, SKIN_EQMAIN);
-        ui_skinned_set_push_button_data(equalizerwin_close, 0, 116, 0, 125);
-        ui_skinned_button_set_skin_index(equalizerwin_close, SKIN_EQMAIN);
-        gtk_widget_hide(equalizerwin_volume);
-        gtk_widget_hide(equalizerwin_balance);
-    }
-
-    gtk_widget_shape_combine_mask(equalizerwin, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
-}
-
-static void
-equalizerwin_set_shade(gboolean shaded)
-{
-    GtkAction *action = gtk_action_group_get_action(
-      toggleaction_group_others , "roll up equalizer" );
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded );
-}
-
-static void
-equalizerwin_shade_toggle(void)
-{
-    equalizerwin_set_shade(!cfg.equalizer_shaded);
-}
-
-void
-equalizerwin_eq_changed(void)
-{
-    gint i;
-
-    cfg.equalizer_preamp = ui_skinned_equalizer_slider_get_position(equalizerwin_preamp);
-    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++)
-        cfg.equalizer_bands[i] = ui_skinned_equalizer_slider_get_position(equalizerwin_bands[i]);
-
-    output_set_eq(cfg.equalizer_active, cfg.equalizer_preamp,
-                  cfg.equalizer_bands);
-
-    gtk_widget_queue_draw(equalizerwin_graph);
-}
-
-static void
-equalizerwin_on_pushed(void)
-{
-    cfg.equalizer_active = UI_SKINNED_BUTTON(equalizerwin_on)->inside;
-    equalizerwin_eq_changed();
-}
-
-static void
-equalizerwin_presets_pushed(void)
-{
-    GdkModifierType modmask;
-    gint x, y;
-
-    gdk_window_get_pointer(NULL, &x, &y, &modmask);
-    ui_manager_popup_menu_show(GTK_MENU(equalizerwin_presets_menu), x, y, 1, GDK_CURRENT_TIME);
-}
-
-static void
-equalizerwin_auto_pushed(void)
-{
-    cfg.equalizer_autoload = UI_SKINNED_BUTTON(equalizerwin_auto)->inside;
-}
-
-gboolean
-equalizerwin_press(GtkWidget * widget, GdkEventButton * event,
-                   gpointer callback_data)
-{
-    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS
-             && event->y < 14) {
-        equalizerwin_set_shade(!cfg.equalizer_shaded);
-        if (dock_is_moving(GTK_WINDOW(equalizerwin)))
-            dock_move_release(GTK_WINDOW(equalizerwin));
-        return TRUE;
-    }
-    if (event->button == 3) {
-        /*
-         * Pop up the main menu a few pixels down to avoid
-         * anything to be selected initially.
-         */
-       ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), event->x_root,
-                                event->y_root + 2, 3, event->time);
-       return TRUE;
-    }
-
-    return FALSE;
-}
-
-static gboolean
-equalizerwin_keypress(GtkWidget * widget,
-                      GdkEventKey * event,
-                      gpointer data)
-{
-    if (event->keyval == GDK_Tab && event->state & GDK_CONTROL_MASK) {
-        if (cfg.playlist_visible)
-            gtk_window_present(GTK_WINDOW(playlistwin));
-        else if (cfg.player_visible)
-            gtk_window_present(GTK_WINDOW(mainwin));
-        return TRUE;
-    }
-
-    if (!cfg.equalizer_shaded) {
-        gtk_widget_event(mainwin, (GdkEvent *) event);
-        return TRUE;
-    }
-
-    switch (event->keyval) {
-    case GDK_Left:
-    case GDK_KP_Left:
-        mainwin_set_balance_diff(-4);
-        break;
-    case GDK_Right:
-    case GDK_KP_Right:
-        mainwin_set_balance_diff(4);
-        break;
-    default:
-        gtk_widget_event(mainwin, (GdkEvent *) event);
-        break;
-    }
-
-    return FALSE;
-}
-
-static void
-equalizerwin_close_cb(void)
-{
-    equalizerwin_show(FALSE);
-}
-
-static gboolean
-equalizerwin_delete(GtkWidget * widget,
-                    gpointer data)
-{
-    equalizerwin_show(FALSE);
-    return TRUE;
-}
-
-static GList *
-equalizerwin_read_presets(const gchar * basename)
-{
-    gchar *filename, *name;
-    RcFile *rcfile;
-    GList *list = NULL;
-    gint i, p = 0;
-    EqualizerPreset *preset;
-
-    /* START mod: add check for the default presets locate in system path ({prefix}/share/audacious)
-       by Massimo Cavalleri (submax) */
-
-    filename = g_build_filename(aud_paths[BMP_PATH_USER_DIR], basename, NULL);
-
-    if ((rcfile = aud_rcfile_open(filename)) == NULL) {
-        g_free(filename);
-        // DATA_DIR = "{prefix}/share/audacious" ; example is "/usr/share/audacious"
-        filename = g_build_filename(DATA_DIR, basename, NULL);
-        if ((rcfile = aud_rcfile_open(filename)) == NULL) {
-           g_free(filename);
-           return NULL;
-        }
-    }
-
-    // END mod
-
-    g_free(filename);
-
-    for (;;) {
-        gchar section[32];
-
-        g_snprintf(section, sizeof(section), "Preset%d", p++);
-        if (aud_rcfile_read_string(rcfile, "Presets", section, &name)) {
-            preset = g_new0(EqualizerPreset, 1);
-            preset->name = name;
-            aud_rcfile_read_float(rcfile, name, "Preamp", &preset->preamp);
-            for (i = 0; i < AUD_EQUALIZER_NBANDS; i++) {
-                gchar band[16];
-                g_snprintf(band, sizeof(band), "Band%d", i);
-                aud_rcfile_read_float(rcfile, name, band, &preset->bands[i]);
-            }
-            list = g_list_prepend(list, preset);
-        }
-        else
-            break;
-    }
-    list = g_list_reverse(list);
-    aud_rcfile_free(rcfile);
-    return list;
-}
-
-gint
-equalizerwin_volume_frame_cb(gint pos)
-{
-    if (equalizerwin_volume) {
-        gint x;
-        if (pos < 32)
-            x = 1;
-        else if (pos < 63)
-            x = 4;
-        else
-            x = 7;
-
-        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_volume)->knob_nx = x;
-        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_volume)->knob_px = x;
-    }
-    return 1;
-}
-
-static void
-equalizerwin_volume_motion_cb(GtkWidget *widget, gint pos)
-{
-    gint v = (gint) rint(pos * 100 / 94.0);
-    mainwin_adjust_volume_motion(v);
-    mainwin_set_volume_slider(v);
-}
-
-static void
-equalizerwin_volume_release_cb(GtkWidget *widget, gint pos)
-{
-    mainwin_adjust_volume_release();
-}
-
-static gint
-equalizerwin_balance_frame_cb(gint pos)
-{
-    if (equalizerwin_balance) {
-        gint x;
-        if (pos < 13)
-            x = 11;
-        else if (pos < 26)
-            x = 14;
-        else
-            x = 17;
-
-        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_balance)->knob_nx = x;
-        UI_SKINNED_HORIZONTAL_SLIDER(equalizerwin_balance)->knob_px = x;
-    }
-
-    return 1;
-}
-
-static void
-equalizerwin_balance_motion_cb(GtkWidget *widget, gint pos)
-{
-    gint b;
-    pos = MIN(pos, 38);         /* The skin uses a even number of pixels
-                                   for the balance-slider *sigh* */
-    b = (gint) rint((pos - 19) * 100 / 19.0);
-    mainwin_adjust_balance_motion(b);
-    mainwin_set_balance_slider(b);
-}
-
-static void
-equalizerwin_balance_release_cb(GtkWidget *widget, gint pos)
-{
-    mainwin_adjust_balance_release();
-}
-
-void
-equalizerwin_set_balance_slider(gint percent)
-{
-    ui_skinned_horizontal_slider_set_position(equalizerwin_balance,
-                         (gint) rint((percent * 19 / 100.0) + 19));
-}
-
-void
-equalizerwin_set_volume_slider(gint percent)
-{
-    ui_skinned_horizontal_slider_set_position(equalizerwin_volume,
-                         (gint) rint(percent * 94 / 100.0));
-}
-
-static void
-equalizerwin_create_widgets(void)
-{
-    gint i;
-
-    equalizerwin_on = ui_skinned_button_new();
-    ui_skinned_toggle_button_setup(equalizerwin_on, SKINNED_WINDOW(equalizerwin)->fixed,
-                                   14, 18, 25, 12, 10, 119, 128, 119, 69, 119, 187, 119, SKIN_EQMAIN);
-    g_signal_connect(equalizerwin_on, "clicked", equalizerwin_on_pushed, NULL);
-    UI_SKINNED_BUTTON(equalizerwin_on)->inside = cfg.equalizer_active;
-
-    equalizerwin_auto = ui_skinned_button_new();
-    ui_skinned_toggle_button_setup(equalizerwin_auto, SKINNED_WINDOW(equalizerwin)->fixed,
-                                   39, 18, 33, 12, 35, 119, 153, 119, 94, 119, 212, 119, SKIN_EQMAIN);
-    g_signal_connect(equalizerwin_auto, "clicked", equalizerwin_auto_pushed, NULL);
-    UI_SKINNED_BUTTON(equalizerwin_auto)->inside = cfg.equalizer_autoload;
-
-    equalizerwin_presets = ui_skinned_button_new();
-    ui_skinned_push_button_setup(equalizerwin_presets, SKINNED_WINDOW(equalizerwin)->fixed,
-                                 217, 18, 44, 12, 224, 164, 224, 176, SKIN_EQMAIN);
-    g_signal_connect(equalizerwin_presets, "clicked", equalizerwin_presets_pushed, NULL );
-
-    equalizerwin_close = ui_skinned_button_new();
-    ui_skinned_push_button_setup(equalizerwin_close, SKINNED_WINDOW(equalizerwin)->fixed,
-                                 264, 3, 9, 9, 0, 116, 0, 125, SKIN_EQMAIN);
-    g_signal_connect(equalizerwin_close, "clicked", equalizerwin_close_cb, NULL );
-
-    equalizerwin_shade = ui_skinned_button_new();
-    ui_skinned_push_button_setup(equalizerwin_shade, SKINNED_WINDOW(equalizerwin)->fixed,
-                                 254, 3, 9, 9, 254, 137, 1, 38, SKIN_EQMAIN);
-    ui_skinned_button_set_skin_index2(equalizerwin_shade, SKIN_EQ_EX);
-    g_signal_connect(equalizerwin_shade, "clicked", equalizerwin_shade_toggle, NULL );
-
-    equalizerwin_graph = ui_skinned_equalizer_graph_new(SKINNED_WINDOW(equalizerwin)->fixed, 86, 17);
-
-    equalizerwin_preamp = ui_skinned_equalizer_slider_new(SKINNED_WINDOW(equalizerwin)->fixed, 21, 38);
-    ui_skinned_equalizer_slider_set_position(equalizerwin_preamp, cfg.equalizer_preamp);
-
-    for (i = 0; i < AUD_EQUALIZER_NBANDS; i++) {
-        equalizerwin_bands[i] =
-            ui_skinned_equalizer_slider_new(SKINNED_WINDOW(equalizerwin)->fixed, 78 + (i * 18), 38);
-        ui_skinned_equalizer_slider_set_position(equalizerwin_bands[i], cfg.equalizer_bands[i]);
-    }
-
-    equalizerwin_volume =
-        ui_skinned_horizontal_slider_new(SKINNED_WINDOW(equalizerwin)->fixed,
-                                         61, 4, 97, 8, 1, 30, 1, 30, 3, 7, 4, 61, 0, 94,
-                                         equalizerwin_volume_frame_cb, SKIN_EQ_EX);
-    g_signal_connect(equalizerwin_volume, "motion", G_CALLBACK(equalizerwin_volume_motion_cb), NULL);
-    g_signal_connect(equalizerwin_volume, "release", G_CALLBACK(equalizerwin_volume_release_cb), NULL);
-
-
-    equalizerwin_balance =
-        ui_skinned_horizontal_slider_new(SKINNED_WINDOW(equalizerwin)->fixed,
-                       164, 4, 42, 8, 11, 30, 11, 30, 3, 7, 4, 164, 0, 39,
-                       equalizerwin_balance_frame_cb, SKIN_EQ_EX);
-    g_signal_connect(equalizerwin_balance, "motion", G_CALLBACK(equalizerwin_balance_motion_cb), NULL);
-    g_signal_connect(equalizerwin_balance, "release", G_CALLBACK(equalizerwin_balance_release_cb), NULL);
-}
-
-
-static void
-equalizerwin_create_window(void)
-{
-    GdkPixbuf *icon;
-    gint width, height;
-
-    width = 275;
-    height = cfg.equalizer_shaded ? 14 : 116;
-
-    equalizerwin = ui_skinned_window_new("equalizer");
-    gtk_window_set_title(GTK_WINDOW(equalizerwin), _("Audacious Equalizer"));
-    gtk_window_set_role(GTK_WINDOW(equalizerwin), "equalizer");
-    gtk_window_set_resizable(GTK_WINDOW(equalizerwin), FALSE);
-
-    if (cfg.scaled && cfg.eq_scaled_linked) {
-        width *= cfg.scale_factor;
-        height *= cfg.scale_factor;
-    }
-
-    gtk_widget_set_size_request(equalizerwin, width, height);
-
-    /* this will hide only mainwin. it's annoying! yaz */
-    gtk_window_set_transient_for(GTK_WINDOW(equalizerwin),
-                                 GTK_WINDOW(mainwin));
-    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(equalizerwin), TRUE);
-
-    icon = gdk_pixbuf_new_from_xpm_data((const gchar **) audacious_eq_icon);
-    gtk_window_set_icon(GTK_WINDOW(equalizerwin), icon);
-    g_object_unref(icon);
-
-    gtk_widget_set_app_paintable(equalizerwin, TRUE);
-
-    if (cfg.equalizer_x != -1 && cfg.save_window_position)
-        gtk_window_move(GTK_WINDOW(equalizerwin),
-                        cfg.equalizer_x, cfg.equalizer_y);
-
-    g_signal_connect(equalizerwin, "delete_event",
-                     G_CALLBACK(equalizerwin_delete), NULL);
-    g_signal_connect(equalizerwin, "button_press_event",
-                     G_CALLBACK(equalizerwin_press), NULL);
-    g_signal_connect(equalizerwin, "key_press_event",
-                     G_CALLBACK(equalizerwin_keypress), NULL);
-}
-
-void
-equalizerwin_create(void)
-{
-    equalizer_presets = equalizerwin_read_presets("eq.preset");
-    equalizer_auto_presets = equalizerwin_read_presets("eq.auto_preset");
-
-    equalizerwin_create_window();
-
-    gtk_window_add_accel_group( GTK_WINDOW(equalizerwin) , ui_manager_get_accel_group() );
-
-    equalizerwin_create_widgets();
-}
-
-
-void
-equalizerwin_show(gboolean show)
-{
-    GtkAction *action = gtk_action_group_get_action(
-      toggleaction_group_others , "show equalizer" );
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , show );
-
-    if (show)
-        equalizerwin_real_show();
-    else
-        equalizerwin_real_hide();
-}
-
-void
-equalizerwin_real_show(void)
-{
-    gtk_window_move(GTK_WINDOW(equalizerwin), cfg.equalizer_x, cfg.equalizer_y);
-    if (cfg.scaled && cfg.eq_scaled_linked)
-        gtk_widget_set_size_request(equalizerwin, 275 * cfg.scale_factor,
-                                    ((cfg.equalizer_shaded ? 14 : 116) * cfg.scale_factor));
-    else
-        gtk_widget_set_size_request(equalizerwin, 275,
-                                    (cfg.equalizer_shaded ? 14 : 116));
-    cfg.equalizer_visible = TRUE;
-    UI_SKINNED_BUTTON(mainwin_eq)->inside = TRUE;
-    gtk_widget_show_all(equalizerwin);
-
-    if (!cfg.equalizer_shaded) {
-        gtk_widget_hide(equalizerwin_volume);
-        gtk_widget_hide(equalizerwin_balance);
-    }
-    else {
-        ui_skinned_set_push_button_data(equalizerwin_shade, -1, 3, -1, 47);
-        ui_skinned_button_set_skin_index1(equalizerwin_shade, SKIN_EQ_EX);
-        ui_skinned_set_push_button_data(equalizerwin_close, 11, 38, 11, 47);
-        ui_skinned_button_set_skin_index(equalizerwin_close, SKIN_EQ_EX);
-    }
-
-    gtk_window_present(GTK_WINDOW(equalizerwin));
-}
-
-void
-equalizerwin_real_hide(void)
-{
-    /*
-     * This function should only be called from the
-     * main menu signal handler
-     */
-    gtk_widget_hide(equalizerwin);
-    cfg.equalizer_visible = FALSE;
-    UI_SKINNED_BUTTON(mainwin_eq)->inside = FALSE;
-    gtk_widget_queue_draw(mainwin_eq);
-}
-
-static EqualizerPreset *
-equalizerwin_find_preset(GList * list, const gchar * name)
-{
-    GList *node = list;
-    EqualizerPreset *preset;
-
-    while (node) {
-        preset = node->data;
-        if (!strcasecmp(preset->name, name))
-            return preset;
-        node = g_list_next(node);
-    }
-    return NULL;
-}
-
-static void
-equalizerwin_write_preset_file(GList * list, const gchar * basename)
-{
-    gchar *filename, *tmp;
-    gint i, p;
-    EqualizerPreset *preset;
-    RcFile *rcfile;
-    GList *node;
-
-    rcfile = aud_rcfile_new();
-    p = 0;
-    for (node = list; node; node = g_list_next(node)) {
-        preset = node->data;
-        tmp = g_strdup_printf("Preset%d", p++);
-        aud_rcfile_write_string(rcfile, "Presets", tmp, preset->name);
-        g_free(tmp);
-        aud_rcfile_write_float(rcfile, preset->name, "Preamp",
-                               preset->preamp);
-        for (i = 0; i < 10; i++) {
-            tmp = g_strdup_printf("Band%d\n", i);
-            aud_rcfile_write_float(rcfile, preset->name, tmp,
-                                   preset->bands[i]);
-            g_free(tmp);
-        }
-    }
-
-    filename = g_build_filename(aud_paths[BMP_PATH_USER_DIR], basename, NULL);
-    aud_rcfile_write(rcfile, filename);
-    aud_rcfile_free(rcfile);
-    g_free(filename);
-}
-
-static gboolean
-equalizerwin_load_preset(GList * list, const gchar * name)
-{
-    EqualizerPreset *preset;
-    gint i;
-
-    if ((preset = equalizerwin_find_preset(list, name)) != NULL) {
-        ui_skinned_equalizer_slider_set_position(equalizerwin_preamp, preset->preamp);
-        for (i = 0; i < 10; i++)
-            ui_skinned_equalizer_slider_set_position(equalizerwin_bands[i], preset->bands[i]);
-        equalizerwin_eq_changed();
-        return TRUE;
-    }
-    return FALSE;
-}
-
-static GList *
-equalizerwin_save_preset(GList * list, const gchar * name,
-                         const gchar * filename)
-{
-    gint i;
-    EqualizerPreset *preset;
-
-    if (!(preset = equalizerwin_find_preset(list, name))) {
-        preset = g_new0(EqualizerPreset, 1);
-        preset->name = g_strdup(name);
-        list = g_list_append(list, preset);
-    }
-
-    preset->preamp = ui_skinned_equalizer_slider_get_position(equalizerwin_preamp);
-    for (i = 0; i < 10; i++)
-        preset->bands[i] = ui_skinned_equalizer_slider_get_position(equalizerwin_bands[i]);
-
-    equalizerwin_write_preset_file(list, filename);
-
-    return list;
-}
-
-static GList *
-equalizerwin_delete_preset(GList * list, gchar * name, gchar * filename)
-{
-    EqualizerPreset *preset;
-    GList *node;
-
-    if (!(preset = equalizerwin_find_preset(list, name)))
-        return list;
-
-    if (!(node = g_list_find(list, preset)))
-        return list;
-
-    list = g_list_remove_link(list, node);
-    equalizer_preset_free(preset);
-    g_list_free_1(node);
-
-    equalizerwin_write_preset_file(list, filename);
-
-    return list;
-}
-
-static void
-equalizerwin_delete_selected_presets(GtkTreeView *view, gchar *filename)
-{
-    gchar *text;
-
-    GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
-    GtkTreeModel *model = gtk_tree_view_get_model(view);
-
-    /*
-     * first we are making a list of the selected rows, then we convert this
-     * list into a list of GtkTreeRowReferences, so that when you delete an
-     * item you can still access the other items
-     * finally we iterate through all GtkTreeRowReferences, convert them to
-     * GtkTreeIters and delete those one after the other
-     */
-
-    GList *list = gtk_tree_selection_get_selected_rows(selection, &model);
-    GList *rrefs = NULL;
-    GList *litr;
-
-    for (litr = list; litr; litr = litr->next)
-    {
-        GtkTreePath *path = litr->data;
-        rrefs = g_list_append(rrefs, gtk_tree_row_reference_new(model, path));
-    }
-
-    for (litr = rrefs; litr; litr = litr->next)
-    {
-        GtkTreeRowReference *ref = litr->data;
-        GtkTreePath *path = gtk_tree_row_reference_get_path(ref);
-        GtkTreeIter iter;
-        gtk_tree_model_get_iter(model, &iter, path);
-
-        gtk_tree_model_get(model, &iter, 0, &text, -1);
-
-        if (!strcmp(filename, "eq.preset"))
-            equalizer_presets = equalizerwin_delete_preset(equalizer_presets, text, filename);
-        else if (!strcmp(filename, "eq.auto_preset"))
-            equalizer_auto_presets = equalizerwin_delete_preset(equalizer_auto_presets, text, filename);
-
-        gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
-    }
-}
-
-static GList *
-import_winamp_eqf(VFSFile * file)
-{
-    gchar header[31];
-    gchar bands[11];
-    gint i = 0;
-    EqualizerPreset *preset = NULL;
-    GList *list = NULL;
-    GtkWidget *dialog;
-    gchar *realfn;
-    gchar preset_name[0xb4];
-
-    vfs_fread(header, 1, 31, file);
-    if (strncmp(header, "Winamp EQ library file v1.1", 27)) goto error;
-
-    AUDDBG("The EQF header is OK\n");
-
-    if (vfs_fseek(file, 0x1f, SEEK_SET) == -1) goto error;
-
-    while (vfs_fread(preset_name, 1, 0xb4, file) == 0xb4) {
-        AUDDBG("The preset name is '%s'\n", preset_name);
-        vfs_fseek(file, 0x4d, SEEK_CUR); /* unknown crap --asphyx */
-        if (vfs_fread(bands, 1, 11, file) != 11) break;
-
-        preset = equalizer_preset_new(preset_name);
-        /*this was divided by 63, but shouldn't it be 64? --majeru*/
-        preset->preamp = EQUALIZER_MAX_GAIN - ((bands[10] * EQUALIZER_MAX_GAIN * 2) / 64.0);
-
-        for (i = 0; i < 10; i++)
-            preset->bands[i] = EQUALIZER_MAX_GAIN - ((bands[i] * EQUALIZER_MAX_GAIN * 2) / 64.0);
-        
-        list = g_list_prepend(list, preset);
-    }
-    
-    list = g_list_reverse(list);
-    if (list == NULL) goto error;
-
-    return list;
-
-error:
-    realfn = g_filename_from_uri(file->uri, NULL, NULL);
-    dialog = gtk_message_dialog_new (GTK_WINDOW(mainwin),
-                                     GTK_DIALOG_DESTROY_WITH_PARENT,
-                                     GTK_MESSAGE_ERROR,
-                                     GTK_BUTTONS_CLOSE,
-                                     _("Error importing Winamp EQF file '%s'"),
-                                     realfn);
-    gtk_dialog_run (GTK_DIALOG (dialog));
-    gtk_widget_destroy (dialog);
-    g_free(realfn);
-    return NULL;
-}
-
-static void
-free_cb (gpointer data, gpointer user_data)
-{
-    equalizer_preset_free((EqualizerPreset*)data);
-}
-
-static void
-equalizerwin_read_winamp_eqf(VFSFile * file)
-{
-    GList *presets;
-    gint i;
-
-    if ((presets = import_winamp_eqf(file)) == NULL)
-        return;
-
-    /* just get the first preset --asphyx */
-    EqualizerPreset *preset = (EqualizerPreset*)presets->data;
-    ui_skinned_equalizer_slider_set_position(equalizerwin_preamp,
-                                             preset->preamp);
-
-    for (i = 0; i < 10; i++)
-        ui_skinned_equalizer_slider_set_position(equalizerwin_bands[i],
-                                                 preset->bands[i]);
-
-    g_list_foreach(presets, free_cb, NULL);
-    g_list_free(presets);
-
-    equalizerwin_eq_changed();
-}
-
-static void
-equalizerwin_read_aud_preset(RcFile * rcfile)
-{
-    gfloat val;
-    gint i;
-
-    if (aud_rcfile_read_float(rcfile, "Equalizer preset", "Preamp", &val))
-        ui_skinned_equalizer_slider_set_position(equalizerwin_preamp, val);
-    for (i = 0; i < 10; i++) {
-        gchar tmp[7];
-        g_snprintf(tmp, sizeof(tmp), "Band%d", i);
-        if (aud_rcfile_read_float(rcfile, "Equalizer preset", tmp, &val))
-            ui_skinned_equalizer_slider_set_position(equalizerwin_bands[i], val);
-    }
-    equalizerwin_eq_changed();
-}
-
-static void
-equalizerwin_save_ok(GtkWidget * widget, gpointer data)
-{
-    const gchar *text;
-
-    text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_entry));
-    if (strlen(text) != 0)
-        equalizer_presets =
-            equalizerwin_save_preset(equalizer_presets, text, "eq.preset");
-    gtk_widget_destroy(equalizerwin_save_window);
-}
-
-static void
-equalizerwin_save_select(GtkTreeView *treeview, GtkTreePath *path,
-                         GtkTreeViewColumn *col, gpointer data)
-{
-    gchar *text;
-
-    GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-
-    if (selection)
-    {
-        if (gtk_tree_selection_get_selected(selection, &model, &iter))
-        {
-            gtk_tree_model_get(model, &iter, 0, &text, -1);
-            gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_entry), text);
-            equalizerwin_save_ok(NULL, NULL);
-
-            g_free(text);
-        }
-    }
-}
-
-static void
-equalizerwin_load_ok(GtkWidget *widget, gpointer data)
-{
-    gchar *text;
-
-    GtkTreeView* view = GTK_TREE_VIEW(data);
-    GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-
-    if (selection)
-    {
-        if (gtk_tree_selection_get_selected(selection, &model, &iter))
-        {
-            gtk_tree_model_get(model, &iter, 0, &text, -1);
-            equalizerwin_load_preset(equalizer_presets, text);
-
-            g_free(text);
-        }
-    }
-    gtk_widget_destroy(equalizerwin_load_window);
-}
-
-static void
-equalizerwin_load_select(GtkTreeView *treeview, GtkTreePath *path,
-                         GtkTreeViewColumn *col, gpointer data)
-{
-    equalizerwin_load_ok(NULL, treeview);
-}
-
-static void
-equalizerwin_delete_delete(GtkWidget *widget, gpointer data)
-{
-    equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.preset");
-}
-
-static void
-equalizerwin_save_auto_ok(GtkWidget *widget, gpointer data)
-{
-    const gchar *text;
-
-    text = gtk_entry_get_text(GTK_ENTRY(equalizerwin_save_auto_entry));
-    if (strlen(text) != 0)
-        equalizer_auto_presets =
-            equalizerwin_save_preset(equalizer_auto_presets, text,
-                                     "eq.auto_preset");
-    gtk_widget_destroy(equalizerwin_save_auto_window);
-}
-
-static void
-equalizerwin_save_auto_select(GtkTreeView *treeview, GtkTreePath *path,
-                              GtkTreeViewColumn *col, gpointer data)
-{
-    gchar *text;
-
-    GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-
-    if (selection)
-    {
-        if (gtk_tree_selection_get_selected(selection, &model, &iter))
-        {
-            gtk_tree_model_get(model, &iter, 0, &text, -1);
-            gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_auto_entry), text);
-            equalizerwin_save_auto_ok(NULL, NULL);
-
-            g_free(text);
-        }
-    }
-}
-
-static void
-equalizerwin_load_auto_ok(GtkWidget *widget, gpointer data)
-{
-    gchar *text;
-
-    GtkTreeView *view = GTK_TREE_VIEW(data);
-    GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-
-    if (selection)
-    {
-        if (gtk_tree_selection_get_selected(selection, &model, &iter))
-        {
-            gtk_tree_model_get(model, &iter, 0, &text, -1);
-            equalizerwin_load_preset(equalizer_auto_presets, text);
-
-            g_free(text);
-        }
-    }
-    gtk_widget_destroy(equalizerwin_load_auto_window);
-}
-
-static void
-equalizerwin_load_auto_select(GtkTreeView *treeview, GtkTreePath *path,
-                              GtkTreeViewColumn *col, gpointer data)
-{
-    equalizerwin_load_auto_ok(NULL, treeview);
-}
-
-static void
-equalizerwin_delete_auto_delete(GtkWidget *widget, gpointer data)
-{
-    equalizerwin_delete_selected_presets(GTK_TREE_VIEW(data), "eq.auto_preset");
-}
-
-
-static void
-load_preset_file(const gchar *filename)
-{
-    RcFile *rcfile;
-
-    if ((rcfile = aud_rcfile_open(filename)) != NULL) {
-        equalizerwin_read_aud_preset(rcfile);
-        aud_rcfile_free(rcfile);
-    }
-}
-
-static VFSFile *
-open_vfs_file(const gchar *filename, const gchar *mode)
-{
-    VFSFile *file;
-    GtkWidget *dialog;
-
-    if (!(file = vfs_fopen(filename, mode))) {
-        dialog = gtk_message_dialog_new (GTK_WINDOW (mainwin),
-                                         GTK_DIALOG_DESTROY_WITH_PARENT,
-                                         GTK_MESSAGE_ERROR,
-                                         GTK_BUTTONS_CLOSE,
-                                         "Error loading file '%s'",
-                                         filename);
-        gtk_dialog_run (GTK_DIALOG (dialog));
-        gtk_widget_destroy (dialog);
-    }
-
-    return file;
-}
-
-static void
-load_winamp_file(const gchar * filename)
-{
-    VFSFile *file;
-
-    if (!(file = open_vfs_file(filename, "rb")))
-        return;
-
-    equalizerwin_read_winamp_eqf(file);
-    vfs_fclose(file);
-}
-
-static void
-import_winamp_file(const gchar * filename)
-{
-    VFSFile *file;
-    GList *list;
-
-    if (!(file = open_vfs_file(filename, "rb")) ||
-        !(list = import_winamp_eqf(file)))
-        return;
-
-    equalizer_presets = g_list_concat(equalizer_presets, list);
-    equalizerwin_write_preset_file(equalizer_presets, "eq.preset");
-
-    vfs_fclose(file);
-}
-
-static void
-save_preset_file(const gchar * filename)
-{
-    RcFile *rcfile;
-    gint i;
-
-    rcfile = aud_rcfile_new();
-    aud_rcfile_write_float(rcfile, "Equalizer preset", "Preamp",
-                           ui_skinned_equalizer_slider_get_position(equalizerwin_preamp));
-
-    for (i = 0; i < 10; i++) {
-        gchar tmp[7];
-        g_snprintf(tmp, sizeof(tmp), "Band%d", i);
-        aud_rcfile_write_float(rcfile, "Equalizer preset", tmp,
-                               ui_skinned_equalizer_slider_get_position(equalizerwin_bands[i]));
-    }
-
-    aud_rcfile_write(rcfile, filename);
-    aud_rcfile_free(rcfile);
-}
-
-static void
-save_winamp_file(const gchar * filename)
-{
-    VFSFile *file;
-
-    gchar name[257];
-    gint i;
-    guchar bands[11];
-
-    if (!(file = open_vfs_file(filename, "wb")))
-        return;
-
-    vfs_fwrite("Winamp EQ library file v1.1\x1a!--", 1, 31, file);
-
-    memset(name, 0, 257);
-    g_strlcpy(name, "Entry1", 257);
-    vfs_fwrite(name, 1, 257, file);
-
-    for (i = 0; i < 10; i++)
-        bands[i] = 63 - (((ui_skinned_equalizer_slider_get_position(equalizerwin_bands[i]) + EQUALIZER_MAX_GAIN) * 63) / EQUALIZER_MAX_GAIN / 2);
-    bands[10] = 63 - (((ui_skinned_equalizer_slider_get_position(equalizerwin_preamp) + EQUALIZER_MAX_GAIN) * 63) / EQUALIZER_MAX_GAIN / 2);
-    vfs_fwrite(bands, 1, 11, file);
-
-    vfs_fclose(file);
-}
-
-static GtkWidget *
-equalizerwin_create_list_window(GList *preset_list,
-                                const gchar *title,
-                                GtkWidget **window,
-                                GtkSelectionMode sel_mode,
-                                GtkWidget **entry,
-                                const gchar *action_name,
-                                GCallback action_func,
-                                GCallback select_row_func)
-{
-    GtkWidget *vbox, *scrolled_window, *bbox, *view;
-    GtkWidget *button_cancel, *button_action;
-    GList *node;
-
-    GtkListStore *store;
-    GtkTreeIter iter;
-    GtkTreeModel *model;
-    GtkCellRenderer *renderer;
-    GtkTreeSelection *selection;
-    GtkTreeSortable *sortable;
-
-
-
-    *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_title(GTK_WINDOW(*window), title);
-    gtk_window_set_type_hint(GTK_WINDOW(*window), GDK_WINDOW_TYPE_HINT_DIALOG);
-    gtk_window_set_default_size(GTK_WINDOW(*window), 350, 300);
-    gtk_window_set_position(GTK_WINDOW(*window), GTK_WIN_POS_CENTER);
-    gtk_container_set_border_width(GTK_CONTAINER(*window), 10);
-    gtk_window_set_transient_for(GTK_WINDOW(*window),
-                                 GTK_WINDOW(equalizerwin));
-    g_signal_connect(*window, "destroy",
-                     G_CALLBACK(gtk_widget_destroyed), window);
-
-    vbox = gtk_vbox_new(FALSE, 10);
-    gtk_container_add(GTK_CONTAINER(*window), vbox);
-
-    scrolled_window = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
-                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-
-
-    /* fill the store with the names of all available presets */
-    store = gtk_list_store_new(1, G_TYPE_STRING);
-    for (node = preset_list; node; node = g_list_next(node))
-    {
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                           0, ((EqualizerPreset*)node->data)->name,
-                           -1);
-    }
-    model = GTK_TREE_MODEL(store);
-
-
-    sortable = GTK_TREE_SORTABLE(store);
-    gtk_tree_sortable_set_sort_column_id(sortable, 0, GTK_SORT_ASCENDING);
-
-
-    view = gtk_tree_view_new();
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1,
-                                                _("Presets"), renderer,
-                                                "text", 0, NULL);
-    gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
-    g_object_unref(model);
-
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
-    gtk_tree_selection_set_mode(selection, sel_mode);
-
-
-
-
-    gtk_container_add(GTK_CONTAINER(scrolled_window), view);
-    gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
-
-    if (entry) {
-        *entry = gtk_entry_new();
-        g_signal_connect(*entry, "activate", action_func, NULL);
-        gtk_box_pack_start(GTK_BOX(vbox), *entry, FALSE, FALSE, 0);
-    }
-
-    bbox = gtk_hbutton_box_new();
-    gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
-    gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
-    gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
-
-    button_cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
-    g_signal_connect_swapped(button_cancel, "clicked",
-                             G_CALLBACK(gtk_widget_destroy),
-                             GTK_OBJECT(*window));
-    gtk_box_pack_start(GTK_BOX(bbox), button_cancel, TRUE, TRUE, 0);
-
-    button_action = gtk_button_new_from_stock(action_name);
-    g_signal_connect(button_action, "clicked", G_CALLBACK(action_func), view);
-    GTK_WIDGET_SET_FLAGS(button_action, GTK_CAN_DEFAULT);
-
-    if (select_row_func)
-        g_signal_connect(view, "row-activated", G_CALLBACK(select_row_func), NULL);
-
-        
-    gtk_box_pack_start(GTK_BOX(bbox), button_action, TRUE, TRUE, 0);
-
-    gtk_widget_grab_default(button_action);
-
-
-    gtk_widget_show_all(*window);
-
-    return *window;
-}
-
-void
-equalizerwin_load_auto_preset(const gchar * filename)
-{
-    gchar *presetfilename, *directory;
-    RcFile *rcfile;
-
-    g_return_if_fail(filename != NULL);
-
-    if (!cfg.equalizer_autoload)
-        return;
-
-    presetfilename = g_strconcat(filename, ".", cfg.eqpreset_extension, NULL);
-
-    /* First try to find a per file preset file */
-    if (strlen(cfg.eqpreset_extension) > 0 &&
-        (rcfile = aud_rcfile_open(presetfilename)) != NULL) {
-        g_free(presetfilename);
-        equalizerwin_read_aud_preset(rcfile);
-        aud_rcfile_free(rcfile);
-        return;
-    }
-
-    g_free(presetfilename);
-
-    directory = g_path_get_dirname(filename);
-    presetfilename = g_build_filename(directory, cfg.eqpreset_default_file,
-                                      NULL);
-    g_free(directory);
-
-    /* Try to find a per directory preset file */
-    if (strlen(cfg.eqpreset_default_file) > 0 &&
-        (rcfile = aud_rcfile_open(presetfilename)) != NULL) {
-        equalizerwin_read_aud_preset(rcfile);
-        aud_rcfile_free(rcfile);
-    }
-    else if (!equalizerwin_load_preset
-             (equalizer_auto_presets, g_basename(filename))) {
-        /* Fall back to the oldstyle auto presets */
-        equalizerwin_load_preset(equalizer_presets, "Default");
-    }
-
-    g_free(presetfilename);
-}
-
-void
-equalizerwin_set_preamp(gfloat preamp)
-{
-    ui_skinned_equalizer_slider_set_position(equalizerwin_preamp, preamp);
-    equalizerwin_eq_changed();
-}
-
-void
-equalizerwin_set_band(gint band, gfloat value)
-{
-    g_return_if_fail(band >= 0 && band < 10);
-    ui_skinned_equalizer_slider_set_position(equalizerwin_bands[band], value);
-}
-
-gfloat
-equalizerwin_get_preamp(void)
-{
-    return ui_skinned_equalizer_slider_get_position(equalizerwin_preamp);
-}
-
-gfloat
-equalizerwin_get_band(gint band)
-{
-    g_return_val_if_fail(band >= 0 && band < 10, 0.0);
-    return ui_skinned_equalizer_slider_get_position(equalizerwin_bands[band]);
-}
-
-void
-action_equ_load_preset(void)
-{
-    if (equalizerwin_load_window) {
-        gtk_window_present(GTK_WINDOW(equalizerwin_load_window));
-        return;
-    }
-    
-    equalizerwin_create_list_window(equalizer_presets,
-                                    Q_("Load preset"),
-                                    &equalizerwin_load_window,
-                                    GTK_SELECTION_SINGLE, NULL,
-                                    GTK_STOCK_OK,
-                                    G_CALLBACK(equalizerwin_load_ok),
-                                    G_CALLBACK(equalizerwin_load_select));
-}
-
-void
-action_equ_load_auto_preset(void)
-{
-    if (equalizerwin_load_auto_window) {
-        gtk_window_present(GTK_WINDOW(equalizerwin_load_auto_window));
-        return;
-    }
-
-    equalizerwin_create_list_window(equalizer_auto_presets,
-                                    Q_("Load auto-preset"),
-                                    &equalizerwin_load_auto_window,
-                                    GTK_SELECTION_SINGLE, NULL,
-                                    GTK_STOCK_OK,
-                                    G_CALLBACK(equalizerwin_load_auto_ok),
-                                    G_CALLBACK(equalizerwin_load_auto_select));
-}
-
-void
-action_equ_load_default_preset(void)
-{
-    equalizerwin_load_preset(equalizer_presets, "Default");
-}
-
-void
-action_equ_zero_preset(void)
-{
-    gint i;
-
-    ui_skinned_equalizer_slider_set_position(equalizerwin_preamp, 0);
-    for (i = 0; i < 10; i++)
-        ui_skinned_equalizer_slider_set_position(equalizerwin_bands[i], 0);
-
-    equalizerwin_eq_changed();
-}
-
-void
-action_equ_load_preset_file(void)
-{
-    GtkWidget *dialog;
-    gchar *file_uri;
-
-    dialog = make_filebrowser(Q_("Load equalizer preset"), FALSE);
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
-        load_preset_file(file_uri);
-        g_free(file_uri);
-    }
-    gtk_widget_destroy(dialog);
-}
-
-void
-action_equ_load_preset_eqf(void)
-{
-    GtkWidget *dialog;
-    gchar *file_uri;
-
-    dialog = make_filebrowser(Q_("Load equalizer preset"), FALSE);
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
-        load_winamp_file(file_uri);
-        g_free(file_uri);
-    }
-    gtk_widget_destroy(dialog);
-}
-
-void
-action_equ_import_winamp_presets(void)
-{
-    GtkWidget *dialog;
-    gchar *file_uri;
-
-    dialog = make_filebrowser(Q_("Load equalizer preset"), FALSE);
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
-        import_winamp_file(file_uri);
-        g_free(file_uri);
-    }
-    gtk_widget_destroy(dialog);
-}
-
-void
-action_equ_save_preset(void)
-{
-    if (equalizerwin_save_window) {
-        gtk_window_present(GTK_WINDOW(equalizerwin_save_window));
-        return;
-    }
-     
-    equalizerwin_create_list_window(equalizer_presets,
-                                    Q_("Save preset"),
-                                    &equalizerwin_save_window,
-                                    GTK_SELECTION_SINGLE,
-                                    &equalizerwin_save_entry,
-                                    GTK_STOCK_OK,
-                                    G_CALLBACK(equalizerwin_save_ok),
-                                    G_CALLBACK(equalizerwin_save_select));
-}
-
-void
-action_equ_save_auto_preset(void)
-{
-    gchar *name;
-    Playlist *playlist = playlist_get_active();
-
-    if (equalizerwin_save_auto_window)
-        gtk_window_present(GTK_WINDOW(equalizerwin_save_auto_window));
-    else
-        equalizerwin_create_list_window(equalizer_auto_presets,
-                                        Q_("Save auto-preset"),
-                                        &equalizerwin_save_auto_window,
-                                        GTK_SELECTION_SINGLE,
-                                        &equalizerwin_save_auto_entry,
-                                        GTK_STOCK_OK,
-                                        G_CALLBACK(equalizerwin_save_auto_ok),
-                                        G_CALLBACK(equalizerwin_save_auto_select));
-
-    name = playlist_get_filename(playlist, playlist_get_position(playlist));
-    if (name) {
-        gtk_entry_set_text(GTK_ENTRY(equalizerwin_save_auto_entry),
-                           g_basename(name));
-        g_free(name);
-    }
-}
-
-void
-action_equ_save_default_preset(void)
-{
-    equalizer_presets =
-        equalizerwin_save_preset(equalizer_presets, Q_("Default"), "eq.preset");
-}
-
-void
-action_equ_save_preset_file(void)
-{
-    GtkWidget *dialog;
-    gchar *file_uri;
-    gchar *songname;
-    Playlist *playlist = playlist_get_active();
-
-    dialog = make_filebrowser(Q_("Save equalizer preset"), TRUE);
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
-        save_preset_file(file_uri);
-        g_free(file_uri);
-    }
-
-    songname = playlist_get_filename(playlist, playlist_get_position(playlist));
-    if (songname) {
-        gchar *eqname = g_strdup_printf("%s.%s", songname,
-                                        cfg.eqpreset_extension);
-        g_free(songname);
-        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
-                                      eqname);
-        g_free(eqname);
-    }
-
-    gtk_widget_destroy(dialog);
-}
-
-void
-action_equ_save_preset_eqf(void)
-{
-    GtkWidget *dialog;
-    gchar *file_uri;
-
-    dialog = make_filebrowser(Q_("Save equalizer preset"), TRUE);
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
-        save_winamp_file(file_uri);
-        g_free(file_uri);
-    }
-    gtk_widget_destroy(dialog);
-}
-
-void
-action_equ_delete_preset(void)
-{
-    if (equalizerwin_delete_window) {
-        gtk_window_present(GTK_WINDOW(equalizerwin_delete_window));
-        return;
-    }
-    
-    equalizerwin_create_list_window(equalizer_presets,
-                                    Q_("Delete preset"),
-                                    &equalizerwin_delete_window,
-                                    GTK_SELECTION_EXTENDED, NULL,
-                                    GTK_STOCK_DELETE,
-                                    G_CALLBACK(equalizerwin_delete_delete),
-                                    NULL);
-}
-
-void
-action_equ_delete_auto_preset(void)
-{
-    if (equalizerwin_delete_auto_window) {
-        gtk_window_present(GTK_WINDOW(equalizerwin_delete_auto_window));
-        return;
-    }
-    
-    equalizerwin_create_list_window(equalizer_auto_presets,
-                                    Q_("Delete auto-preset"),
-                                    &equalizerwin_delete_auto_window,
-                                    GTK_SELECTION_EXTENDED, NULL,
-                                    GTK_STOCK_DELETE,
-                                    G_CALLBACK(equalizerwin_delete_auto_delete),
-                                    NULL);
-}
-
-void
-equalizer_activate(gboolean active)
-{
-    cfg.equalizer_active = active;
-    UI_SKINNED_BUTTON(equalizerwin_on)->inside = active;
-    gtk_widget_queue_draw(equalizerwin_on);
-
-    equalizerwin_eq_changed();
-}
--- a/src/audacious/ui_equalizer.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  Based on BMP:
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_EQUALIZER_H
-#define AUDACIOUS_UI_EQUALIZER_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#define EQUALIZER_SCALED     (cfg.scaled && cfg.eq_scaled_linked)
-#define EQUALIZER_SCALE_FACTOR (EQUALIZER_SCALED ? cfg.scale_factor : 1)
-
-#define EQUALIZER_HEIGHT         ((cfg.equalizer_shaded ? 14 : 116) * (EQUALIZER_SCALE_FACTOR))
-#define EQUALIZER_WIDTH          (275 * EQUALIZER_SCALE_FACTOR)
-
-#define EQUALIZER_DEFAULT_POS_X  20
-#define EQUALIZER_DEFAULT_POS_Y  136
-
-#define EQUALIZER_DEFAULT_DIR_PRESET "dir_default.preset"
-#define EQUALIZER_DEFAULT_PRESET_EXT "preset"
-
-void equalizerwin_set_scaled(gboolean ds);
-void equalizerwin_set_shade_menu_cb(gboolean shaded);
-void draw_equalizer_window(gboolean force);
-void equalizerwin_create(void);
-void equalizerwin_show(gboolean show);
-void equalizerwin_real_show(void);
-void equalizerwin_real_hide(void);
-void equalizerwin_load_auto_preset(const gchar * filename);
-void equalizerwin_set_volume_slider(gint percent);
-void equalizerwin_set_balance_slider(gint percent);
-void equalizerwin_eq_changed(void);
-void equalizerwin_set_preamp(gfloat preamp);
-void equalizerwin_set_band(gint band, gfloat value);
-gfloat equalizerwin_get_preamp(void);
-gfloat equalizerwin_get_band(gint band);
-
-gboolean equalizerwin_has_focus(void);
-
-extern GtkWidget *equalizerwin;
-extern GtkWidget *equalizerwin_graph;
-extern gboolean equalizerwin_focus;
-
-void equalizer_activate(gboolean active);
-
-#endif /* AUDACIOUS_UI_EQUALIZER_H */
--- a/src/audacious/ui_fileinfo.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_fileinfo.c	Wed Aug 06 22:33:27 2008 +0300
@@ -55,11 +55,8 @@
 
 #include "playlist.h"
 
-#include "ui_main.h"
-#include "ui_playlist.h"
 #include "build_stamp.h"
 #include "ui_fileinfo.h"
-#include "ui_playlist.h"
 
 #define G_FREE_CLEAR(a) if(a != NULL) { g_free(a); a = NULL; }
 #define STATUS_TIMEOUT 3*1000
--- a/src/audacious/ui_fileopener.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_fileopener.c	Wed Aug 06 22:33:27 2008 +0300
@@ -27,7 +27,6 @@
 #include "main.h"
 #include "playback.h"
 #include "strings.h"
-#include "ui_playlist.h"
 
 static void
 filebrowser_add_files(GtkFileChooser * browser,
@@ -49,7 +48,7 @@
         g_free(filename);
     } 
 
-    playlistwin_update_list(playlist);
+    hook_call("playlist update", playlist);
 
     ptr = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(browser));
 
@@ -286,7 +285,7 @@
         playlist_add(playlist, filename);
         g_free(filename);
     }
-    playlistwin_update_list(playlist);
+    hook_call("playlist update", playlist);
 
     gtk_label_get(GTK_LABEL(GTK_BIN(filesel->history_pulldown)->child),
           &ptr);
--- a/src/audacious/ui_hints.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team
- *
- *  Based on BMP:
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#include "ui_hints.h"
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "ui_playlist.h"
-
-#include "platform/smartinclude.h"
-
-void
-hint_set_always(gboolean always)
-{
-    gtk_window_set_keep_above(GTK_WINDOW(mainwin), always);
-    gtk_window_set_keep_above(GTK_WINDOW(equalizerwin), always);
-    gtk_window_set_keep_above(GTK_WINDOW(playlistwin), always);
-}
-
-void
-hint_set_sticky(gboolean sticky)
-{
-    if (sticky) {
-        gtk_window_stick(GTK_WINDOW(mainwin));
-        gtk_window_stick(GTK_WINDOW(equalizerwin));
-        gtk_window_stick(GTK_WINDOW(playlistwin));
-    }
-    else {
-        gtk_window_unstick(GTK_WINDOW(mainwin));
-        gtk_window_unstick(GTK_WINDOW(equalizerwin));
-        gtk_window_unstick(GTK_WINDOW(playlistwin));
-    }
-}
-
--- a/src/audacious/ui_hints.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team
- *
- *  Based on BMP:
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_HINTS_H
-#define AUDACIOUS_UI_HINTS_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-void hint_set_always(gboolean always);
-void hint_set_sticky(gboolean sticky);
-
-#endif /* AUDACIOUS_UI_HINTS_H */
--- a/src/audacious/ui_jumptotrack.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_jumptotrack.c	Wed Aug 06 22:33:27 2008 +0300
@@ -51,7 +51,6 @@
   #include <regex.h>
 #endif
 
-#include "ui_main.h"
 #include "icons-stock.h"
 
 #include "actions-mainwin.h"
@@ -64,20 +63,12 @@
 #include "playlist.h"
 #include "pluginenum.h"
 #include "ui_credits.h"
-#include "ui_dock.h"
-#include "ui_equalizer.h"
 #include "ui_fileopener.h"
-#include "ui_manager.h"
-#include "ui_playlist.h"
 #include "ui_preferences.h"
-#include "ui_skinselector.h"
-#include "ui_urlopener.h"
 #include "strings.h"
 #include "util.h"
 #include "visualization.h"
 
-#include "ui_skinned_window.h"
-
 #include "ui_jumptotrack_cache.h"
 
 static GtkWidget *jump_to_track_win = NULL;
--- a/src/audacious/ui_jumptotrack.h	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_jumptotrack.h	Wed Aug 06 22:33:27 2008 +0300
@@ -26,8 +26,8 @@
 #ifndef AUDACIOUS_UI_JUMPTOTRACK_H
 #define AUDACIOUS_UI_JUMPTOTRACK_H
 
-extern void ui_jump_to_track_update(GtkWidget * widget, gpointer user_data);
-extern void ui_jump_to_track(void);
-extern void ui_jump_to_track_hide(void);
+void ui_jump_to_track_update(GtkWidget * widget, gpointer user_data);
+void ui_jump_to_track(void);
+void ui_jump_to_track_hide(void);
 
 #endif /* AUDACIOUS_UI_JUMPTOTRACK_H */
--- a/src/audacious/ui_legacy.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_legacy.c	Wed Aug 06 22:33:27 2008 +0300
@@ -64,15 +64,15 @@
 #include "playlist.h"
 #include "pluginenum.h"
 #include "signals.h"
-#include "ui_skin.h"
-#include "ui_equalizer.h"
+#include "legacy/ui_skin.h"
+#include "legacy/ui_equalizer.h"
 #include "ui_fileinfo.h"
-#include "ui_hints.h"
-#include "ui_main.h"
-#include "ui_manager.h"
-#include "ui_playlist.h"
+#include "legacy/ui_hints.h"
+#include "legacy/ui_main.h"
+#include "legacy/ui_manager.h"
+#include "legacy/ui_playlist.h"
 #include "ui_preferences.h"
-#include "ui_skinselector.h"
+#include "legacy/ui_skinselector.h"
 #include "util.h"
 
 #include "libSAD.h"
--- a/src/audacious/ui_main.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2850 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2006  Audacious development team.
- *
- *  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <glib/gprintf.h>
-#include <gtk/gtk.h>
-#include <gtk/gtkmessagedialog.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-/* GDK including */
-#include "platform/smartinclude.h"
-
-#if defined(USE_REGEX_ONIGURUMA)
-#include <onigposix.h>
-#elif defined(USE_REGEX_PCRE)
-#include <pcreposix.h>
-#else
-#include <regex.h>
-#endif
-
-#include "ui_main.h"
-#include "icons-stock.h"
-
-#include "actions-mainwin.h"
-#include "configdb.h"
-#include "dnd.h"
-#include "input.h"
-#include "main.h"
-#include "playback.h"
-#include "playlist.h"
-#include "pluginenum.h"
-#include "strings.h"
-#include "ui_credits.h"
-#include "ui_dock.h"
-#include "ui_equalizer.h"
-#include "ui_fileinfo.h"
-#include "ui_fileopener.h"
-#include "ui_hints.h"
-#include "ui_jumptotrack.h"
-#include "ui_main_evlisteners.h"
-#include "ui_manager.h"
-#include "ui_playlist.h"
-#include "ui_preferences.h"
-#include "ui_skinselector.h"
-#include "ui_urlopener.h"
-#include "util.h"
-#include "visualization.h"
-
-#include "ui_skinned_window.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_textbox.h"
-#include "ui_skinned_number.h"
-#include "ui_skinned_horizontal_slider.h"
-#include "ui_skinned_menurow.h"
-#include "ui_skinned_playstatus.h"
-#include "ui_skinned_monostereo.h"
-#include "ui_skinned_playlist.h"
-
-static GTimeVal cb_time; 
-static const int TRISTATE_THRESHOLD = 200;
-
-enum {
-    MAINWIN_SEEK_REV = -1,
-    MAINWIN_SEEK_NIL,
-    MAINWIN_SEEK_FWD
-};
-
-GtkWidget *mainwin = NULL;
-
-static gint balance;
-
-static GtkWidget *mainwin_jtt = NULL;
-
-static gint seek_state = MAINWIN_SEEK_NIL;
-static gint seek_initial_pos = 0;
-
-static GtkWidget *mainwin_menubtn;
-static GtkWidget *mainwin_minimize, *mainwin_shade, *mainwin_close;
-
-static GtkWidget *mainwin_rew, *mainwin_fwd;
-static GtkWidget *mainwin_eject;
-static GtkWidget *mainwin_play, *mainwin_pause, *mainwin_stop;
-
-static GtkWidget *mainwin_shuffle, *mainwin_repeat;
-GtkWidget *mainwin_eq, *mainwin_pl;
-
-GtkWidget *mainwin_info;
-GtkWidget *mainwin_stime_min, *mainwin_stime_sec;
-
-static GtkWidget *mainwin_rate_text, *mainwin_freq_text, *mainwin_othertext;
-
-GtkWidget *mainwin_playstatus;
-
-GtkWidget *mainwin_minus_num, *mainwin_10min_num, *mainwin_min_num;
-GtkWidget *mainwin_10sec_num, *mainwin_sec_num;
-
-GtkWidget *mainwin_vis;
-GtkWidget *mainwin_svis;
-
-GtkWidget *mainwin_sposition = NULL;
-
-static GtkWidget *mainwin_menurow;
-static GtkWidget *mainwin_volume, *mainwin_balance;
-GtkWidget *mainwin_position;
-
-static GtkWidget *mainwin_monostereo;
-static GtkWidget *mainwin_srew, *mainwin_splay, *mainwin_spause;
-static GtkWidget *mainwin_sstop, *mainwin_sfwd, *mainwin_seject, *mainwin_about;
-
-static gint mainwin_timeout_id;
-
-static gboolean mainwin_info_text_locked = FALSE;
-static guint mainwin_volume_release_timeout = 0;
-
-static int ab_position_a = -1;
-static int ab_position_b = -1;
-
-static void mainwin_refresh_visible(void);
-static gint mainwin_idle_func(gpointer data);
-
-static void set_timer_mode_menu_cb(TimerMode mode);
-static void set_timer_mode(TimerMode mode);
-static void change_timer_mode(void);
-
-static void mainwin_position_motion_cb(GtkWidget *widget, gint pos);
-static void mainwin_position_release_cb(GtkWidget *widget, gint pos);
-
-static void set_scaled(gboolean scaled);
-static void mainwin_eq_pushed(gboolean toggled);
-static void mainwin_pl_pushed(gboolean toggled);
-
-static void
-mainwin_set_title_scroll(gboolean scroll)
-{
-    cfg.autoscroll = scroll;
-    ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll);
-}
-
-
-void
-mainwin_set_always_on_top(gboolean always)
-{
-    GtkAction *action = gtk_action_group_get_action(toggleaction_group_others,
-                                                    "view always on top");
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , always );
-}
-
-static void
-mainwin_set_shade(gboolean shaded)
-{
-    GtkAction *action = gtk_action_group_get_action(toggleaction_group_others,
-                                                    "roll up player");
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded );
-}
-
-static void
-mainwin_set_shade_menu_cb(gboolean shaded)
-{
-    cfg.player_shaded = shaded;
-
-    if (shaded) {
-        dock_shade(get_dock_window_list(), GTK_WINDOW(mainwin),
-                   MAINWIN_SHADED_HEIGHT * MAINWIN_SCALE_FACTOR);
-    } else {
-        gint height = !aud_active_skin->properties.mainwin_height ? MAINWIN_HEIGHT :
-            aud_active_skin->properties.mainwin_height;
-
-        dock_shade(get_dock_window_list(), GTK_WINDOW(mainwin), height * MAINWIN_SCALE_FACTOR);
-    }
-
-    mainwin_refresh_hints();
-    ui_skinned_set_push_button_data(mainwin_shade, 0, cfg.player_shaded ? 27 : 18, 9, cfg.player_shaded ? 27 : 18);
-    gtk_widget_shape_combine_mask(mainwin, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
-}
-
-static void
-mainwin_vis_set_refresh(RefreshRate rate)
-{
-    cfg.vis_refresh = rate;
-}
-
-static void
-mainwin_vis_set_afalloff(FalloffSpeed speed)
-{
-    cfg.analyzer_falloff = speed;
-}
-
-static void
-mainwin_vis_set_pfalloff(FalloffSpeed speed)
-{
-    cfg.peaks_falloff = speed;
-}
-
-static void
-mainwin_vis_set_analyzer_mode(AnalyzerMode mode)
-{
-    cfg.analyzer_mode = mode;
-}
-
-static void
-mainwin_vis_set_analyzer_type(AnalyzerType mode)
-{
-    cfg.analyzer_type = mode;
-}
-
-void
-mainwin_vis_set_type(VisType mode)
-{
-    GtkAction *action;
-
-    switch ( mode )
-    {
-        case VIS_ANALYZER:
-            action = gtk_action_group_get_action(radioaction_group_vismode,
-                                                 "vismode analyzer");
-            break;
-        case VIS_SCOPE:
-            action = gtk_action_group_get_action(radioaction_group_vismode,
-                                                 "vismode scope");
-            break;
-        case VIS_VOICEPRINT:
-            action = gtk_action_group_get_action(radioaction_group_vismode,
-                                                 "vismode voiceprint");
-            break;
-        case VIS_OFF:
-        default:
-            action = gtk_action_group_get_action(radioaction_group_vismode,
-                                                 "vismode off");
-            break;
-    }
-
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , TRUE );
-}
-
-static void
-mainwin_vis_set_type_menu_cb(VisType mode)
-{
-    cfg.vis_type = mode;
-
-    if (mode == VIS_OFF) {
-        if (cfg.player_shaded) {
-            ui_svis_set_visible(mainwin_svis, FALSE);
-            ui_vis_set_visible(mainwin_vis, TRUE);
-        } else {
-            ui_svis_set_visible(mainwin_svis, TRUE);
-            ui_vis_set_visible(mainwin_vis, FALSE);
-        }
-    }
-    if (mode == VIS_ANALYZER || mode == VIS_SCOPE || mode == VIS_VOICEPRINT) {
-        if (cfg.player_shaded) {
-            ui_svis_clear_data(mainwin_svis);
-            ui_svis_set_visible(mainwin_svis, TRUE);
-            ui_vis_clear_data(mainwin_vis);
-            ui_vis_set_visible(mainwin_vis, FALSE);
-        } else {
-            ui_svis_clear_data(mainwin_svis);
-            ui_svis_set_visible(mainwin_svis, FALSE);
-            ui_vis_clear_data(mainwin_vis);
-            ui_vis_set_visible(mainwin_vis, TRUE);
-        }
-    }
-}
-
-static void
-mainwin_menubtn_cb(void)
-{
-    gint x, y;
-    gtk_window_get_position(GTK_WINDOW(mainwin), &x, &y);
-    ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu),
-                               x + 6 * MAINWIN_SCALE_FACTOR ,
-                               y + MAINWIN_SHADED_HEIGHT * MAINWIN_SCALE_FACTOR,
-                               1, GDK_CURRENT_TIME);
-}
-
-void
-mainwin_minimize_cb(void)
-{
-    if (!mainwin)
-        return;
-
-    gtk_window_iconify(GTK_WINDOW(mainwin));
-}
-
-static void
-mainwin_shade_toggle(void)
-{
-    mainwin_set_shade(!cfg.player_shaded);
-}
-
-void
-mainwin_quit_cb(void)
-{
-    if (mainwin_timeout_id)
-        g_source_remove(mainwin_timeout_id);
-
-    aud_quit();
-}
-
-gboolean
-mainwin_vis_cb(GtkWidget *widget, GdkEventButton *event)
-{
-    if (event->button == 1) {
-        cfg.vis_type++;
-
-        if (cfg.vis_type > VIS_OFF)
-            cfg.vis_type = VIS_ANALYZER;
-
-        mainwin_vis_set_type(cfg.vis_type);
-    } else if (event->button == 3) {
-        ui_manager_popup_menu_show(GTK_MENU(mainwin_visualization_menu),
-                                   event->x_root, event->y_root, 3,
-                                   event->time);
-    }
-    return TRUE;
-}
-
-static void
-mainwin_destroy(GtkWidget * widget, gpointer data)
-{
-    mainwin_quit_cb();
-}
-
-static gchar *mainwin_tb_old_text = NULL;
-
-void
-mainwin_lock_info_text(const gchar * text)
-{
-    if (mainwin_info_text_locked != TRUE)
-        mainwin_tb_old_text = g_strdup(aud_active_skin->properties.mainwin_othertext_is_status ?
-                                       UI_SKINNED_TEXTBOX(mainwin_othertext)->text : UI_SKINNED_TEXTBOX(mainwin_info)->text);
-
-    mainwin_info_text_locked = TRUE;
-    if (aud_active_skin->properties.mainwin_othertext_is_status)
-        ui_skinned_textbox_set_text(mainwin_othertext, text);
-    else
-        ui_skinned_textbox_set_text(mainwin_info, text);
-}
-
-void
-mainwin_release_info_text(void)
-{
-    mainwin_info_text_locked = FALSE;
-
-    if (mainwin_tb_old_text != NULL)
-    {
-        if (aud_active_skin->properties.mainwin_othertext_is_status)
-            ui_skinned_textbox_set_text(mainwin_othertext, mainwin_tb_old_text);
-        else
-            ui_skinned_textbox_set_text(mainwin_info, mainwin_tb_old_text);
-        g_free(mainwin_tb_old_text);
-        mainwin_tb_old_text = NULL;
-    }
-}
-
-
-static gchar *
-make_mainwin_title(const gchar * title)
-{
-    if (title)
-        return g_strdup_printf(_("%s - Audacious"), title);
-    else
-        return g_strdup(_("Audacious"));
-}
-
-void
-mainwin_set_song_title(const gchar * title)
-{
-    gchar *mainwin_title_text = make_mainwin_title(title);
-    gtk_window_set_title(GTK_WINDOW(mainwin), mainwin_title_text);
-    g_free(mainwin_title_text);
-}
-
-static void
-mainwin_refresh_visible(void)
-{
-    if (!aud_active_skin || !cfg.player_visible)
-        return;
-
-    gtk_widget_show_all(mainwin);
-
-    if (!aud_active_skin->properties.mainwin_text_visible)
-        gtk_widget_hide(mainwin_info);
-
-    if (!aud_active_skin->properties.mainwin_vis_visible)
-        gtk_widget_hide(mainwin_vis);
-
-    if (!aud_active_skin->properties.mainwin_menurow_visible)
-        gtk_widget_hide(mainwin_menurow);
-
-    if (aud_active_skin->properties.mainwin_othertext) {
-        gtk_widget_hide(mainwin_rate_text);
-        gtk_widget_hide(mainwin_freq_text);
-        gtk_widget_hide(mainwin_monostereo);
-
-        if (!aud_active_skin->properties.mainwin_othertext_visible)
-            gtk_widget_hide(mainwin_othertext);
-    } else {
-        gtk_widget_hide(mainwin_othertext);
-    }
-
-    if (!aud_active_skin->properties.mainwin_vis_visible)
-        gtk_widget_hide(mainwin_vis);
-
-    if (!playback_get_playing()) {
-        gtk_widget_hide(mainwin_minus_num);
-        gtk_widget_hide(mainwin_10min_num);
-        gtk_widget_hide(mainwin_min_num);
-        gtk_widget_hide(mainwin_10sec_num);
-        gtk_widget_hide(mainwin_sec_num);
-
-        gtk_widget_hide(mainwin_stime_min);
-        gtk_widget_hide(mainwin_stime_sec);
-
-        gtk_widget_hide(mainwin_position);
-        gtk_widget_hide(mainwin_sposition);
-    }
-
-    if (cfg.player_shaded) {
-        ui_svis_clear_data(mainwin_svis);
-        if (cfg.vis_type != VIS_OFF)
-            ui_svis_set_visible(mainwin_svis, TRUE);
-        else
-            ui_svis_set_visible(mainwin_svis, FALSE);
-
-        ui_skinned_textbox_set_scroll(mainwin_info, FALSE);
-        if (!playback_get_playing()) {
-            gtk_widget_hide(mainwin_sposition);
-            gtk_widget_hide(mainwin_stime_min);
-            gtk_widget_hide(mainwin_stime_sec);
-        }
-    } else {
-        gtk_widget_hide(mainwin_srew);
-        gtk_widget_hide(mainwin_splay);
-        gtk_widget_hide(mainwin_spause);
-        gtk_widget_hide(mainwin_sstop);
-        gtk_widget_hide(mainwin_sfwd);
-        gtk_widget_hide(mainwin_seject);
-        gtk_widget_hide(mainwin_stime_min);
-        gtk_widget_hide(mainwin_stime_sec);
-        gtk_widget_hide(mainwin_svis);
-        gtk_widget_hide(mainwin_sposition);
-        ui_vis_clear_data(mainwin_vis);
-        if (cfg.vis_type != VIS_OFF)
-            ui_vis_set_visible(mainwin_vis, TRUE);
-        else
-            ui_vis_set_visible(mainwin_vis, FALSE);
-
-        ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll);
-    }
-}
-
-void
-mainwin_refresh_hints(void)
-{
-    /* positioning and size attributes */
-    if (aud_active_skin->properties.mainwin_vis_x && aud_active_skin->properties.mainwin_vis_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_vis), aud_active_skin->properties.mainwin_vis_x,
-                       aud_active_skin->properties.mainwin_vis_y);
-
-    if (aud_active_skin->properties.mainwin_vis_width)
-        gtk_widget_set_size_request(mainwin_vis, aud_active_skin->properties.mainwin_vis_width * MAINWIN_SCALE_FACTOR,
-                                    UI_VIS(mainwin_vis)->height* MAINWIN_SCALE_FACTOR);
-
-    if (aud_active_skin->properties.mainwin_text_x && aud_active_skin->properties.mainwin_text_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_info), aud_active_skin->properties.mainwin_text_x,
-                       aud_active_skin->properties.mainwin_text_y);
-
-    if (aud_active_skin->properties.mainwin_text_width) {
-        UI_SKINNED_TEXTBOX(mainwin_info)->width = aud_active_skin->properties.mainwin_text_width;
-        gtk_widget_set_size_request(mainwin_info, aud_active_skin->properties.mainwin_text_width * MAINWIN_SCALE_FACTOR,
-                                    UI_SKINNED_TEXTBOX(mainwin_info)->height * MAINWIN_SCALE_FACTOR );
-    }
-
-    if (aud_active_skin->properties.mainwin_infobar_x && aud_active_skin->properties.mainwin_infobar_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_othertext), aud_active_skin->properties.mainwin_infobar_x,
-                       aud_active_skin->properties.mainwin_infobar_y);
-
-    if (aud_active_skin->properties.mainwin_number_0_x && aud_active_skin->properties.mainwin_number_0_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_minus_num), aud_active_skin->properties.mainwin_number_0_x,
-                       aud_active_skin->properties.mainwin_number_0_y);
-
-    if (aud_active_skin->properties.mainwin_number_1_x && aud_active_skin->properties.mainwin_number_1_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_10min_num), aud_active_skin->properties.mainwin_number_1_x,
-                       aud_active_skin->properties.mainwin_number_1_y);
-
-    if (aud_active_skin->properties.mainwin_number_2_x && aud_active_skin->properties.mainwin_number_2_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_min_num), aud_active_skin->properties.mainwin_number_2_x,
-                       aud_active_skin->properties.mainwin_number_2_y);
-
-    if (aud_active_skin->properties.mainwin_number_3_x && aud_active_skin->properties.mainwin_number_3_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_10sec_num), aud_active_skin->properties.mainwin_number_3_x,
-                       aud_active_skin->properties.mainwin_number_3_y);
-
-    if (aud_active_skin->properties.mainwin_number_4_x && aud_active_skin->properties.mainwin_number_4_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_sec_num), aud_active_skin->properties.mainwin_number_4_x,
-                       aud_active_skin->properties.mainwin_number_4_y);
-
-    if (aud_active_skin->properties.mainwin_playstatus_x && aud_active_skin->properties.mainwin_playstatus_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_playstatus, aud_active_skin->properties.mainwin_playstatus_x,
-                       aud_active_skin->properties.mainwin_playstatus_y);
-
-    if (aud_active_skin->properties.mainwin_volume_x && aud_active_skin->properties.mainwin_volume_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_volume), aud_active_skin->properties.mainwin_volume_x,
-                       aud_active_skin->properties.mainwin_volume_y);
-
-    if (aud_active_skin->properties.mainwin_balance_x && aud_active_skin->properties.mainwin_balance_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_balance), aud_active_skin->properties.mainwin_balance_x,
-                       aud_active_skin->properties.mainwin_balance_y);
-
-    if (aud_active_skin->properties.mainwin_position_x && aud_active_skin->properties.mainwin_position_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_position), aud_active_skin->properties.mainwin_position_x,
-                       aud_active_skin->properties.mainwin_position_y);
-
-    if (aud_active_skin->properties.mainwin_previous_x && aud_active_skin->properties.mainwin_previous_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_rew, aud_active_skin->properties.mainwin_previous_x,
-                       aud_active_skin->properties.mainwin_previous_y);
-
-    if (aud_active_skin->properties.mainwin_play_x && aud_active_skin->properties.mainwin_play_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_play), aud_active_skin->properties.mainwin_play_x,
-                       aud_active_skin->properties.mainwin_play_y);
-
-    if (aud_active_skin->properties.mainwin_pause_x && aud_active_skin->properties.mainwin_pause_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_pause), aud_active_skin->properties.mainwin_pause_x,
-                       aud_active_skin->properties.mainwin_pause_y);
-
-    if (aud_active_skin->properties.mainwin_stop_x && aud_active_skin->properties.mainwin_stop_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_stop), aud_active_skin->properties.mainwin_stop_x,
-                       aud_active_skin->properties.mainwin_stop_y);
-
-    if (aud_active_skin->properties.mainwin_next_x && aud_active_skin->properties.mainwin_next_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_fwd), aud_active_skin->properties.mainwin_next_x,
-                       aud_active_skin->properties.mainwin_next_y);
-
-    if (aud_active_skin->properties.mainwin_eject_x && aud_active_skin->properties.mainwin_eject_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_eject), aud_active_skin->properties.mainwin_eject_x,
-                       aud_active_skin->properties.mainwin_eject_y);
-
-    if (aud_active_skin->properties.mainwin_eqbutton_x && aud_active_skin->properties.mainwin_eqbutton_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_eq), aud_active_skin->properties.mainwin_eqbutton_x,
-                       aud_active_skin->properties.mainwin_eqbutton_y);
-
-    if (aud_active_skin->properties.mainwin_plbutton_x && aud_active_skin->properties.mainwin_plbutton_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_pl), aud_active_skin->properties.mainwin_plbutton_x,
-                       aud_active_skin->properties.mainwin_plbutton_y);
-
-    if (aud_active_skin->properties.mainwin_shuffle_x && aud_active_skin->properties.mainwin_shuffle_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_shuffle), aud_active_skin->properties.mainwin_shuffle_x,
-                       aud_active_skin->properties.mainwin_shuffle_y);
-
-    if (aud_active_skin->properties.mainwin_repeat_x && aud_active_skin->properties.mainwin_repeat_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_repeat), aud_active_skin->properties.mainwin_repeat_x,
-                       aud_active_skin->properties.mainwin_repeat_y);
-
-    if (aud_active_skin->properties.mainwin_about_x && aud_active_skin->properties.mainwin_about_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_about), aud_active_skin->properties.mainwin_about_x,
-                       aud_active_skin->properties.mainwin_about_y);
-
-    if (aud_active_skin->properties.mainwin_minimize_x && aud_active_skin->properties.mainwin_minimize_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_minimize), cfg.player_shaded ? 244 : aud_active_skin->properties.mainwin_minimize_x,
-                       cfg.player_shaded ? 3 : aud_active_skin->properties.mainwin_minimize_y);
-
-    if (aud_active_skin->properties.mainwin_shade_x && aud_active_skin->properties.mainwin_shade_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_shade), cfg.player_shaded ? 254 : aud_active_skin->properties.mainwin_shade_x,
-                       cfg.player_shaded ? 3 : aud_active_skin->properties.mainwin_shade_y);
-
-    if (aud_active_skin->properties.mainwin_close_x && aud_active_skin->properties.mainwin_close_y)
-        gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_close), cfg.player_shaded ? 264 : aud_active_skin->properties.mainwin_close_x,
-                       cfg.player_shaded ? 3 : aud_active_skin->properties.mainwin_close_y);
-
-    mainwin_refresh_visible();
-
-    /* window size, mainwinWidth && mainwinHeight properties */
-    if (aud_active_skin->properties.mainwin_height && aud_active_skin->properties.mainwin_width)
-    {
-        dock_window_resize(GTK_WINDOW(mainwin), cfg.player_shaded ? MAINWIN_SHADED_WIDTH * MAINWIN_SCALE_FACTOR : aud_active_skin->properties.mainwin_width * MAINWIN_SCALE_FACTOR,
-                           cfg.player_shaded ? MAINWIN_SHADED_HEIGHT * MAINWIN_SCALE_FACTOR : aud_active_skin->properties.mainwin_height * MAINWIN_SCALE_FACTOR,
-                           aud_active_skin->properties.mainwin_width * MAINWIN_SCALE_FACTOR,
-                           aud_active_skin->properties.mainwin_height * MAINWIN_SCALE_FACTOR);
-
-        gdk_flush();
-    }
-}
-
-void
-mainwin_set_song_info(gint bitrate,
-                      gint frequency,
-                      gint n_channels)
-{
-    gchar *text;
-    gchar *title;
-    Playlist *playlist = playlist_get_active();
-
-    GDK_THREADS_ENTER();
-    if (bitrate != -1) {
-        bitrate /= 1000;
-
-        if (bitrate < 1000) {
-            /* Show bitrate in 1000s */
-            text = g_strdup_printf("%3d", bitrate);
-        }
-        else {
-            /* Show bitrate in 100,000s */
-            text = g_strdup_printf("%2dH", bitrate / 100);
-        }
-        ui_skinned_textbox_set_text(mainwin_rate_text, text);
-        g_free(text);
-    }
-    else
-        ui_skinned_textbox_set_text(mainwin_rate_text, _("VBR"));
-
-    /* Show sampling frequency in kHz */
-    text = g_strdup_printf("%2d", frequency / 1000);
-    ui_skinned_textbox_set_text(mainwin_freq_text, text);
-    g_free(text);
-
-    ui_skinned_monostereo_set_num_channels(mainwin_monostereo, n_channels);
-
-    if (!playback_get_paused() && mainwin_playstatus != NULL)
-        ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
-
-    if (aud_active_skin && aud_active_skin->properties.mainwin_othertext)
-    {
-        if (bitrate != -1)
-            text = g_strdup_printf("%d kbps, %0.1f kHz, %s",
-                                   bitrate,
-                                   (gfloat) frequency / 1000,
-                                   (n_channels > 1) ? _("stereo") : _("mono"));
-        else
-            text = g_strdup_printf("VBR, %0.1f kHz, %s",
-                                   (gfloat) frequency / 1000,
-                                   (n_channels > 1) ? _("stereo") : _("mono"));
-
-        ui_skinned_textbox_set_text(mainwin_othertext, text);
-        g_free(text);
-    }
-
-    title = playlist_get_info_text(playlist);
-    mainwin_set_song_title(title);
-    g_free(title);
-    GDK_THREADS_LEAVE();
-}
-
-void
-mainwin_clear_song_info(void)
-{
-    if (!mainwin)
-        return;
-
-    /* clear title */
-    mainwin_set_song_title(NULL);
-
-    /* clear sampling parameters */
-    playback_set_sample_params(0, 0, 0);
-
-    UI_SKINNED_HORIZONTAL_SLIDER(mainwin_position)->pressed = FALSE;
-    UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->pressed = FALSE;
-
-    /* clear sampling parameter displays */
-    ui_skinned_textbox_set_text(mainwin_rate_text, "   ");
-    ui_skinned_textbox_set_text(mainwin_freq_text, "  ");
-    ui_skinned_monostereo_set_num_channels(mainwin_monostereo, 0);
-
-    if (mainwin_playstatus != NULL)
-        ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_STOP);
-
-    mainwin_refresh_visible();
-
-    playlistwin_hide_timer();
-    ui_vis_clear_data(mainwin_vis);
-    ui_svis_clear_data(mainwin_svis);
-}
-
-void
-mainwin_disable_seekbar(void)
-{
-    if (!mainwin)
-        return;
-
-    gtk_widget_hide(mainwin_position);
-    gtk_widget_hide(mainwin_sposition);
-}
-
-static gboolean
-mainwin_mouse_button_release(GtkWidget * widget,
-                             GdkEventButton * event,
-                             gpointer callback_data)
-{
-    if (dock_is_moving(GTK_WINDOW(mainwin))) {
-        dock_move_release(GTK_WINDOW(mainwin));
-    }
-
-    return FALSE;
-}
-
-void
-mainwin_scrolled(GtkWidget *widget, GdkEventScroll *event,
-                 gpointer callback_data)
-{
-    Playlist *playlist = playlist_get_active();
-
-    switch (event->direction) {
-        case GDK_SCROLL_UP:
-            mainwin_set_volume_diff(cfg.mouse_change);
-            break;
-        case GDK_SCROLL_DOWN:
-            mainwin_set_volume_diff(-cfg.mouse_change);
-            break;
-        case GDK_SCROLL_LEFT:
-            if (playlist_get_current_length(playlist) != -1)
-                playback_seek(CLAMP(playback_get_time() - 1000,
-                                    0, playlist_get_current_length(playlist)) / 1000);
-            break;
-        case GDK_SCROLL_RIGHT:
-            if (playlist_get_current_length(playlist) != -1)
-                playback_seek(CLAMP(playback_get_time() + 1000,
-                                    0, playlist_get_current_length(playlist)) / 1000);
-            break;
-    }
-}
-
-static gboolean
-mainwin_widget_contained(GdkEventButton *event, int x, int y, int w, int h)
-{
-    if ((event->x > x && event->y > y) &&
-        (event->x < x+w && event->y < y+h))
-        return TRUE;
-
-    return FALSE;
-}
-
-static gboolean
-mainwin_mouse_button_press(GtkWidget * widget,
-                           GdkEventButton * event,
-                           gpointer callback_data)
-{
-    if (cfg.scaled) {
-        /*
-         * A hack to make scaling transparent to callbacks.
-         * We should make a copy of this data instead of
-         * tampering with the data we get from gtk+
-         */
-        event->x /= cfg.scale_factor;
-        event->y /= cfg.scale_factor;
-    }
-
-    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS && event->y < 14) {
-        mainwin_set_shade(!cfg.player_shaded);
-        if (dock_is_moving(GTK_WINDOW(mainwin)))
-            dock_move_release(GTK_WINDOW(mainwin));
-        return TRUE;
-    }
-
-    if (event->button == 3) {
-        /* Pop up playback menu if right clicked over playback-control widgets,
-         * otherwise popup general menu
-         */
-        if (mainwin_widget_contained(event, aud_active_skin->properties.mainwin_position_x,
-                                     aud_active_skin->properties.mainwin_position_y, 248, 10) ||
-            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_previous_x,
-                                     aud_active_skin->properties.mainwin_previous_y, 23, 18) ||
-            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_play_x,
-                                     aud_active_skin->properties.mainwin_play_y, 23, 18) ||
-            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_pause_x,
-                                     aud_active_skin->properties.mainwin_pause_y, 23, 18) ||
-            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_stop_x,
-                                     aud_active_skin->properties.mainwin_stop_y, 23, 18) ||
-            mainwin_widget_contained(event, aud_active_skin->properties.mainwin_next_x,
-                                     aud_active_skin->properties.mainwin_next_y, 23, 18))
-        {
-
-            ui_manager_popup_menu_show(GTK_MENU(mainwin_playback_menu),
-                                       event->x_root,
-                                       event->y_root, 3, event->time);
-        } else {
-            /*
-             * Pop up the main menu a few pixels down.
-             * This will avoid that anything is selected
-             * if one right-clicks to focus the window
-             * without raising it.
-             *
-             ***MD I think the above is stupid, people don't expect this
-             *
-             */
-            ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu),
-                                       event->x_root,
-                                       event->y_root, 3, event->time);
-        }
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-static gboolean
-mainwin_keypress(GtkWidget * grab_widget,
-                 GdkEventKey * event,
-                 gpointer data)
-{
-    Playlist *playlist = playlist_get_active();
-
-    switch (event->keyval) {
-
-        case GDK_Up:
-        case GDK_KP_Up:
-        case GDK_KP_8:
-            mainwin_set_volume_diff(2);
-            break;
-        case GDK_Down:
-        case GDK_KP_Down:
-        case GDK_KP_2:
-            mainwin_set_volume_diff(-2);
-            break;
-        case GDK_Left:
-        case GDK_KP_Left:
-        case GDK_KP_7:
-            if (playlist_get_current_length(playlist) != -1)
-                playback_seek(CLAMP
-                              (playback_get_time() - 5000, 0,
-                               playlist_get_current_length(playlist)) / 1000);
-            break;
-        case GDK_Right:
-        case GDK_KP_Right:
-        case GDK_KP_9:
-            if (playlist_get_current_length(playlist) != -1)
-                playback_seek(CLAMP
-                              (playback_get_time() + 5000, 0,
-                               playlist_get_current_length(playlist)) / 1000);
-            break;
-        case GDK_KP_4:
-            playlist_prev(playlist);
-            break;
-        case GDK_KP_6:
-            playlist_next(playlist);
-            break;
-        case GDK_KP_Insert:
-            ui_jump_to_track();
-            break;
-        case GDK_Return:
-        case GDK_KP_Enter:
-        case GDK_KP_5:
-            mainwin_play_pushed();
-            break;
-        case GDK_space:
-            playback_pause();
-            break;
-        case GDK_Escape:
-            mainwin_minimize_cb();
-            break;
-        case GDK_Tab:
-            if (event->state & GDK_CONTROL_MASK) {
-                if (cfg.equalizer_visible)
-                    gtk_window_present(GTK_WINDOW(equalizerwin));
-                else if (cfg.playlist_visible)
-                    gtk_window_present(GTK_WINDOW(playlistwin));
-            }
-            break;
-        case GDK_c:
-            if (event->state & GDK_CONTROL_MASK) {
-                Playlist *playlist = playlist_get_active();
-                gint pos = playlist_get_position(playlist);
-                gchar *title = playlist_get_songtitle(playlist, pos);
-
-                if (title != NULL) {
-                    GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
-                    gtk_clipboard_set_text(clip, title, -1);
-                    gtk_clipboard_store(clip);
-                }
-
-                return TRUE;
-            }
-            return FALSE;
-        default:
-            return FALSE;
-    }
-
-    return TRUE;
-}
-
-static void
-mainwin_jump_to_time_cb(GtkWidget * widget,
-                        GtkWidget * entry)
-{
-    guint min = 0, sec = 0, params;
-    gint time;
-    Playlist *playlist = playlist_get_active();
-
-    params = sscanf(gtk_entry_get_text(GTK_ENTRY(entry)), "%u:%u",
-                    &min, &sec);
-    if (params == 2)
-        time = (min * 60) + sec;
-    else if (params == 1)
-        time = min;
-    else
-        return;
-
-    if (playlist_get_current_length(playlist) > -1 &&
-        time <= (playlist_get_current_length(playlist) / 1000))
-    {
-        playback_seek(time);
-        gtk_widget_destroy(mainwin_jtt);
-    }
-}
-
-
-void
-mainwin_jump_to_time(void)
-{
-    GtkWidget *vbox, *hbox_new, *hbox_total;
-    GtkWidget *time_entry, *label, *bbox, *jump, *cancel;
-    GtkWidget *dialog;
-    guint tindex;
-    gchar time_str[10];
-
-    if (!playback_get_playing()) {
-        dialog =
-            gtk_message_dialog_new (GTK_WINDOW (mainwin),
-                                    GTK_DIALOG_DESTROY_WITH_PARENT,
-                                    GTK_MESSAGE_ERROR,
-                                    GTK_BUTTONS_CLOSE,
-                                    _("Can't jump to time when no track is being played.\n"));
-        gtk_dialog_run (GTK_DIALOG (dialog));
-        gtk_widget_destroy (dialog);
-        return;
-    }
-
-    if (mainwin_jtt) {
-        gtk_window_present(GTK_WINDOW(mainwin_jtt));
-        return;
-    }
-
-    mainwin_jtt = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_type_hint(GTK_WINDOW(mainwin_jtt),
-                             GDK_WINDOW_TYPE_HINT_DIALOG);
-
-    gtk_window_set_title(GTK_WINDOW(mainwin_jtt), _("Jump to Time"));
-    gtk_window_set_position(GTK_WINDOW(mainwin_jtt), GTK_WIN_POS_CENTER);
-    gtk_window_set_transient_for(GTK_WINDOW(mainwin_jtt),
-                                 GTK_WINDOW(mainwin));
-
-    g_signal_connect(mainwin_jtt, "destroy",
-                     G_CALLBACK(gtk_widget_destroyed), &mainwin_jtt);
-    gtk_container_border_width(GTK_CONTAINER(mainwin_jtt), 10);
-
-    vbox = gtk_vbox_new(FALSE, 5);
-    gtk_container_add(GTK_CONTAINER(mainwin_jtt), vbox);
-
-    hbox_new = gtk_hbox_new(FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(vbox), hbox_new, TRUE, TRUE, 5);
-
-    time_entry = gtk_entry_new();
-    gtk_box_pack_start(GTK_BOX(hbox_new), time_entry, FALSE, FALSE, 5);
-    g_signal_connect(time_entry, "activate",
-                     G_CALLBACK(mainwin_jump_to_time_cb), time_entry);
-
-    gtk_widget_set_size_request(time_entry, 70, -1);
-    label = gtk_label_new(_("minutes:seconds"));
-    gtk_box_pack_start(GTK_BOX(hbox_new), label, FALSE, FALSE, 5);
-
-    hbox_total = gtk_hbox_new(FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(vbox), hbox_total, TRUE, TRUE, 5);
-    gtk_widget_show(hbox_total);
-
-    /* FIXME: Disable display of current track length. It's not
-       updated when track changes */
-#if 0
-    label = gtk_label_new(_("Track length:"));
-    gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 5);
-
-    len = playlist_get_current_length() / 1000;
-    g_snprintf(time_str, sizeof(time_str), "%u:%2.2u", len / 60, len % 60);
-    label = gtk_label_new(time_str);
-
-    gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 10);
-#endif
-
-    bbox = gtk_hbutton_box_new();
-    gtk_box_pack_start(GTK_BOX(vbox), bbox, TRUE, TRUE, 0);
-    gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
-    gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
-
-    cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
-    GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
-    gtk_container_add(GTK_CONTAINER(bbox), cancel);
-    g_signal_connect_swapped(cancel, "clicked",
-                             G_CALLBACK(gtk_widget_destroy), mainwin_jtt);
-
-    jump = gtk_button_new_from_stock(GTK_STOCK_JUMP_TO);
-    GTK_WIDGET_SET_FLAGS(jump, GTK_CAN_DEFAULT);
-    gtk_container_add(GTK_CONTAINER(bbox), jump);
-    g_signal_connect(jump, "clicked",
-                     G_CALLBACK(mainwin_jump_to_time_cb), time_entry);
-
-    tindex = playback_get_time() / 1000;
-    g_snprintf(time_str, sizeof(time_str), "%u:%2.2u", tindex / 60,
-               tindex % 60);
-    gtk_entry_set_text(GTK_ENTRY(time_entry), time_str);
-
-    gtk_entry_select_region(GTK_ENTRY(time_entry), 0, strlen(time_str));
-
-    gtk_widget_show_all(mainwin_jtt);
-
-    gtk_widget_grab_focus(time_entry);
-    gtk_widget_grab_default(jump);
-}
-
-/*
- * Rewritten 09/13/06:
- *
- * Remove all of this flaky iter/sourcelist/strsplit stuff.
- * All we care about is the filepath.
- *
- * We can figure this out and easily pass it to g_filename_from_uri().
- *   - nenolod
- */
-void
-mainwin_drag_data_received(GtkWidget * widget,
-                           GdkDragContext * context,
-                           gint x,
-                           gint y,
-                           GtkSelectionData * selection_data,
-                           guint info,
-                           guint time,
-                           gpointer user_data)
-{
-    Playlist *playlist = playlist_get_active();
-
-    g_return_if_fail(selection_data != NULL);
-    g_return_if_fail(selection_data->data != NULL);
-
-    if (str_has_prefix_nocase((gchar *) selection_data->data, "fonts:///"))
-    {
-        gchar *path = (gchar *) selection_data->data;
-        gchar *decoded = g_filename_from_uri(path, NULL, NULL);
-
-        if (decoded == NULL)
-            return;
-
-        cfg.playlist_font = g_strconcat(decoded, strrchr(cfg.playlist_font, ' '), NULL);
-        ui_skinned_playlist_set_font(cfg.playlist_font);
-        playlistwin_update_list(playlist);
-
-        g_free(decoded);
-
-        return;
-    }
-
-    /* perhaps make suffix check case-insensitive -- desowin */
-    if (str_has_prefix_nocase((char*)selection_data->data, "file:///")) {
-        if (str_has_suffix_nocase((char*)selection_data->data, ".wsz\r\n") ||
-            str_has_suffix_nocase((char*)selection_data->data, ".zip\r\n")) {
-            on_skin_view_drag_data_received(GTK_WIDGET(user_data), context, x, y, selection_data, info, time, NULL);
-            return;
-        }
-    }
-
-    playlist_clear(playlist);
-    playlist_add_url(playlist, (gchar *) selection_data->data);
-    playback_initiate();
-}
-
-static void
-on_add_url_add_clicked(GtkWidget * widget,
-                       GtkWidget * entry)
-{
-    const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
-    if (text && *text)
-        playlist_add_url(playlist_get_active(), text);
-}
-
-static void
-on_add_url_ok_clicked(GtkWidget * widget,
-                      GtkWidget * entry)
-{
-    Playlist *playlist = playlist_get_active();
-
-    const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
-    if (text && *text)
-    {
-        playlist_clear(playlist);
-        playlist_add_url(playlist, text);
-        playback_initiate();
-    }
-}
-
-static void
-on_visibility_warning_toggle(GtkToggleButton *tbt, gpointer unused)
-{
-    cfg.warn_about_win_visibility = !gtk_toggle_button_get_active(tbt);
-}
-
-static void
-on_visibility_warning_response(GtkDialog *dlg, gint r_id, gpointer unused)
-{
-    switch (r_id)
-    {
-        case GTK_RESPONSE_OK:
-            mainwin_show(TRUE);
-            break;
-        case GTK_RESPONSE_CANCEL:
-        default:
-            break;
-    }
-    gtk_widget_destroy(GTK_WIDGET(dlg));
-}
-
-void
-mainwin_show_visibility_warning(void)
-{
-    if (cfg.warn_about_win_visibility)
-    {
-        GtkWidget *label, *checkbt, *vbox;
-        GtkWidget *warning_dlg =
-            gtk_dialog_new_with_buttons( _("Audacious - visibility warning") ,
-                                         GTK_WINDOW(mainwin) ,
-                                         GTK_DIALOG_DESTROY_WITH_PARENT ,
-                                         _("Show main player window") ,
-                                         GTK_RESPONSE_OK , _("Ignore") ,
-                                         GTK_RESPONSE_CANCEL , NULL );
-
-        vbox = gtk_vbox_new( FALSE , 4 );
-        gtk_container_set_border_width( GTK_CONTAINER(vbox) , 4 );
-        gtk_box_pack_start( GTK_BOX(GTK_DIALOG(warning_dlg)->vbox) , vbox , TRUE , TRUE , 0 );
-        label = gtk_label_new( _("Audacious has been started with all of its windows hidden.\n"
-                                 "You may want to show the player window again to control Audacious; "
-                                 "otherwise, you'll have to control it remotely via audtool or "
-                                 "enabled plugins (such as the statusicon plugin).") );
-        gtk_label_set_line_wrap( GTK_LABEL(label) , TRUE );
-        gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
-        checkbt = gtk_check_button_new_with_label( _("Always ignore, show/hide is controlled remotely") );
-        gtk_box_pack_start( GTK_BOX(vbox) , label , TRUE , TRUE , 0 );
-        gtk_box_pack_start( GTK_BOX(vbox) , checkbt , TRUE , TRUE , 0 );
-        g_signal_connect( G_OBJECT(checkbt) , "toggled" ,
-                          G_CALLBACK(on_visibility_warning_toggle) , NULL );
-        g_signal_connect( G_OBJECT(warning_dlg) , "response" ,
-                          G_CALLBACK(on_visibility_warning_response) , NULL );
-        gtk_widget_show_all(warning_dlg);
-    }
-}
-
-static void
-on_broken_gtk_engine_warning_toggle(GtkToggleButton *tbt, gpointer unused)
-{
-    cfg.warn_about_broken_gtk_engines = !gtk_toggle_button_get_active(tbt);
-}
-
-void
-ui_main_check_theme_engine(void)
-{
-    GtkSettings *settings;
-    GtkWidget *widget;
-    gchar *theme = NULL;
-
-    widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_widget_ensure_style(widget);
-
-    settings = gtk_settings_get_default();
-    g_object_get(G_OBJECT(settings), "gtk-theme-name", &theme, NULL);
-    gtk_widget_destroy(widget);
-
-    if (theme == NULL)
-        return;
-
-    if (g_ascii_strcasecmp(theme, "Qt"))
-    {
-        g_free(theme);
-        return;
-    }
-
-    if (cfg.warn_about_broken_gtk_engines)
-    {
-        gchar *msg;
-        GtkWidget *label, *checkbt, *vbox;
-        GtkWidget *warning_dlg =
-            gtk_dialog_new_with_buttons( _("Audacious - broken GTK engine usage warning") ,
-                                         GTK_WINDOW(mainwin) , GTK_DIALOG_DESTROY_WITH_PARENT ,
-                                         GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL );
-        vbox = gtk_vbox_new( FALSE , 4 );
-        gtk_container_set_border_width( GTK_CONTAINER(vbox) , 4 );
-        gtk_box_pack_start( GTK_BOX(GTK_DIALOG(warning_dlg)->vbox) , vbox ,
-                            TRUE , TRUE , 0 );
-
-        msg = g_strdup_printf(_("<big><b>Broken GTK engine in use</b></big>\n\n"
-                                "Audacious has detected that you are using a broken GTK engine.\n\n"
-                                "The theme engine you are using, <i>%s</i>, is incompatible with some of the features "
-                                "used by modern skins. The incompatible features have been disabled for this session.\n\n"
-                                "To use these features, please consider using a different GTK theme engine."), theme);
-        label = gtk_label_new(msg);
-        gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
-        g_free(msg);
-
-        gtk_label_set_line_wrap( GTK_LABEL(label) , TRUE );
-        gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 );
-        checkbt = gtk_check_button_new_with_label( _("Do not display this warning again") );
-        gtk_box_pack_start( GTK_BOX(vbox) , label , TRUE , TRUE , 0 );
-        gtk_box_pack_start( GTK_BOX(vbox) , checkbt , TRUE , TRUE , 0 );
-        g_signal_connect( G_OBJECT(checkbt) , "toggled" ,
-                          G_CALLBACK(on_broken_gtk_engine_warning_toggle) , NULL );
-        g_signal_connect( G_OBJECT(warning_dlg) , "response" ,
-                          G_CALLBACK(gtk_widget_destroy) , NULL );        
-        gtk_widget_show_all(warning_dlg);
-        gtk_window_stick(GTK_WINDOW(warning_dlg));
-    }
-
-    cfg.disable_inline_gtk = TRUE;
-
-    g_free(theme);
-}
-
-void
-mainwin_show_add_url_window(void)
-{
-    static GtkWidget *url_window = NULL;
-
-    if (!url_window) {
-        url_window =
-            util_add_url_dialog_new(_("Enter location to play:"),
-                                    G_CALLBACK(on_add_url_ok_clicked),
-                                    G_CALLBACK(on_add_url_add_clicked));
-        gtk_window_set_transient_for(GTK_WINDOW(url_window),
-                                     GTK_WINDOW(mainwin));
-        g_signal_connect(url_window, "destroy",
-                         G_CALLBACK(gtk_widget_destroyed),
-                         &url_window);
-    }
-
-    gtk_window_present(GTK_WINDOW(url_window));
-}
-
-static void
-check_set( GtkActionGroup * action_group ,
-           const gchar * action_name ,
-           gboolean is_on )
-{
-    /* check_set noew uses gtkaction */
-    GtkAction *action = gtk_action_group_get_action( action_group , action_name );
-    if ( action != NULL )
-        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , is_on );
-    return;
-}
-
-void
-mainwin_eject_pushed(void)
-{
-    run_filebrowser(TRUE);
-}
-
-void
-mainwin_rev_pushed(void)
-{
-    g_get_current_time(&cb_time);
-
-    seek_initial_pos = ui_skinned_horizontal_slider_get_position(mainwin_position);
-    seek_state = MAINWIN_SEEK_REV;
-    mainwin_timeout_id = g_timeout_add(MAINWIN_UPDATE_INTERVAL,
-                                       (GSourceFunc) mainwin_idle_func, NULL);
-}
-
-void
-mainwin_rev_release(void)
-{
-    GTimeVal now_time;
-    GTimeVal delta_time;
-    gulong now_dur;
-
-    g_get_current_time(&now_time);
-
-    delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec;
-    delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec;
-
-    now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000));
-
-    if ( now_dur <= TRISTATE_THRESHOLD )
-    {
-        /* interpret as 'skip to previous song' */
-        playlist_prev(playlist_get_active());
-    }
-    else
-    {
-        /* interpret as 'seek' */
-        mainwin_position_release_cb( mainwin_position, ui_skinned_horizontal_slider_get_position(mainwin_position) );
-    }
-
-    seek_state = MAINWIN_SEEK_NIL;
-
-    g_source_remove(mainwin_timeout_id);
-    mainwin_timeout_id = 0;
-}
-
-void
-mainwin_fwd_pushed(void)
-{
-    g_get_current_time(&cb_time);
-
-    seek_initial_pos = ui_skinned_horizontal_slider_get_position(mainwin_position);
-    seek_state = MAINWIN_SEEK_FWD;
-    mainwin_timeout_id = g_timeout_add(MAINWIN_UPDATE_INTERVAL,
-                                       (GSourceFunc) mainwin_idle_func, NULL);
-}
-
-void
-mainwin_fwd_release(void)
-{
-    GTimeVal now_time;
-    GTimeVal delta_time;
-    gulong now_dur;
-
-    g_get_current_time(&now_time);
-
-    delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec;
-    delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec;
-
-    now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000));
-
-    if ( now_dur <= TRISTATE_THRESHOLD )
-    {
-        /* interpret as 'skip to next song' */
-        playlist_next(playlist_get_active());
-    }
-    else
-    {
-        /* interpret as 'seek' */
-        mainwin_position_release_cb( mainwin_position, ui_skinned_horizontal_slider_get_position(mainwin_position) );
-    }
-
-    seek_state = MAINWIN_SEEK_NIL;
-
-    g_source_remove(mainwin_timeout_id);
-    mainwin_timeout_id = 0;
-}
-
-void
-mainwin_play_pushed(void)
-{
-    if (ab_position_a != -1)
-        playback_seek(ab_position_a / 1000);
-    if (playback_get_paused()) {
-        playback_pause();
-        return;
-    }
-
-    if (playlist_get_length(playlist_get_active()))
-        playback_initiate();
-    else
-        mainwin_eject_pushed();
-}
-
-void
-mainwin_stop_pushed(void)
-{
-    ip_data.stop = TRUE;
-    playback_stop();
-    mainwin_clear_song_info();
-    ab_position_a = ab_position_b = -1;
-    ip_data.stop = FALSE;
-}
-
-void
-mainwin_shuffle_pushed(gboolean toggled)
-{
-    check_set( toggleaction_group_others , "playback shuffle" , toggled );
-}
-
-void mainwin_shuffle_pushed_cb(void) {
-    mainwin_shuffle_pushed(UI_SKINNED_BUTTON(mainwin_shuffle)->inside);
-}
-
-void
-mainwin_repeat_pushed(gboolean toggled)
-{
-    check_set( toggleaction_group_others , "playback repeat" , toggled );
-}
-
-void mainwin_repeat_pushed_cb(void) {
-    mainwin_repeat_pushed(UI_SKINNED_BUTTON(mainwin_repeat)->inside);
-}
-
-void mainwin_equalizer_pushed_cb(void) {
-    mainwin_eq_pushed(UI_SKINNED_BUTTON(mainwin_eq)->inside);
-}
-
-void mainwin_playlist_pushed_cb(void) {
-    mainwin_pl_pushed(UI_SKINNED_BUTTON(mainwin_pl)->inside);
-}
-
-void
-mainwin_eq_pushed(gboolean toggled)
-{
-    equalizerwin_show(toggled);
-}
-
-void
-mainwin_pl_pushed(gboolean toggled)
-{
-    if (toggled)
-        playlistwin_show();
-    else
-        playlistwin_hide();
-}
-
-gint
-mainwin_spos_frame_cb(gint pos)
-{
-    if (mainwin_sposition) {
-        gint x = 0;
-        if (pos < 6)
-            x = 17;
-        else if (pos < 9)
-            x = 20;
-        else
-            x = 23;
-
-        UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->knob_nx = x;
-        UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->knob_px = x;
-    }
-    return 1;
-}
-
-void
-mainwin_spos_motion_cb(GtkWidget *widget, gint pos)
-{
-    gint time;
-    gchar *time_msg;
-    Playlist *playlist = playlist_get_active();
-
-    pos--;
-
-    time = ((playlist_get_current_length(playlist) / 1000) * pos) / 12;
-
-    if (cfg.timer_mode == TIMER_REMAINING) {
-        time = (playlist_get_current_length(playlist) / 1000) - time;
-        time_msg = g_strdup_printf("-%2.2d", time / 60);
-        ui_skinned_textbox_set_text(mainwin_stime_min, time_msg);
-        g_free(time_msg);
-    }
-    else {
-        time_msg = g_strdup_printf(" %2.2d", time / 60);
-        ui_skinned_textbox_set_text(mainwin_stime_min, time_msg);
-        g_free(time_msg);
-    }
-
-    time_msg = g_strdup_printf("%2.2d", time % 60);
-    ui_skinned_textbox_set_text(mainwin_stime_sec, time_msg);
-    g_free(time_msg);
-}
-
-void
-mainwin_spos_release_cb(GtkWidget *widget, gint pos)
-{
-    playback_seek(((playlist_get_current_length(playlist_get_active()) / 1000) *
-                   (pos - 1)) / 12);
-}
-
-void
-mainwin_position_motion_cb(GtkWidget *widget, gint pos)
-{
-    gint length, time;
-    gchar *seek_msg;
-
-    length = playlist_get_current_length(playlist_get_active()) / 1000;
-    time = (length * pos) / 219;
-    seek_msg = g_strdup_printf(_("Seek to: %d:%-2.2d/%d:%-2.2d (%d%%)"),
-                               time / 60, time % 60,
-                               length / 60, length % 60,
-                               (length != 0) ? (time * 100) / length : 0);
-    mainwin_lock_info_text(seek_msg);
-    g_free(seek_msg);
-}
-
-void
-mainwin_position_release_cb(GtkWidget *widget, gint pos)
-{
-    gint length, time;
-
-    length = playlist_get_current_length(playlist_get_active()) / 1000;
-    time = (length * pos) / 219;
-    playback_seek(time);
-    mainwin_release_info_text();
-}
-
-gint
-mainwin_volume_frame_cb(gint pos)
-{
-    return (gint) rint((pos / 52.0) * 28);
-}
-
-void
-mainwin_adjust_volume_motion(gint v)
-{
-    gchar *volume_msg;
-
-    volume_msg = g_strdup_printf(_("Volume: %d%%"), v);
-    mainwin_lock_info_text(volume_msg);
-    g_free(volume_msg);
-
-    if (balance < 0)
-        input_set_volume(v, (v * (100 - abs(balance))) / 100);
-    else if (balance > 0)
-        input_set_volume((v * (100 - abs(balance))) / 100, v);
-    else
-        input_set_volume(v, v);
-}
-
-void
-mainwin_adjust_volume_release(void)
-{
-    mainwin_release_info_text();
-}
-
-void
-mainwin_adjust_balance_motion(gint b)
-{
-    gchar *balance_msg;
-    gint v, pvl, pvr;
-
-    balance = b;
-    input_get_volume(&pvl, &pvr);
-    v = MAX(pvl, pvr);
-    if (b < 0) {
-        balance_msg = g_strdup_printf(_("Balance: %d%% left"), -b);
-        input_set_volume(v, (gint) rint(((100 + b) / 100.0) * v));
-    }
-    else if (b == 0) {
-        balance_msg = g_strdup_printf(_("Balance: center"));
-        input_set_volume(v, v);
-    }
-    else {                      /* b > 0 */
-        balance_msg = g_strdup_printf(_("Balance: %d%% right"), b);
-        input_set_volume((gint) rint(((100 - b) / 100.0) * v), v);
-    }
-    mainwin_lock_info_text(balance_msg);
-    g_free(balance_msg);
-}
-
-void
-mainwin_adjust_balance_release(void)
-{
-    mainwin_release_info_text();
-}
-
-void
-mainwin_set_volume_slider(gint percent)
-{
-    ui_skinned_horizontal_slider_set_position(mainwin_volume, (gint) rint((percent * 51) / 100.0));
-}
-
-void
-mainwin_set_balance_slider(gint percent)
-{
-    ui_skinned_horizontal_slider_set_position(mainwin_balance, (gint) rint(((percent * 12) / 100.0) + 12));
-}
-
-void
-mainwin_volume_motion_cb(GtkWidget *widget, gint pos)
-{
-    gint vol = (pos * 100) / 51;
-    mainwin_adjust_volume_motion(vol);
-    equalizerwin_set_volume_slider(vol);
-}
-
-gboolean
-mainwin_volume_release_cb(GtkWidget *widget, gint pos)
-{
-    mainwin_adjust_volume_release();
-    return FALSE;
-}
-
-gint
-mainwin_balance_frame_cb(gint pos)
-{
-    return ((abs(pos - 12) * 28) / 13);
-}
-
-void
-mainwin_balance_motion_cb(GtkWidget *widget, gint pos)
-{
-    gint bal = ((pos - 12) * 100) / 12;
-    mainwin_adjust_balance_motion(bal);
-    equalizerwin_set_balance_slider(bal);
-}
-
-void
-mainwin_balance_release_cb(GtkWidget *widget, gint pos)
-{
-    mainwin_adjust_volume_release();
-}
-
-void
-mainwin_set_volume_diff(gint diff)
-{
-    gint vl, vr, vol;
-
-    input_get_volume(&vl, &vr);
-    vol = MAX(vl, vr);
-    vol = CLAMP(vol + diff, 0, 100);
-
-    mainwin_adjust_volume_motion(vol);
-    mainwin_set_volume_slider(vol);
-    equalizerwin_set_volume_slider(vol);
-
-    if (mainwin_volume_release_timeout)
-        g_source_remove(mainwin_volume_release_timeout);
-    mainwin_volume_release_timeout =
-        g_timeout_add(700, (GSourceFunc)(mainwin_volume_release_cb), NULL);
-}
-
-void
-mainwin_set_balance_diff(gint diff)
-{
-    gint b;
-    b = CLAMP(balance + diff, -100, 100);
-    mainwin_adjust_balance_motion(b);
-    mainwin_set_balance_slider(b);
-    equalizerwin_set_balance_slider(b);
-}
-
-void
-mainwin_show(gboolean show)
-{
-    if (show)
-        mainwin_real_show();
-    else
-        mainwin_real_hide();
-}
-
-void
-mainwin_real_show(void)
-{
-    cfg.player_visible = TRUE;
-
-    check_set( toggleaction_group_others , "show player" , TRUE );
-
-    if (cfg.player_shaded)
-        ui_vis_clear_data(mainwin_vis);
-
-    if (cfg.show_wm_decorations) {
-        if (cfg.player_x != -1 && cfg.save_window_position)
-            gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y);
-
-        gtk_widget_show(mainwin);
-        return;
-    }
-
-    if (cfg.player_x != -1 && cfg.save_window_position)
-        gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y);
-
-    mainwin_refresh_hints();
-    gtk_window_present(GTK_WINDOW(mainwin));
-}
-
-void
-mainwin_real_hide(void)
-{
-    check_set( toggleaction_group_others , "show player", FALSE);
-
-    if (cfg.player_shaded)
-        ui_svis_clear_data(mainwin_svis);
-
-    gtk_widget_hide(mainwin);
-
-    cfg.player_visible = FALSE;
-}
-
-
-void
-mainwin_set_stopaftersong(gboolean stop)
-{
-    cfg.stopaftersong = stop;
-    check_set(toggleaction_group_others, "stop after current song", cfg.stopaftersong);
-}
-
-void
-mainwin_set_noplaylistadvance(gboolean no_advance)
-{
-    cfg.no_playlist_advance = no_advance;
-    check_set(toggleaction_group_others, "playback no playlist advance", cfg.no_playlist_advance);
-}
-
-static void
-mainwin_set_scaled(gboolean scaled)
-{
-    gint height;
-
-    if (cfg.player_shaded)
-        height = MAINWIN_SHADED_HEIGHT;
-    else
-        height = aud_active_skin->properties.mainwin_height;
-
-    dock_window_resize(GTK_WINDOW(mainwin), cfg.player_shaded ? MAINWIN_SHADED_WIDTH : aud_active_skin->properties.mainwin_width,
-                       cfg.player_shaded ? MAINWIN_SHADED_HEIGHT : aud_active_skin->properties.mainwin_height,
-                       aud_active_skin->properties.mainwin_width * cfg.scale_factor , aud_active_skin->properties.mainwin_height * cfg.scale_factor);
-
-    GList *iter;
-    for (iter = GTK_FIXED (SKINNED_WINDOW(mainwin)->fixed)->children; iter; iter = g_list_next (iter)) {
-        GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
-        GtkWidget *child = child_data->widget;
-        g_signal_emit_by_name(child, "toggle-scaled");
-    }
-
-    mainwin_refresh_hints();
-    gtk_widget_shape_combine_mask(mainwin, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
-}
-
-void
-set_scaled(gboolean scaled)
-{
-    cfg.scaled = scaled;
-
-    mainwin_set_scaled(scaled);
-
-    if (cfg.eq_scaled_linked)
-        equalizerwin_set_scaled(scaled);
-}
-
-
-
-void
-mainwin_general_menu_callback(gpointer data,
-                              guint action,
-                              GtkWidget * item)
-{
-    Playlist *playlist = playlist_get_active();
-
-    switch (action) {
-        case MAINWIN_GENERAL_PREFS:
-            show_prefs_window();
-            break;
-        case MAINWIN_GENERAL_ABOUT:
-            show_about_window();
-            break;
-        case MAINWIN_GENERAL_PLAYFILE:
-            run_filebrowser(FALSE);
-            break;
-        case MAINWIN_GENERAL_PLAYLOCATION:
-            mainwin_show_add_url_window();
-            break;
-        case MAINWIN_GENERAL_FILEINFO:
-            ui_fileinfo_show_current(playlist);
-            break;
-        case MAINWIN_GENERAL_FOCUSPLWIN:
-            gtk_window_present(GTK_WINDOW(playlistwin));
-            break;
-        case MAINWIN_GENERAL_SHOWMWIN:
-            mainwin_show(GTK_CHECK_MENU_ITEM(item)->active);
-            break;
-        case MAINWIN_GENERAL_SHOWPLWIN:
-            if (GTK_CHECK_MENU_ITEM(item)->active)
-                playlistwin_show();
-            else
-                playlistwin_hide();
-            break;
-        case MAINWIN_GENERAL_SHOWEQWIN:
-            if (GTK_CHECK_MENU_ITEM(item)->active)
-                equalizerwin_real_show();
-            else
-                equalizerwin_real_hide();
-            break;
-        case MAINWIN_GENERAL_PREV:
-            playlist_prev(playlist);
-            break;
-        case MAINWIN_GENERAL_PLAY:
-            mainwin_play_pushed();
-            break;
-        case MAINWIN_GENERAL_PAUSE:
-            playback_pause();
-            break;
-        case MAINWIN_GENERAL_STOP:
-            mainwin_stop_pushed();
-            break;
-        case MAINWIN_GENERAL_NEXT:
-            playlist_next(playlist);
-            break;
-        case MAINWIN_GENERAL_BACK5SEC:
-            if (playback_get_playing()
-                && playlist_get_current_length(playlist) != -1)
-                playback_seek_relative(-5);
-            break;
-        case MAINWIN_GENERAL_FWD5SEC:
-            if (playback_get_playing()
-                && playlist_get_current_length(playlist) != -1)
-                playback_seek_relative(5);
-            break;
-        case MAINWIN_GENERAL_START:
-            playlist_set_position(playlist, 0);
-            break;
-        case MAINWIN_GENERAL_JTT:
-            mainwin_jump_to_time();
-            break;
-        case MAINWIN_GENERAL_JTF:
-            ui_jump_to_track();
-            break;
-        case MAINWIN_GENERAL_EXIT:
-            mainwin_quit_cb();
-            break;
-        case MAINWIN_GENERAL_SETAB:
-            if (playlist_get_current_length(playlist) != -1) {
-                if (ab_position_a == -1) {
-                    ab_position_a = playback_get_time();
-                    ab_position_b = -1;
-                    mainwin_lock_info_text("'Loop-Point A Position' set.");
-                } else if (ab_position_b == -1) {
-                    int time = playback_get_time();
-                    if (time > ab_position_a)
-                        ab_position_b = time;
-                    mainwin_release_info_text();
-                } else {
-                    ab_position_a = playback_get_time();
-                    ab_position_b = -1;
-                    mainwin_lock_info_text("'Loop-Point A Position' reset.");
-                }
-            }
-            break;
-        case MAINWIN_GENERAL_CLEARAB:
-            if (playlist_get_current_length(playlist) != -1) {
-                ab_position_a = ab_position_b = -1;
-                mainwin_release_info_text();
-            }
-            break;
-        case MAINWIN_GENERAL_NEW_PL:
-            {
-                Playlist *new_pl = playlist_new();
-                playlist_add_playlist(new_pl);
-                playlist_select_playlist(new_pl);
-            }
-            break;
-        case MAINWIN_GENERAL_PREV_PL:
-            playlist_select_prev();
-            break;
-        case MAINWIN_GENERAL_NEXT_PL:
-            playlist_select_next();
-            break;
-    }
-}
-
-static void
-mainwin_mr_change(GtkWidget *widget, MenuRowItem i)
-{
-    switch (i) {
-        case MENUROW_OPTIONS:
-            mainwin_lock_info_text(_("Options Menu"));
-            break;
-        case MENUROW_ALWAYS:
-            if (UI_SKINNED_MENUROW(mainwin_menurow)->always_selected)
-                mainwin_lock_info_text(_("Disable 'Always On Top'"));
-            else
-                mainwin_lock_info_text(_("Enable 'Always On Top'"));
-            break;
-        case MENUROW_FILEINFOBOX:
-            mainwin_lock_info_text(_("File Info Box"));
-            break;
-        case MENUROW_SCALE:
-            if (UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected)
-                mainwin_lock_info_text(_("Disable 'GUI Scaling'"));
-            else
-                mainwin_lock_info_text(_("Enable 'GUI Scaling'"));
-            break;
-        case MENUROW_VISUALIZATION:
-            mainwin_lock_info_text(_("Visualization Menu"));
-            break;
-        case MENUROW_NONE:
-            break;
-    }
-}
-
-static void
-mainwin_mr_release(GtkWidget *widget, MenuRowItem i, GdkEventButton *event)
-{
-    switch (i) {
-        case MENUROW_OPTIONS:
-            ui_manager_popup_menu_show(GTK_MENU(mainwin_view_menu),
-                                       event->x_root, event->y_root, 1,
-                                       event->time);
-            break;
-        case MENUROW_ALWAYS:
-            gtk_toggle_action_set_active(
-                                         GTK_TOGGLE_ACTION(gtk_action_group_get_action(
-                                                                                       toggleaction_group_others , "view always on top" )) ,
-                                         UI_SKINNED_MENUROW(mainwin_menurow)->always_selected );
-            break;
-        case MENUROW_FILEINFOBOX:
-            ui_fileinfo_show_current(playlist_get_active());
-            break;
-        case MENUROW_SCALE:
-            gtk_toggle_action_set_active(
-                                         GTK_TOGGLE_ACTION(gtk_action_group_get_action(
-                                                                                       toggleaction_group_others , "view scaled" )) ,
-                                         UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected );
-            break;
-        case MENUROW_VISUALIZATION:
-            ui_manager_popup_menu_show(GTK_MENU(mainwin_visualization_menu),
-                                       event->x_root, event->y_root, 1,
-                                       event->time);
-            break;
-        case MENUROW_NONE:
-            break;
-    }
-    mainwin_release_info_text();
-}
-
-void
-run_no_output_device_dialog(gpointer hook_data, gpointer user_data)
-{
-    const gchar *markup =
-        N_("<b><big>Couldn't open audio.</big></b>\n\n"
-           "Please check that:\n"
-           "1. You have the correct output plugin selected.\n"
-           "2. No other programs is blocking the soundcard.\n"
-           "3. Your soundcard is configured properly.\n");
-
-    GDK_THREADS_ENTER();
-    GtkWidget *dialog =
-        gtk_message_dialog_new_with_markup(GTK_WINDOW(mainwin),
-                                           GTK_DIALOG_DESTROY_WITH_PARENT,
-                                           GTK_MESSAGE_ERROR,
-                                           GTK_BUTTONS_OK,
-                                           _(markup));
-    gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_widget_destroy(dialog);
-    GDK_THREADS_LEAVE();
-}
-
-static void
-set_timer_mode(TimerMode mode)
-{
-    if (mode == TIMER_ELAPSED)
-        check_set(radioaction_group_viewtime, "view time elapsed", TRUE);
-    else
-        check_set(radioaction_group_viewtime, "view time remaining", TRUE);
-}
-
-static void
-set_timer_mode_menu_cb(TimerMode mode)
-{
-    cfg.timer_mode = mode;
-}
-
-gboolean
-change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event)
-{
-    if (event->button == 1) {
-        change_timer_mode();
-    } else if (event->button == 3)
-        return FALSE;
-
-    return TRUE;
-}
-
-static void change_timer_mode(void) {
-    if (cfg.timer_mode == TIMER_ELAPSED)
-        set_timer_mode(TIMER_REMAINING);
-    else
-        set_timer_mode(TIMER_ELAPSED);
-    if (playback_get_playing())
-        mainwin_update_song_info();
-}
-
-static void
-mainwin_playlist_prev(void)
-{
-    playlist_prev(playlist_get_active());
-}
-
-static void
-mainwin_playlist_next(void)
-{
-    playlist_next(playlist_get_active());
-}
-
-void
-mainwin_setup_menus(void)
-{
-    set_timer_mode(cfg.timer_mode);
-
-    /* View menu */
-
-    check_set(toggleaction_group_others, "view always on top", cfg.always_on_top);
-    check_set(toggleaction_group_others, "view put on all workspaces", cfg.sticky);
-    check_set(toggleaction_group_others, "roll up player", cfg.player_shaded);
-    check_set(toggleaction_group_others, "roll up playlist editor", cfg.playlist_shaded);
-    check_set(toggleaction_group_others, "roll up equalizer", cfg.equalizer_shaded);
-    check_set(toggleaction_group_others, "view easy move", cfg.easy_move);
-    check_set(toggleaction_group_others, "view scaled", cfg.scaled);
-
-    /* Songname menu */
-
-    check_set(toggleaction_group_others, "autoscroll songname", cfg.autoscroll);
-    check_set(toggleaction_group_others, "stop after current song", cfg.stopaftersong);
-
-    /* Playback menu */
-
-    check_set(toggleaction_group_others, "playback repeat", cfg.repeat);
-    check_set(toggleaction_group_others, "playback shuffle", cfg.shuffle);
-    check_set(toggleaction_group_others, "playback no playlist advance", cfg.no_playlist_advance);
-
-    /* Visualization menu */
-
-    switch ( cfg.vis_type )
-    {
-        case VIS_ANALYZER:
-            check_set(radioaction_group_vismode, "vismode analyzer", TRUE);
-            break;
-        case VIS_SCOPE:
-            check_set(radioaction_group_vismode, "vismode scope", TRUE);
-            break;
-        case VIS_VOICEPRINT:
-            check_set(radioaction_group_vismode, "vismode voiceprint", TRUE);
-            break;
-        case VIS_OFF:
-        default:
-            check_set(radioaction_group_vismode, "vismode off", TRUE);
-            break;
-    }
-
-    switch ( cfg.analyzer_mode )
-    {
-        case ANALYZER_FIRE:
-            check_set(radioaction_group_anamode, "anamode fire", TRUE);
-            break;
-        case ANALYZER_VLINES:
-            check_set(radioaction_group_anamode, "anamode vertical lines", TRUE);
-            break;
-        case ANALYZER_NORMAL:
-        default:
-            check_set(radioaction_group_anamode, "anamode normal", TRUE);
-            break;
-    }
-
-    switch ( cfg.analyzer_type )
-    {
-        case ANALYZER_BARS:
-            check_set(radioaction_group_anatype, "anatype bars", TRUE);
-            break;
-        case ANALYZER_LINES:
-        default:
-            check_set(radioaction_group_anatype, "anatype lines", TRUE);
-            break;
-    }
-
-    check_set(toggleaction_group_others, "anamode peaks", cfg.analyzer_peaks );
-
-    switch ( cfg.scope_mode )
-    {
-        case SCOPE_LINE:
-            check_set(radioaction_group_scomode, "scomode line", TRUE);
-            break;
-        case SCOPE_SOLID:
-            check_set(radioaction_group_scomode, "scomode solid", TRUE);
-            break;
-        case SCOPE_DOT:
-        default:
-            check_set(radioaction_group_scomode, "scomode dot", TRUE);
-            break;
-    }
-
-    switch ( cfg.voiceprint_mode )
-    {
-        case VOICEPRINT_FIRE:
-            check_set(radioaction_group_vprmode, "vprmode fire", TRUE);
-            break;
-        case VOICEPRINT_ICE:
-            check_set(radioaction_group_vprmode, "vprmode ice", TRUE);
-            break;
-        case VOICEPRINT_NORMAL:
-        default:
-            check_set(radioaction_group_vprmode, "vprmode normal", TRUE);
-            break;
-    }
-
-    switch ( cfg.vu_mode )
-    {
-        case VU_SMOOTH:
-            check_set(radioaction_group_wshmode, "wshmode smooth", TRUE);
-            break;
-        case VU_NORMAL:
-        default:
-            check_set(radioaction_group_wshmode, "wshmode normal", TRUE);
-            break;
-    }
-
-    switch ( cfg.vis_refresh )
-    {
-        case REFRESH_HALF:
-            check_set(radioaction_group_refrate, "refrate half", TRUE);
-            break;
-        case REFRESH_QUARTER:
-            check_set(radioaction_group_refrate, "refrate quarter", TRUE);
-            break;
-        case REFRESH_EIGTH:
-            check_set(radioaction_group_refrate, "refrate eighth", TRUE);
-            break;
-        case REFRESH_FULL:
-        default:
-            check_set(radioaction_group_refrate, "refrate full", TRUE);
-            break;
-    }
-
-    switch ( cfg.analyzer_falloff )
-    {
-        case FALLOFF_SLOW:
-            check_set(radioaction_group_anafoff, "anafoff slow", TRUE);
-            break;
-        case FALLOFF_MEDIUM:
-            check_set(radioaction_group_anafoff, "anafoff medium", TRUE);
-            break;
-        case FALLOFF_FAST:
-            check_set(radioaction_group_anafoff, "anafoff fast", TRUE);
-            break;
-        case FALLOFF_FASTEST:
-            check_set(radioaction_group_anafoff, "anafoff fastest", TRUE);
-            break;
-        case FALLOFF_SLOWEST:
-        default:
-            check_set(radioaction_group_anafoff, "anafoff slowest", TRUE);
-            break;
-    }
-
-    switch ( cfg.peaks_falloff )
-    {
-        case FALLOFF_SLOW:
-            check_set(radioaction_group_peafoff, "peafoff slow", TRUE);
-            break;
-        case FALLOFF_MEDIUM:
-            check_set(radioaction_group_peafoff, "peafoff medium", TRUE);
-            break;
-        case FALLOFF_FAST:
-            check_set(radioaction_group_peafoff, "peafoff fast", TRUE);
-            break;
-        case FALLOFF_FASTEST:
-            check_set(radioaction_group_peafoff, "peafoff fastest", TRUE);
-            break;
-        case FALLOFF_SLOWEST:
-        default:
-            check_set(radioaction_group_peafoff, "peafoff slowest", TRUE);
-            break;
-    }
-
-}
-
-static void mainwin_info_double_clicked_cb(void) {
-    ui_fileinfo_show_current(playlist_get_active());
-}
-
-static void
-mainwin_info_right_clicked_cb(GtkWidget *widget, GdkEventButton *event)
-{
-    ui_manager_popup_menu_show(GTK_MENU(mainwin_songname_menu),
-                               event->x_root, event->y_root, 3, event->time);
-}
-
-static void
-mainwin_create_widgets(void)
-{
-    mainwin_menubtn = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_menubtn, SKINNED_WINDOW(mainwin)->fixed,
-                                 6, 3, 9, 9, 0, 0, 0, 9, SKIN_TITLEBAR);
-    g_signal_connect(mainwin_menubtn, "clicked", mainwin_menubtn_cb, NULL );
-
-    mainwin_minimize = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_minimize, SKINNED_WINDOW(mainwin)->fixed,
-                                 244, 3, 9, 9, 9, 0, 9, 9, SKIN_TITLEBAR);
-    g_signal_connect(mainwin_minimize, "clicked", mainwin_minimize_cb, NULL );
-
-    mainwin_shade = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_shade, SKINNED_WINDOW(mainwin)->fixed,
-                                 254, 3, 9, 9, 0,
-                                 cfg.player_shaded ? 27 : 18, 9, cfg.player_shaded ? 27 : 18, SKIN_TITLEBAR);
-    g_signal_connect(mainwin_shade, "clicked", mainwin_shade_toggle, NULL );
-
-    mainwin_close = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_close, SKINNED_WINDOW(mainwin)->fixed,
-                                 264, 3, 9, 9, 18, 0, 18, 9, SKIN_TITLEBAR);
-    g_signal_connect(mainwin_close, "clicked", mainwin_quit_cb, NULL );
-
-    mainwin_rew = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_rew, SKINNED_WINDOW(mainwin)->fixed,
-                                 16, 88, 23, 18, 0, 0, 0, 18, SKIN_CBUTTONS);
-    g_signal_connect(mainwin_rew, "pressed", mainwin_rev_pushed, NULL);
-    g_signal_connect(mainwin_rew, "released", mainwin_rev_release, NULL);
-
-    mainwin_fwd = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_fwd, SKINNED_WINDOW(mainwin)->fixed,
-                                 108, 88, 22, 18, 92, 0, 92, 18, SKIN_CBUTTONS);
-    g_signal_connect(mainwin_fwd, "pressed", mainwin_fwd_pushed, NULL);
-    g_signal_connect(mainwin_fwd, "released", mainwin_fwd_release, NULL);
-
-    mainwin_play = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_play, SKINNED_WINDOW(mainwin)->fixed,
-                                 39, 88, 23, 18, 23, 0, 23, 18, SKIN_CBUTTONS);
-    g_signal_connect(mainwin_play, "clicked", mainwin_play_pushed, NULL );
-
-    mainwin_pause = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_pause, SKINNED_WINDOW(mainwin)->fixed,
-                                 62, 88, 23, 18, 46, 0, 46, 18, SKIN_CBUTTONS);
-    g_signal_connect(mainwin_pause, "clicked", playback_pause, NULL );
-
-    mainwin_stop = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_stop, SKINNED_WINDOW(mainwin)->fixed,
-                                 85, 88, 23, 18, 69, 0, 69, 18, SKIN_CBUTTONS);
-    g_signal_connect(mainwin_stop, "clicked", mainwin_stop_pushed, NULL );
-
-    mainwin_eject = ui_skinned_button_new();
-    ui_skinned_push_button_setup(mainwin_eject, SKINNED_WINDOW(mainwin)->fixed,
-                                 136, 89, 22, 16, 114, 0, 114, 16, SKIN_CBUTTONS);
-    g_signal_connect(mainwin_eject, "clicked", mainwin_eject_pushed, NULL);
-
-    mainwin_srew = ui_skinned_button_new();
-    ui_skinned_small_button_setup(mainwin_srew, SKINNED_WINDOW(mainwin)->fixed, 169, 4, 8, 7);
-    g_signal_connect(mainwin_srew, "clicked", mainwin_playlist_prev, NULL);
-
-    mainwin_splay = ui_skinned_button_new();
-    ui_skinned_small_button_setup(mainwin_splay, SKINNED_WINDOW(mainwin)->fixed, 177, 4, 10, 7);
-    g_signal_connect(mainwin_splay, "clicked", mainwin_play_pushed, NULL);
-
-    mainwin_spause = ui_skinned_button_new();
-    ui_skinned_small_button_setup(mainwin_spause, SKINNED_WINDOW(mainwin)->fixed, 187, 4, 10, 7);
-    g_signal_connect(mainwin_spause, "clicked", playback_pause, NULL);
-
-    mainwin_sstop = ui_skinned_button_new();
-    ui_skinned_small_button_setup(mainwin_sstop, SKINNED_WINDOW(mainwin)->fixed, 197, 4, 9, 7);
-    g_signal_connect(mainwin_sstop, "clicked", mainwin_stop_pushed, NULL);
-
-    mainwin_sfwd = ui_skinned_button_new();
-    ui_skinned_small_button_setup(mainwin_sfwd, SKINNED_WINDOW(mainwin)->fixed, 206, 4, 8, 7);
-    g_signal_connect(mainwin_sfwd, "clicked", mainwin_playlist_next, NULL);
-
-    mainwin_seject = ui_skinned_button_new();
-    ui_skinned_small_button_setup(mainwin_seject, SKINNED_WINDOW(mainwin)->fixed, 216, 4, 9, 7);
-    g_signal_connect(mainwin_seject, "clicked", mainwin_eject_pushed, NULL);
-
-    mainwin_shuffle = ui_skinned_button_new();
-    ui_skinned_toggle_button_setup(mainwin_shuffle, SKINNED_WINDOW(mainwin)->fixed,
-                                   164, 89, 46, 15, 28, 0, 28, 15, 28, 30, 28, 45, SKIN_SHUFREP);
-    g_signal_connect(mainwin_shuffle, "clicked", mainwin_shuffle_pushed_cb, NULL);
-
-    mainwin_repeat = ui_skinned_button_new();
-    ui_skinned_toggle_button_setup(mainwin_repeat, SKINNED_WINDOW(mainwin)->fixed,
-                                   210, 89, 28, 15, 0, 0, 0, 15, 0, 30, 0, 45, SKIN_SHUFREP);
-    g_signal_connect(mainwin_repeat, "clicked", mainwin_repeat_pushed_cb, NULL);
-
-    mainwin_eq = ui_skinned_button_new();
-    ui_skinned_toggle_button_setup(mainwin_eq, SKINNED_WINDOW(mainwin)->fixed,
-                                   219, 58, 23, 12, 0, 61, 46, 61, 0, 73, 46, 73, SKIN_SHUFREP);
-    g_signal_connect(mainwin_eq, "clicked", mainwin_equalizer_pushed_cb, NULL);
-    UI_SKINNED_BUTTON(mainwin_eq)->inside = cfg.equalizer_visible;
-
-    mainwin_pl = ui_skinned_button_new();
-    ui_skinned_toggle_button_setup(mainwin_pl, SKINNED_WINDOW(mainwin)->fixed,
-                                   242, 58, 23, 12, 23, 61, 69, 61, 23, 73, 69, 73, SKIN_SHUFREP);
-    g_signal_connect(mainwin_pl, "clicked", mainwin_playlist_pushed_cb, NULL);
-    UI_SKINNED_BUTTON(mainwin_pl)->inside = cfg.playlist_visible;
-
-    mainwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 112, 27, 153, 1, SKIN_TEXT);
-    ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll);
-    ui_skinned_textbox_set_xfont(mainwin_info, !cfg.mainwin_use_bitmapfont, cfg.mainwin_font);
-    g_signal_connect(mainwin_info, "double-clicked", mainwin_info_double_clicked_cb, NULL);
-    g_signal_connect(mainwin_info, "right-clicked", G_CALLBACK(mainwin_info_right_clicked_cb), NULL);
-
-    mainwin_othertext = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 112, 43, 153, 1, SKIN_TEXT);
-
-    mainwin_rate_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 111, 43, 15, 0, SKIN_TEXT);
-
-    mainwin_freq_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 156, 43, 10, 0, SKIN_TEXT);
-
-    mainwin_menurow = ui_skinned_menurow_new(SKINNED_WINDOW(mainwin)->fixed, 10, 22, 304, 0, 304, 44,  SKIN_TITLEBAR);
-    g_signal_connect(mainwin_menurow, "change", G_CALLBACK(mainwin_mr_change), NULL);
-    g_signal_connect(mainwin_menurow, "release", G_CALLBACK(mainwin_mr_release), NULL);
-
-    mainwin_volume = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 107, 57, 68,
-                                                      13, 15, 422, 0, 422, 14, 11, 15, 0, 0, 51,
-                                                      mainwin_volume_frame_cb, SKIN_VOLUME);
-    g_signal_connect(mainwin_volume, "motion", G_CALLBACK(mainwin_volume_motion_cb), NULL);
-    g_signal_connect(mainwin_volume, "release", G_CALLBACK(mainwin_volume_release_cb), NULL);
-
-    mainwin_balance = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 177, 57, 38,
-                                                       13, 15, 422, 0, 422, 14, 11, 15, 9, 0, 24,
-                                                       mainwin_balance_frame_cb, SKIN_BALANCE);
-    g_signal_connect(mainwin_balance, "motion", G_CALLBACK(mainwin_balance_motion_cb), NULL);
-    g_signal_connect(mainwin_balance, "release", G_CALLBACK(mainwin_balance_release_cb), NULL);
-
-    mainwin_monostereo = ui_skinned_monostereo_new(SKINNED_WINDOW(mainwin)->fixed, 212, 41, SKIN_MONOSTEREO);
-
-    mainwin_playstatus = ui_skinned_playstatus_new(SKINNED_WINDOW(mainwin)->fixed, 24, 28);
-
-    mainwin_minus_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 36, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_minus_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    mainwin_10min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 48, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_10min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    mainwin_min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 60, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    mainwin_10sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 78, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_10sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    mainwin_sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 90, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    mainwin_about = ui_skinned_button_new();
-    ui_skinned_small_button_setup(mainwin_about, SKINNED_WINDOW(mainwin)->fixed, 247, 83, 20, 25);
-    g_signal_connect(mainwin_about, "clicked", show_about_window, NULL);
-
-    mainwin_vis = ui_vis_new(SKINNED_WINDOW(mainwin)->fixed, 24, 43, 76);
-    g_signal_connect(mainwin_vis, "button-press-event", G_CALLBACK(mainwin_vis_cb), NULL);
-    mainwin_svis = ui_svis_new(SKINNED_WINDOW(mainwin)->fixed, 79, 5);
-    g_signal_connect(mainwin_svis, "button-press-event", G_CALLBACK(mainwin_vis_cb), NULL);
-
-    mainwin_position = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 16, 72, 248,
-                                                        10, 248, 0, 278, 0, 29, 10, 10, 0, 0, 219,
-                                                        NULL, SKIN_POSBAR);
-    g_signal_connect(mainwin_position, "motion", G_CALLBACK(mainwin_position_motion_cb), NULL);
-    g_signal_connect(mainwin_position, "release", G_CALLBACK(mainwin_position_release_cb), NULL);
-
-    mainwin_sposition = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 226, 4, 17,
-                                                         7, 17, 36, 17, 36, 3, 7, 36, 0, 1, 13,
-                                                         mainwin_spos_frame_cb, SKIN_TITLEBAR);
-    g_signal_connect(mainwin_sposition, "motion", G_CALLBACK(mainwin_spos_motion_cb), NULL);
-    g_signal_connect(mainwin_sposition, "release", G_CALLBACK(mainwin_spos_release_cb), NULL);
-
-    mainwin_stime_min = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 130, 4, 15, FALSE, SKIN_TEXT);
-    g_signal_connect(mainwin_stime_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    mainwin_stime_sec = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 147, 4, 10, FALSE, SKIN_TEXT);
-    g_signal_connect(mainwin_stime_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-
-    hook_associate("playback audio error", (void *) mainwin_stop_pushed, NULL);
-    hook_associate("playback audio error", (void *) run_no_output_device_dialog, NULL);
-
-    hook_associate("playback seek", (HookFunction) mainwin_update_song_info, NULL);
-}
-
-static void
-mainwin_create_window(void)
-{
-    gint width, height;
-
-    mainwin = ui_skinned_window_new("player");
-    gtk_window_set_title(GTK_WINDOW(mainwin), _("Audacious"));
-    gtk_window_set_role(GTK_WINDOW(mainwin), "player");
-    gtk_window_set_resizable(GTK_WINDOW(mainwin), FALSE);
-
-    width = cfg.player_shaded ? MAINWIN_SHADED_WIDTH : aud_active_skin->properties.mainwin_width;
-    height = cfg.player_shaded ? MAINWIN_SHADED_HEIGHT : aud_active_skin->properties.mainwin_height;
-
-    if (cfg.scaled) {
-        width *= cfg.scale_factor;
-        height *= cfg.scale_factor;
-    }
-
-    gtk_widget_set_size_request(mainwin, width, height);
-
-    if (cfg.player_x != -1 && cfg.save_window_position)
-        gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y);
-
-    g_signal_connect(mainwin, "destroy", G_CALLBACK(mainwin_destroy), NULL);
-    g_signal_connect(mainwin, "button_press_event",
-                     G_CALLBACK(mainwin_mouse_button_press), NULL);
-    g_signal_connect(mainwin, "scroll_event",
-                     G_CALLBACK(mainwin_scrolled), NULL);
-    g_signal_connect(mainwin, "button_release_event",
-                     G_CALLBACK(mainwin_mouse_button_release), NULL);
-
-    aud_drag_dest_set(mainwin);
-
-    g_signal_connect(mainwin, "key_press_event",
-                     G_CALLBACK(mainwin_keypress), NULL);
-
-    ui_main_evlistener_init();
-}
-
-void
-mainwin_create(void)
-{
-    mainwin_create_window();
-
-    gtk_window_add_accel_group( GTK_WINDOW(mainwin) , ui_manager_get_accel_group() );
-
-    mainwin_create_widgets();
-}
-
-gboolean
-mainwin_update_song_info(void)
-{
-    if (!playback_get_playing())
-        return FALSE;
-
-    gint time = playback_get_time();
-    gint length = playback_get_length();
-    gint t;
-    gchar stime_prefix;
-
-    if (ab_position_a != -1 && ab_position_b != -1 && time > ab_position_b)
-        playback_seek(ab_position_a/1000);
-
-    if (length == -1 && cfg.timer_mode == TIMER_REMAINING)
-        cfg.timer_mode = TIMER_ELAPSED;
-
-    playlistwin_set_time(time, length, cfg.timer_mode);
-
-    if (cfg.timer_mode == TIMER_REMAINING) {
-        if (length != -1) {
-            ui_skinned_number_set_number(mainwin_minus_num, 11);
-            t = length - time;
-            stime_prefix = '-';
-        }
-        else {
-            ui_skinned_number_set_number(mainwin_minus_num, 10);
-            t = time;
-            stime_prefix = ' ';
-        }
-    }
-    else {
-        ui_skinned_number_set_number(mainwin_minus_num, 10);
-        t = time;
-        stime_prefix = ' ';
-    }
-    t /= 1000;
-
-    /* Show the time in the format HH:MM when we have more than 100
-     * minutes. */
-    if (t >= 100 * 60)
-        t /= 60;
-    ui_skinned_number_set_number(mainwin_10min_num, t / 600);
-    ui_skinned_number_set_number(mainwin_min_num, (t / 60) % 10);
-    ui_skinned_number_set_number(mainwin_10sec_num, (t / 10) % 6);
-    ui_skinned_number_set_number(mainwin_sec_num, t % 10);
-
-    if (!UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->pressed) {
-        gchar *time_str;
-
-        time_str = g_strdup_printf("%c%2.2d", stime_prefix, t / 60);
-        ui_skinned_textbox_set_text(mainwin_stime_min, time_str);
-        g_free(time_str);
-
-        time_str = g_strdup_printf("%2.2d", t % 60);
-        ui_skinned_textbox_set_text(mainwin_stime_sec, time_str);
-        g_free(time_str);
-    }
-
-    time /= 1000;
-    length /= 1000;
-    if (length > 0) {
-        if (time > length) {
-            ui_skinned_horizontal_slider_set_position(mainwin_position, 219);
-            ui_skinned_horizontal_slider_set_position(mainwin_sposition, 13);
-        }
-        /* update the slider position ONLY if there is not a seek in progress */
-        else if (seek_state == MAINWIN_SEEK_NIL)  {
-            ui_skinned_horizontal_slider_set_position(mainwin_position, (time * 219) / length);
-            ui_skinned_horizontal_slider_set_position(mainwin_sposition,
-                                                      ((time * 12) / length) + 1);
-        }
-    }
-    else {
-        ui_skinned_horizontal_slider_set_position(mainwin_position, 0);
-        ui_skinned_horizontal_slider_set_position(mainwin_sposition, 1);
-    }
-
-    return TRUE;
-}
-
-static gboolean
-mainwin_idle_func(gpointer data)
-{
-    GDK_THREADS_ENTER();
-
-    /* tristate buttons seek */
-    if ( seek_state != MAINWIN_SEEK_NIL )
-    {
-        GTimeVal now_time;
-        GTimeVal delta_time;
-        gulong now_dur;
-        g_get_current_time(&now_time);
-
-        delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec;
-        delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec;
-
-        now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000));
-
-        if ( now_dur > TRISTATE_THRESHOLD )
-        {
-            gint np;
-            if (seek_state == MAINWIN_SEEK_REV)
-                np = seek_initial_pos - labs((gulong)(now_dur/100)); /* seek back */
-            else
-                np = seek_initial_pos + labs((gulong)(now_dur/100)); /* seek forward */
-
-            /* boundaries check */
-            if (np < 0 )
-                np = 0;
-            else if ( np > 219 )
-                np = 219;
-
-            ui_skinned_horizontal_slider_set_position( mainwin_position , np );
-            mainwin_position_motion_cb( mainwin_position, np );
-        }
-    }
-
-    GDK_THREADS_LEAVE();
-    return TRUE;
-}
-
-
-/* toggleactionentries actions */
-
-void
-action_anamode_peaks( GtkToggleAction * action )
-{
-    cfg.analyzer_peaks = gtk_toggle_action_get_active( action );
-}
-
-void
-action_autoscroll_songname( GtkToggleAction * action )
-{
-    mainwin_set_title_scroll(gtk_toggle_action_get_active(action));
-    playlistwin_set_sinfo_scroll(cfg.autoscroll); /* propagate scroll setting to playlistwin_sinfo */
-}
-
-void
-action_playback_noplaylistadvance( GtkToggleAction * action )
-{
-    cfg.no_playlist_advance = gtk_toggle_action_get_active( action );
-}
-
-void
-action_playback_repeat( GtkToggleAction * action )
-{
-    cfg.repeat = gtk_toggle_action_get_active( action );
-    UI_SKINNED_BUTTON(mainwin_repeat)->inside = cfg.repeat;
-    gtk_widget_queue_draw(mainwin_repeat);
-}
-
-void
-action_playback_shuffle( GtkToggleAction * action )
-{
-    cfg.shuffle = gtk_toggle_action_get_active( action );
-    playlist_set_shuffle(cfg.shuffle);
-    UI_SKINNED_BUTTON(mainwin_shuffle)->inside = cfg.shuffle;
-    gtk_widget_queue_draw(mainwin_shuffle);
-}
-
-void
-action_stop_after_current_song( GtkToggleAction * action )
-{
-    cfg.stopaftersong = gtk_toggle_action_get_active( action );
-}
-
-void
-action_view_always_on_top( GtkToggleAction * action )
-{
-    UI_SKINNED_MENUROW(mainwin_menurow)->always_selected = gtk_toggle_action_get_active( action );
-    cfg.always_on_top = UI_SKINNED_MENUROW(mainwin_menurow)->always_selected;
-    gtk_widget_queue_draw(mainwin_menurow);
-    hint_set_always(cfg.always_on_top);
-}
-
-void
-action_view_scaled( GtkToggleAction * action )
-{
-    UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected = gtk_toggle_action_get_active( action );
-    gtk_widget_queue_draw(mainwin_menurow);
-    set_scaled(UI_SKINNED_MENUROW(mainwin_menurow)->scale_selected);
-    gdk_flush();
-}
-
-void
-action_view_easymove( GtkToggleAction * action )
-{
-    cfg.easy_move = gtk_toggle_action_get_active( action );
-}
-
-void
-action_view_on_all_workspaces( GtkToggleAction * action )
-{
-    cfg.sticky = gtk_toggle_action_get_active( action );
-    hint_set_sticky(cfg.sticky);
-}
-
-void
-action_roll_up_equalizer( GtkToggleAction * action )
-{
-    equalizerwin_set_shade_menu_cb(gtk_toggle_action_get_active(action));
-}
-
-void
-action_roll_up_player( GtkToggleAction * action )
-{
-    mainwin_set_shade_menu_cb(gtk_toggle_action_get_active(action));
-}
-
-void
-action_roll_up_playlist_editor( GtkToggleAction * action )
-{
-    playlistwin_set_shade(gtk_toggle_action_get_active(action));
-}
-
-void
-action_show_equalizer( GtkToggleAction * action )
-{
-    if (gtk_toggle_action_get_active(action))
-        equalizerwin_real_show();
-    else
-        equalizerwin_real_hide();
-}
-
-void
-action_show_playlist_editor( GtkToggleAction * action )
-{
-    if (gtk_toggle_action_get_active(action))
-        playlistwin_show();
-    else
-        playlistwin_hide();
-}
-
-void
-action_show_player( GtkToggleAction * action )
-{
-    mainwin_show(gtk_toggle_action_get_active(action));
-}
-
-
-/* radioactionentries actions (one callback for each radio group) */
-
-void
-action_anafoff( GtkAction *action, GtkRadioAction *current )
-{
-    mainwin_vis_set_afalloff(gtk_radio_action_get_current_value(current));
-}
-
-void
-action_anamode( GtkAction *action, GtkRadioAction *current )
-{
-    mainwin_vis_set_analyzer_mode(gtk_radio_action_get_current_value(current));
-}
-
-void
-action_anatype( GtkAction *action, GtkRadioAction *current )
-{
-    mainwin_vis_set_analyzer_type(gtk_radio_action_get_current_value(current));
-}
-
-void
-action_peafoff( GtkAction *action, GtkRadioAction *current )
-{
-    mainwin_vis_set_pfalloff(gtk_radio_action_get_current_value(current));
-}
-
-void
-action_refrate( GtkAction *action, GtkRadioAction *current )
-{
-    mainwin_vis_set_refresh(gtk_radio_action_get_current_value(current));
-}
-
-void
-action_scomode( GtkAction *action, GtkRadioAction *current )
-{
-    cfg.scope_mode = gtk_radio_action_get_current_value(current);
-}
-
-void
-action_vismode( GtkAction *action, GtkRadioAction *current )
-{
-    mainwin_vis_set_type_menu_cb(gtk_radio_action_get_current_value(current));
-}
-
-void
-action_vprmode( GtkAction *action, GtkRadioAction *current )
-{
-    cfg.voiceprint_mode = gtk_radio_action_get_current_value(current);
-}
-
-void
-action_wshmode( GtkAction *action, GtkRadioAction *current )
-{
-    cfg.vu_mode = gtk_radio_action_get_current_value(current);
-}
-
-void
-action_viewtime( GtkAction *action, GtkRadioAction *current )
-{
-    set_timer_mode_menu_cb(gtk_radio_action_get_current_value(current));
-}
-
-
-/* actionentries actions */
-
-void
-action_about_audacious( void )
-{
-    show_about_window();
-}
-
-void
-action_play_file( void )
-{
-    run_filebrowser(TRUE);
-}
-
-void
-action_play_location( void )
-{
-    mainwin_show_add_url_window();
-}
-
-void
-action_ab_set( void )
-{
-    Playlist *playlist = playlist_get_active();
-    if (playlist_get_current_length(playlist) != -1)
-    {
-        if (ab_position_a == -1)
-        {
-            ab_position_a = playback_get_time();
-            ab_position_b = -1;
-            mainwin_lock_info_text("LOOP-POINT A POSITION SET.");
-        }
-        else if (ab_position_b == -1)
-        {
-            int time = playback_get_time();
-            if (time > ab_position_a)
-                ab_position_b = time;
-            mainwin_release_info_text();
-        }
-        else
-        {
-            ab_position_a = playback_get_time();
-            ab_position_b = -1;
-            mainwin_lock_info_text("LOOP-POINT A POSITION RESET.");
-        }
-    }
-}
-
-void
-action_ab_clear( void )
-{
-    Playlist *playlist = playlist_get_active();
-    if (playlist_get_current_length(playlist) != -1)
-    {
-        ab_position_a = ab_position_b = -1;
-        mainwin_release_info_text();
-    }
-}
-
-void
-action_current_track_info( void )
-{
-    ui_fileinfo_show_current(playlist_get_active());
-}
-
-void
-action_jump_to_file( void )
-{
-    ui_jump_to_track();
-}
-
-void
-action_jump_to_playlist_start( void )
-{
-    Playlist *playlist = playlist_get_active();
-    playlist_set_position(playlist, 0);
-}
-
-void
-action_jump_to_time( void )
-{
-    mainwin_jump_to_time();
-}
-
-void
-action_playback_next( void )
-{
-    Playlist *playlist = playlist_get_active();
-    playlist_next(playlist);
-}
-
-void
-action_playback_previous( void )
-{
-    Playlist *playlist = playlist_get_active();
-    playlist_prev(playlist);
-}
-
-void
-action_playback_play( void )
-{
-    mainwin_play_pushed();
-}
-
-void
-action_playback_pause( void )
-{
-    playback_pause();
-}
-
-void
-action_playback_stop( void )
-{
-    mainwin_stop_pushed();
-}
-
-void
-action_preferences( void )
-{
-    show_prefs_window();
-}
-
-void
-action_quit( void )
-{
-    mainwin_quit_cb();
-}
-
-void
-util_menu_main_show( gint x , gint y , guint button , guint time )
-{
-    /* convenience function that shows the main popup menu wherever requested */
-    ui_manager_popup_menu_show( GTK_MENU(mainwin_general_menu),
-                                x , y , button , time );
-    return;
-}
--- a/src/audacious/ui_main.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_MAIN_H
-#define AUDACIOUS_UI_MAIN_H
-
-#include <gtk/gtk.h>
-
-#include "ui_vis.h"
-#include "ui_svis.h"
-
-/* yes, main window size is fixed */
-#define MAINWIN_WIDTH            (gint)275
-#define MAINWIN_HEIGHT           (gint)116
-#define MAINWIN_TITLEBAR_HEIGHT  (gint)14
-#define MAINWIN_SHADED_WIDTH     MAINWIN_WIDTH
-#define MAINWIN_SHADED_HEIGHT    MAINWIN_TITLEBAR_HEIGHT
-#define MAINWIN_SCALE_FACTOR     (cfg.scaled ? cfg.scale_factor : 1)
-
-#define MAINWIN_UPDATE_INTERVAL  100
-
-#define MAINWIN_DEFAULT_POS_X    20
-#define MAINWIN_DEFAULT_POS_Y    20
-
-#define MAINWIN_DEFAULT_FONT     "Sans Bold 9"
-
-
-typedef enum {
-    TIMER_ELAPSED,
-    TIMER_REMAINING
-} TimerMode;
-
-enum {
-    MAINWIN_GENERAL_ABOUT,
-    
-    MAINWIN_GENERAL_PLAYFILE,
-    MAINWIN_GENERAL_PLAYLOCATION,
-
-    MAINWIN_GENERAL_FILEINFO,
-    MAINWIN_GENERAL_PREFS,
-
-    MAINWIN_GENERAL_SHOWMWIN,
-    MAINWIN_GENERAL_SHOWPLWIN,
-
-    MAINWIN_GENERAL_FOCUSMWIN,
-    MAINWIN_GENERAL_FOCUSPLWIN,
-
-    MAINWIN_GENERAL_SHOWEQWIN,
-    MAINWIN_GENERAL_EXIT,
-
-    MAINWIN_GENERAL_PREV,
-    MAINWIN_GENERAL_PLAY,
-    MAINWIN_GENERAL_PAUSE,
-    MAINWIN_GENERAL_STOP,
-    MAINWIN_GENERAL_NEXT,
-    MAINWIN_GENERAL_STOPFADE,
-    MAINWIN_GENERAL_BACK5SEC,
-    MAINWIN_GENERAL_FWD5SEC,
-    MAINWIN_GENERAL_START,
-    MAINWIN_GENERAL_BACK10,
-    MAINWIN_GENERAL_FWD10,
-    MAINWIN_GENERAL_JTT,
-    MAINWIN_GENERAL_JTF,
-    MAINWIN_GENERAL_QUEUE,
-    MAINWIN_GENERAL_CQUEUE,
-    MAINWIN_GENERAL_VOLUP,
-    MAINWIN_GENERAL_VOLDOWN,
-    MAINWIN_GENERAL_SETAB,
-    MAINWIN_GENERAL_CLEARAB,
-
-    MAINWIN_GENERAL_NEXT_PL,
-    MAINWIN_GENERAL_PREV_PL,
-    MAINWIN_GENERAL_NEW_PL
-};
-
-extern GtkWidget *mainwin;
-extern GtkWidget *err;
-
-extern gboolean mainwin_moving;
-extern gboolean mainwin_focus;
-
-extern GtkWidget *mainwin_jtf;
-extern GtkWidget *mainwin_eq, *mainwin_pl;
-extern GtkWidget *mainwin_info;
-
-extern GtkWidget *mainwin_stime_min, *mainwin_stime_sec;
-
-extern GtkWidget *mainwin_vis;
-extern GtkWidget *mainwin_svis;
-
-extern GtkWidget *mainwin_playstatus;
-
-extern GtkWidget *mainwin_minus_num, *mainwin_10min_num, *mainwin_min_num;
-extern GtkWidget *mainwin_10sec_num, *mainwin_sec_num;
-
-extern GtkWidget *mainwin_position, *mainwin_sposition;
-
-void mainwin_create(void);
-
-void mainwin_lock_info_text(const gchar * text);
-void mainwin_release_info_text(void);
-void mainwin_play_pushed(void);
-void mainwin_stop_pushed(void);
-void mainwin_eject_pushed(void);
-
-void mainwin_rev_pushed(void);
-void mainwin_rev_release(void);
-void mainwin_fwd_pushed(void);
-void mainwin_fwd_release(void);
-
-void mainwin_adjust_volume_motion(gint v);
-void mainwin_adjust_volume_release(void);
-void mainwin_adjust_balance_motion(gint b);
-void mainwin_adjust_balance_release(void);
-void mainwin_set_volume_slider(gint percent);
-void mainwin_set_balance_slider(gint percent);
-
-void mainwin_vis_set_type(VisType mode);
-
-void mainwin_refresh_hints(void);
-void mainwin_set_info_text(void);
-void mainwin_set_song_info(gint rate, gint freq, gint nch);
-void mainwin_clear_song_info(void);
-void mainwin_set_stopaftersong(gboolean stop);
-void mainwin_set_noplaylistadvance(gboolean no_advance);
-
-void mainwin_set_always_on_top(gboolean always);
-void mainwin_set_volume_diff(gint diff);
-void mainwin_set_balance_diff(gint diff);
-
-void mainwin_show(gboolean);
-void mainwin_real_show(void);
-void mainwin_real_hide(void);
-void mainwin_move(gint x, gint y);
-void mainwin_shuffle_pushed(gboolean toggled);
-void mainwin_repeat_pushed(gboolean toggled);
-void mainwin_disable_seekbar(void);
-void mainwin_set_title(const gchar * text);
-void mainwin_show_add_url_window(void);
-void mainwin_minimize_cb(void);
-void mainwin_general_menu_callback(gpointer cb_data,
-                                   guint action,
-                                   GtkWidget * widget);
-
-gboolean mainwin_update_song_info(void);
-void mainwin_drag_data_received(GtkWidget * widget,
-                                GdkDragContext * context,
-                                gint x,
-                                gint y,
-                                GtkSelectionData * selection_data,
-                                guint info,
-                                guint time,
-                                gpointer user_data);
-
-void mainwin_setup_menus(void);
-gboolean change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event);
-
-void mainwin_jump_to_file(void);
-void mainwin_jump_to_time(void);
-
-void mainwin_ewmh_activate(void);
-
-void mainwin_show_visibility_warning(void);
-
-/* FIXME: placed here for now */
-void playback_get_sample_params(gint * bitrate,
-                                gint * frequency,
-                                gint * numchannels);
-
-void ui_main_check_theme_engine(void);
-
-void util_menu_main_show( gint x , gint y , guint button , guint time );
-
-#endif /* AUDACIOUS_UI_MAIN_H */
--- a/src/audacious/ui_main_evlisteners.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,474 +0,0 @@
-/*
- * Audacious
- * Copyright (c) 2006-2007 Audacious development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_playlist_evlisteners.h"
-
-#include <glib.h>
-#include <math.h>
-
-#include "hook.h"
-#include "playback.h"
-#include "playlist.h"
-#include "playlist_evmessages.h"
-#include "visualization.h"
-
-#include "ui_credits.h"
-#include "ui_equalizer.h"
-#include "ui_fileopener.h"
-#include "ui_jumptotrack.h"
-#include "ui_main.h"
-#include "ui_playlist.h"
-#include "ui_preferences.h"
-#include "ui_skinned_playstatus.h"
-#include "ui_skinned_textbox.h"
-#include "ui_skinned_window.h"
-
-static gint song_info_timeout_source = 0;
-static gint update_vis_timeout_source = 0;
-
-/* XXX: there has to be a better way than polling here! */
-/* also: where should this function go? should it stay here? --mf0102 */
-static gboolean
-update_vis_func(gpointer unused)
-{
-    if (!playback_get_playing())
-        return FALSE;
-
-    input_update_vis(playback_get_time());
-
-    return TRUE;
-}
-
-static void
-ui_main_evlistener_title_change(gpointer hook_data, gpointer user_data)
-{
-    gchar *text = (gchar *) hook_data;
-
-    ui_skinned_textbox_set_text(mainwin_info, text);
-    playlistwin_update_list(playlist_get_active());
-}
-
-static void
-ui_main_evlistener_hide_seekbar(gpointer hook_data, gpointer user_data)
-{
-    mainwin_disable_seekbar();
-}
-
-static void
-ui_main_evlistener_volume_change(gpointer hook_data, gpointer user_data)
-{
-    gint *h_vol = (gint *) hook_data;
-    gint vl, vr, b, v;
-
-    vl = CLAMP(h_vol[0], 0, 100);
-    vr = CLAMP(h_vol[1], 0, 100);
-    v = MAX(vl, vr);
-    if (vl > vr)
-        b = (gint) rint(((gdouble) vr / vl) * 100) - 100;
-    else if (vl < vr)
-        b = 100 - (gint) rint(((gdouble) vl / vr) * 100);
-    else
-        b = 0;
-
-    mainwin_set_volume_slider(v);
-    equalizerwin_set_volume_slider(v);
-    mainwin_set_balance_slider(b);
-    equalizerwin_set_balance_slider(b);
-}
-
-static void
-ui_main_evlistener_playback_initiate(gpointer hook_data, gpointer user_data)
-{
-    playback_initiate();
-}
-
-static void
-ui_main_evlistener_playback_begin(gpointer hook_data, gpointer user_data)
-{
-    PlaylistEntry *entry = (PlaylistEntry*)hook_data;
-    g_return_if_fail(entry != NULL);
-
-    equalizerwin_load_auto_preset(entry->filename);
-    hook_call("equalizer changed", NULL);
-
-    ui_vis_clear_data(mainwin_vis);
-    ui_svis_clear_data(mainwin_svis);
-    mainwin_disable_seekbar();
-    mainwin_update_song_info();
-
-    if (cfg.player_shaded) {
-        gtk_widget_show(mainwin_stime_min);
-        gtk_widget_show(mainwin_stime_sec);
-        gtk_widget_show(mainwin_sposition);
-    } else {
-        gtk_widget_show(mainwin_minus_num);
-        gtk_widget_show(mainwin_10min_num);
-        gtk_widget_show(mainwin_min_num);
-        gtk_widget_show(mainwin_10sec_num);
-        gtk_widget_show(mainwin_sec_num);
-        gtk_widget_show(mainwin_position);
-    }
-
-    song_info_timeout_source = 
-        g_timeout_add_seconds(1, (GSourceFunc) mainwin_update_song_info, NULL);
-
-    update_vis_timeout_source =
-        g_timeout_add(10, (GSourceFunc) update_vis_func, NULL);
-
-    vis_playback_start();
-
-    ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
-}
-
-static void
-ui_main_evlistener_playback_stop(gpointer hook_data, gpointer user_data)
-{
-    if (song_info_timeout_source)
-        g_source_remove(song_info_timeout_source);
-
-    vis_playback_stop();
-    free_vis_data();
-
-    ui_skinned_playstatus_set_buffering(mainwin_playstatus, FALSE);
-}
-
-static void
-ui_main_evlistener_playback_pause(gpointer hook_data, gpointer user_data)
-{
-    ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PAUSE);
-}
-
-static void
-ui_main_evlistener_playback_unpause(gpointer hook_data, gpointer user_data)
-{
-    ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY);
-}
-
-static void
-ui_main_evlistener_playback_seek(gpointer hook_data, gpointer user_data)
-{
-    free_vis_data();
-}
-
-static void
-ui_main_evlistener_playback_play_file(gpointer hook_data, gpointer user_data)
-{
-    if (cfg.random_skin_on_play)
-        skin_set_random_skin();
-}
-
-static void
-ui_main_evlistener_playlist_end_reached(gpointer hook_data, gpointer user_data)
-{
-    mainwin_clear_song_info();
-
-    if (cfg.stopaftersong)
-        mainwin_set_stopaftersong(FALSE);
-}
-
-static void
-ui_main_evlistener_playlist_info_change(gpointer hook_data, gpointer user_data)
-{
-    PlaylistEventInfoChange *msg = (PlaylistEventInfoChange *) hook_data;
-
-    mainwin_set_song_info(msg->bitrate, msg->samplerate, msg->channels);
-}
-
-static void
-ui_main_evlistener_mainwin_set_always_on_top(gpointer hook_data, gpointer user_data)
-{
-    gboolean *ontop = (gboolean*)hook_data;
-    mainwin_set_always_on_top(*ontop);
-}
-
-static void
-ui_main_evlistener_mainwin_show(gpointer hook_data, gpointer user_data)
-{
-    gboolean *show = (gboolean*)hook_data;
-    mainwin_show(*show);
-}
-
-static void
-ui_main_evlistener_equalizerwin_show(gpointer hook_data, gpointer user_data)
-{
-    gboolean *show = (gboolean*)hook_data;
-    equalizerwin_show(*show);
-}
-
-static void
-ui_main_evlistener_prefswin_show(gpointer hook_data, gpointer user_data)
-{
-    gboolean *show = (gboolean*)hook_data;
-    if (*show == TRUE)
-        show_prefs_window();
-    else
-        hide_prefs_window();
-}
-
-static void
-ui_main_evlistener_aboutwin_show(gpointer hook_data, gpointer user_data)
-{
-    gboolean *show = (gboolean*)hook_data;
-    if (*show == TRUE)
-        show_about_window();
-    else
-        hide_about_window();
-}
-
-
-static void
-ui_main_evlistener_ui_jump_to_track_show(gpointer hook_data, gpointer user_data)
-{
-    gboolean *show = (gboolean*)hook_data;
-    if (*show == TRUE)
-        ui_jump_to_track();
-    else
-        ui_jump_to_track_hide();
-}
-
-static void
-ui_main_evlistener_filebrowser_show(gpointer hook_data, gpointer user_data)
-{
-    gboolean *play_button = (gboolean*)hook_data;
-    run_filebrowser(*play_button);
-}
-
-static void
-ui_main_evlistener_filebrowser_hide(gpointer hook_data, gpointer user_data)
-{
-    hide_filebrowser();
-}
-
-static void
-ui_main_evlistener_visualization_timeout(gpointer hook_data, gpointer user_data)
-{
-    if (hook_data == NULL) {
-        if (cfg.player_shaded && cfg.player_visible)
-            ui_svis_timeout_func(mainwin_svis, NULL);
-        else
-            ui_vis_timeout_func(mainwin_vis, NULL);
-        return;
-    }
-
-    VisNode *vis = (VisNode*) hook_data;
-
-    guint8 intern_vis_data[512];
-    gint16 mono_freq[2][256];
-    gboolean mono_freq_calced = FALSE;
-    gint16 mono_pcm[2][512], stereo_pcm[2][512];
-    gboolean mono_pcm_calced = FALSE, stereo_pcm_calced = FALSE;
-    gint i;
-
-    if (cfg.vis_type == VIS_OFF)
-        return;
-
-    if (cfg.vis_type == VIS_ANALYZER) {
-            /* Spectrum analyzer */
-            /* 76 values */
-            const gint long_xscale[] =
-                { 0, 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, 61, 66, 71, 76, 81, 87, 93,
-                100, 107,
-                114, 122, 131, 140, 150, 161, 172, 184, 255
-            };
-            /* 20 values */
-            const int short_xscale[] =
-                { 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 15, 20, 27,
-                36, 47, 62, 82, 107, 141, 184, 255
-            };
-            const double y_scale = 3.60673760222;   /* 20.0 / log(256) */
-            const int *xscale;
-            gint j, y, max;
-
-            if (!mono_freq_calced)
-                calc_mono_freq(mono_freq, vis->data, vis->nch);
-
-            memset(intern_vis_data, 0, 75);
-
-            if (cfg.analyzer_type == ANALYZER_BARS) {
-                if (cfg.player_shaded) {
-                    max = 13;
-                }
-                else {
-                    max = 19;
-                }
-                xscale = short_xscale;
-            }
-            else {
-                if (cfg.player_shaded) {
-                    max = 37;
-                }
-                else {
-                    max = 75;
-                }
-                xscale = long_xscale;
-            }
-
-            for (i = 0; i < max; i++) {
-                for (j = xscale[i], y = 0; j < xscale[i + 1]; j++) {
-                    if (mono_freq[0][j] > y)
-                        y = mono_freq[0][j];
-                }
-                y >>= 7;
-                if (y != 0) {
-                    intern_vis_data[i] = log(y) * y_scale;
-                    if (intern_vis_data[i] > 15)
-                        intern_vis_data[i] = 15;
-                }
-                else
-                    intern_vis_data[i] = 0;
-            }
-        
-    }
-    else if(cfg.vis_type == VIS_VOICEPRINT){
-        if (cfg.player_shaded && cfg.player_visible) {
-            /* VU */
-            gint vu, val;
-
-            if (!stereo_pcm_calced)
-                calc_stereo_pcm(stereo_pcm, vis->data, vis->nch);
-            vu = 0;
-            for (i = 0; i < 512; i++) {
-                val = abs(stereo_pcm[0][i]);
-                if (val > vu)
-                    vu = val;
-            }
-            intern_vis_data[0] = (vu * 37) >> 15;
-            if (intern_vis_data[0] > 37)
-                intern_vis_data[0] = 37;
-            if (vis->nch == 2) {
-                vu = 0;
-                for (i = 0; i < 512; i++) {
-                    val = abs(stereo_pcm[1][i]);
-                    if (val > vu)
-                        vu = val;
-                }
-                intern_vis_data[1] = (vu * 37) >> 15;
-                if (intern_vis_data[1] > 37)
-                    intern_vis_data[1] = 37;
-            }
-            else
-                intern_vis_data[1] = intern_vis_data[0];
-        }
-        else { /*Voiceprint*/
-            if (!mono_freq_calced)
-                calc_mono_freq(mono_freq, vis->data, vis->nch);
-            memset(intern_vis_data, 0, 256);
-
-            /* For the values [0-16] we use the frequency that's 3/2 as much.
-               If we assume the 512 values calculated by calc_mono_freq to
-               cover 0-22kHz linearly we get a range of
-               [0-16] * 3/2 * 22000/512 = [0-1,031] Hz.
-               Most stuff above that is harmonics and we want to utilize the
-               16 samples we have to the max[tm]
-               */
-            for (i = 0; i < 50 ; i+=3){
-                intern_vis_data[i/3] += (mono_freq[0][i/2] >> 5);
-
-                /*Boost frequencies above 257Hz a little*/
-                //if(i > 4 * 3)
-                //  intern_vis_data[i/3] += 8;
-            }
-        }
-    }
-    else { /* (cfg.vis_type == VIS_SCOPE) */
-
-        /* Oscilloscope */
-        gint pos, step;
-
-        if (!mono_pcm_calced)
-            calc_mono_pcm(mono_pcm, vis->data, vis->nch);
-
-        step = (vis->length << 8) / 74;
-        for (i = 0, pos = 0; i < 75; i++, pos += step) {
-            intern_vis_data[i] = ((mono_pcm[0][pos >> 8]) >> 12) + 7;
-            if (intern_vis_data[i] == 255)
-                intern_vis_data[i] = 0;
-            else if (intern_vis_data[i] > 12)
-                intern_vis_data[i] = 12;
-            /* Do not see the point of that? (comparison always false) -larne.
-               if (intern_vis_data[i] < 0)
-               intern_vis_data[i] = 0; */
-        }
-    }
-
-    if (cfg.player_shaded && cfg.player_visible)
-        ui_svis_timeout_func(mainwin_svis, intern_vis_data);
-    else
-        ui_vis_timeout_func(mainwin_vis, intern_vis_data);
-}
-
-static void
-ui_main_evlistener_config_save(gpointer hook_data, gpointer user_data)
-{
-    ConfigDb *db = (ConfigDb *) hook_data;
-
-    if (SKINNED_WINDOW(mainwin)->x != -1 &&
-        SKINNED_WINDOW(mainwin)->y != -1 )
-    {
-        cfg_db_set_int(db, NULL, "player_x", SKINNED_WINDOW(mainwin)->x);
-        cfg_db_set_int(db, NULL, "player_y", SKINNED_WINDOW(mainwin)->y);
-    }
-
-    cfg_db_set_bool(db, NULL, "mainwin_use_bitmapfont",
-                    cfg.mainwin_use_bitmapfont);
-}
-
-static void
-ui_main_evlistener_equalizer_changed(gpointer hook_data, gpointer user_data)
-{
-    output_set_eq(cfg.equalizer_active, cfg.equalizer_preamp,
-                  cfg.equalizer_bands);
-}
-
-void
-ui_main_evlistener_init(void)
-{
-    hook_associate("title change", ui_main_evlistener_title_change, NULL);
-    hook_associate("hide seekbar", ui_main_evlistener_hide_seekbar, NULL);
-    hook_associate("volume set", ui_main_evlistener_volume_change, NULL);
-    hook_associate("playback initiate", ui_main_evlistener_playback_initiate, NULL);
-    hook_associate("playback begin", ui_main_evlistener_playback_begin, NULL);
-    hook_associate("playback stop", ui_main_evlistener_playback_stop, NULL);
-    hook_associate("playback pause", ui_main_evlistener_playback_pause, NULL);
-    hook_associate("playback unpause", ui_main_evlistener_playback_unpause, NULL);
-    hook_associate("playback seek", ui_main_evlistener_playback_seek, NULL);
-    hook_associate("playback play file", ui_main_evlistener_playback_play_file, NULL);
-    hook_associate("playlist end reached", ui_main_evlistener_playlist_end_reached, NULL);
-    hook_associate("playlist info change", ui_main_evlistener_playlist_info_change, NULL);
-    hook_associate("mainwin set always on top", ui_main_evlistener_mainwin_set_always_on_top, NULL);
-    hook_associate("mainwin show", ui_main_evlistener_mainwin_show, NULL);
-    hook_associate("equalizerwin show", ui_main_evlistener_equalizerwin_show, NULL);
-    hook_associate("prefswin show", ui_main_evlistener_prefswin_show, NULL);
-    hook_associate("aboutwin show", ui_main_evlistener_aboutwin_show, NULL);
-    hook_associate("ui jump to track show", ui_main_evlistener_ui_jump_to_track_show, NULL);
-    hook_associate("filebrowser show", ui_main_evlistener_filebrowser_show, NULL);
-    hook_associate("filebrowser hide", ui_main_evlistener_filebrowser_hide, NULL);
-    hook_associate("visualization timeout", ui_main_evlistener_visualization_timeout, NULL);
-    hook_associate("config save", ui_main_evlistener_config_save, NULL);
-
-    hook_associate("equalizer changed", ui_main_evlistener_equalizer_changed, NULL);
-}
-
--- a/src/audacious/ui_main_evlisteners.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Audacious
- * Copyright (c) 2006-2007 Audacious development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include <glib.h>
-
-#ifndef AUDACIOUS_UI_MAIN_EVLISTENERS_H
-#define AUDACIOUS_UI_MAIN_EVLISTENERS_H
-
-void ui_main_evlistener_init(void);
-
-#endif /* AUDACIOUS_UI_MAIN_EVLISTENERS_H */
--- a/src/audacious/ui_manager.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,872 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include "ui_manager.h"
-#include "actions-mainwin.h"
-#include "actions-playlist.h"
-#include "actions-equalizer.h"
-
-/* this header contains prototypes for plugin-available menu functions */
-#include "ui_plugin_menu.h"
-
-/* TODO ui_main.h is only included because ui_manager.c needs the values of
-   TimerMode enum; move that enum elsewhere so we can get rid of this include */
-#include "ui_main.h"
-
-#include "icons-stock.h"
-
-#include "sync-menu.h"
-
-static GtkUIManager *ui_manager = NULL;
-static gboolean menu_created = FALSE;
-
-
-/* toggle action entries */
-
-static GtkToggleActionEntry toggleaction_entries_others[] = {
-
-	{ "autoscroll songname", NULL , N_("Autoscroll Songname"), NULL,
-	  N_("Autoscroll Songname"), G_CALLBACK(action_autoscroll_songname) , FALSE },
-
-	{ "stop after current song", NULL , N_("Stop after Current Song"), "<Ctrl>M",
-	  N_("Stop after Current Song"), G_CALLBACK(action_stop_after_current_song) , FALSE },
-
-	{ "anamode peaks", NULL , N_("Peaks"), NULL,
-	  N_("Peaks"), G_CALLBACK(action_anamode_peaks) , FALSE },
-
-	{ "playback repeat", NULL , N_("Repeat"), "R",
-	  N_("Repeat"), G_CALLBACK(action_playback_repeat) , FALSE },
-
-	{ "playback shuffle", NULL , N_("Shuffle"), "S",
-	  N_("Shuffle"), G_CALLBACK(action_playback_shuffle) , FALSE },
-
-	{ "playback no playlist advance", NULL , N_("No Playlist Advance"), "<Ctrl>N",
-	  N_("No Playlist Advance"), G_CALLBACK(action_playback_noplaylistadvance) , FALSE },
-
-	{ "show player", NULL , N_("Show Player"), "<Alt>M",
-	  N_("Show Player"), G_CALLBACK(action_show_player) , FALSE },
-
-	{ "show playlist editor", NULL , N_("Show Playlist Editor"), "<Alt>E",
-	  N_("Show Playlist Editor"), G_CALLBACK(action_show_playlist_editor) , FALSE },
-
-	{ "show equalizer", NULL , N_("Show Equalizer"), "<Alt>G",
-	  N_("Show Equalizer"), G_CALLBACK(action_show_equalizer) , FALSE },
-
-	{ "view always on top", NULL , N_("Always on Top"), "<Ctrl>O",
-	  N_("Always on Top"), G_CALLBACK(action_view_always_on_top) , FALSE },
-
-	{ "view put on all workspaces", NULL , N_("Put on All Workspaces"), "<Ctrl>S",
-	  N_("Put on All Workspaces"), G_CALLBACK(action_view_on_all_workspaces) , FALSE },
-
-	{ "roll up player", NULL , N_("Roll up Player"), "<Ctrl>W",
-	  N_("Roll up Player"), G_CALLBACK(action_roll_up_player) , FALSE },
-
-	{ "roll up playlist editor", NULL , N_("Roll up Playlist Editor"), "<Shift><Ctrl>W",
-	  N_("Roll up Playlist Editor"), G_CALLBACK(action_roll_up_playlist_editor) , FALSE },
-
-	{ "roll up equalizer", NULL , N_("Roll up Equalizer"), "<Ctrl><Alt>W",
-	  N_("Roll up Equalizer"), G_CALLBACK(action_roll_up_equalizer) , FALSE },
-
-	{ "view scaled", NULL , N_("Scale"), "<Ctrl>D",
-	  N_("DoubleSize"), G_CALLBACK(action_view_scaled) , FALSE },
-
-	{ "view easy move", NULL , N_("Easy Move"), "<Ctrl>E",
-	  N_("Easy Move"), G_CALLBACK(action_view_easymove) , FALSE }
-};
-
-
-
-/* radio action entries */
-
-static GtkRadioActionEntry radioaction_entries_vismode[] = {
-	{ "vismode analyzer", NULL , N_("Analyzer"), NULL, N_("Analyzer"), VIS_ANALYZER },
-	{ "vismode scope", NULL , N_("Scope"), NULL, N_("Scope"), VIS_SCOPE },
-	{ "vismode voiceprint", NULL , N_("Voiceprint"), NULL, N_("Voiceprint"), VIS_VOICEPRINT },
-	{ "vismode off", NULL , N_("Off"), NULL, N_("Off"), VIS_OFF }
-};
-
-static GtkRadioActionEntry radioaction_entries_anamode[] = {
-	{ "anamode normal", NULL , N_("Normal"), NULL, N_("Normal"), ANALYZER_NORMAL },
-	{ "anamode fire", NULL , N_("Fire"), NULL, N_("Fire"), ANALYZER_FIRE },
-	{ "anamode vertical lines", NULL , N_("Vertical Lines"), NULL, N_("Vertical Lines"), ANALYZER_VLINES }
-};
-
-static GtkRadioActionEntry radioaction_entries_anatype[] = {
-	{ "anatype lines", NULL , N_("Lines"), NULL, N_("Lines"), ANALYZER_LINES },
-	{ "anatype bars", NULL , N_("Bars"), NULL, N_("Bars"), ANALYZER_BARS }
-};
-
-static GtkRadioActionEntry radioaction_entries_scomode[] = {
-	{ "scomode dot", NULL , N_("Dot Scope"), NULL, N_("Dot Scope"), SCOPE_DOT },
-	{ "scomode line", NULL , N_("Line Scope"), NULL, N_("Line Scope"), SCOPE_LINE },
-	{ "scomode solid", NULL , N_("Solid Scope"), NULL, N_("Solid Scope"), SCOPE_SOLID }
-};
-
-static GtkRadioActionEntry radioaction_entries_vprmode[] = {
-	{ "vprmode normal", NULL , N_("Normal"), NULL, N_("Normal"), VOICEPRINT_NORMAL },
-	{ "vprmode fire", NULL , N_("Fire"), NULL, N_("Fire"), VOICEPRINT_FIRE },
-	{ "vprmode ice", NULL , N_("Ice"), NULL, N_("Ice"), VOICEPRINT_ICE }
-};
-
-static GtkRadioActionEntry radioaction_entries_wshmode[] = {
-	{ "wshmode normal", NULL , N_("Normal"), NULL, N_("Normal"), VU_NORMAL },
-	{ "wshmode smooth", NULL , N_("Smooth"), NULL, N_("Smooth"), VU_SMOOTH }
-};
-
-static GtkRadioActionEntry radioaction_entries_refrate[] = {
-	{ "refrate full", NULL , N_("Full (~50 fps)"), NULL, N_("Full (~50 fps)"), REFRESH_FULL },
-	{ "refrate half", NULL , N_("Half (~25 fps)"), NULL, N_("Half (~25 fps)"), REFRESH_HALF },
-	{ "refrate quarter", NULL , N_("Quarter (~13 fps)"), NULL, N_("Quarter (~13 fps)"), REFRESH_QUARTER },
-	{ "refrate eighth", NULL , N_("Eighth (~6 fps)"), NULL, N_("Eighth (~6 fps)"), REFRESH_EIGTH }
-};
-
-static GtkRadioActionEntry radioaction_entries_anafoff[] = {
-	{ "anafoff slowest", NULL , N_("Slowest"), NULL, N_("Slowest"), FALLOFF_SLOWEST },
-	{ "anafoff slow", NULL , N_("Slow"), NULL, N_("Slow"), FALLOFF_SLOW },
-	{ "anafoff medium", NULL , N_("Medium"), NULL, N_("Medium"), FALLOFF_MEDIUM },
-	{ "anafoff fast", NULL , N_("Fast"), NULL, N_("Fast"), FALLOFF_FAST },
-	{ "anafoff fastest", NULL , N_("Fastest"), NULL, N_("Fastest"), FALLOFF_FASTEST }
-};
-
-static GtkRadioActionEntry radioaction_entries_peafoff[] = {
-	{ "peafoff slowest", NULL , N_("Slowest"), NULL, N_("Slowest"), FALLOFF_SLOWEST },
-	{ "peafoff slow", NULL , N_("Slow"), NULL, N_("Slow"), FALLOFF_SLOW },
-	{ "peafoff medium", NULL , N_("Medium"), NULL, N_("Medium"), FALLOFF_MEDIUM },
-	{ "peafoff fast", NULL , N_("Fast"), NULL, N_("Fast"), FALLOFF_FAST },
-	{ "peafoff fastest", NULL , N_("Fastest"), NULL, N_("Fastest"), FALLOFF_FASTEST }
-};
-
-static GtkRadioActionEntry radioaction_entries_viewtime[] = {
-	{ "view time elapsed", NULL , N_("Time Elapsed"), "<Ctrl>E", N_("Time Elapsed"), TIMER_ELAPSED },
-	{ "view time remaining", NULL , N_("Time Remaining"), "<Ctrl>R", N_("Time Remaining"), TIMER_REMAINING }
-};
-
-
-
-/* normal actions */
-
-static GtkActionEntry action_entries_playback[] = {
-
-	{ "playback", NULL, N_("Playback") },
-	
-	{ "playback play", GTK_STOCK_MEDIA_PLAY , N_("Play"), "X",
-	  N_("Play"), G_CALLBACK(action_playback_play) },
-
-	{ "playback pause", GTK_STOCK_MEDIA_PAUSE , N_("Pause"), "C",
-	  N_("Pause"), G_CALLBACK(action_playback_pause) },
-
-	{ "playback stop", GTK_STOCK_MEDIA_STOP , N_("Stop"), "V",
-	  N_("Stop"), G_CALLBACK(action_playback_stop) },
-
-	{ "playback previous", GTK_STOCK_MEDIA_PREVIOUS , N_("Previous"), "Z",
-	  N_("Previous"), G_CALLBACK(action_playback_previous) },
-
-	{ "playback next", GTK_STOCK_MEDIA_NEXT , N_("Next"), "B",
-	  N_("Next"), G_CALLBACK(action_playback_next) }
-};
-
-
-static GtkActionEntry action_entries_visualization[] = {
-	{ "visualization", NULL, N_("Visualization") },
-	{ "vismode", NULL, N_("Visualization Mode") },
-	{ "anamode", NULL, N_("Analyzer Mode") },
-	{ "scomode", NULL, N_("Scope Mode") },
-	{ "vprmode", NULL, N_("Voiceprint Mode") },
-	{ "wshmode", NULL, N_("WindowShade VU Mode") },
-	{ "refrate", NULL, N_("Refresh Rate") },
-	{ "anafoff", NULL, N_("Analyzer Falloff") },
-	{ "peafoff", NULL, N_("Peaks Falloff") }
-};
-
-static GtkActionEntry action_entries_playlist[] = {
-
-	{ "playlist", NULL, N_("Playlist") },
-
-	{ "playlist new", GTK_STOCK_NEW , N_("New Playlist"), "<Shift>N",
-	  N_("New Playlist"), G_CALLBACK(action_playlist_new) },
-
-	{ "playlist select next", GTK_STOCK_MEDIA_NEXT, N_("Select Next Playlist"), "<Shift>P",
-	  N_("Select Next Playlist"), G_CALLBACK(action_playlist_next) },
-
-	{ "playlist select previous", GTK_STOCK_MEDIA_PREVIOUS, N_("Select Previous Playlist"), "<Shift><Ctrl>P",
-	  N_("Select Previous Playlist"), G_CALLBACK(action_playlist_prev) },
-
-	{ "playlist delete", GTK_STOCK_DELETE , N_("Delete Playlist"), "<Shift>D",
-	  N_("Delete Playlist"), G_CALLBACK(action_playlist_delete) },
-
-        { "playlist load", GTK_STOCK_OPEN, N_("Load List"), "O",
-          N_("Loads a playlist file into the selected playlist."), G_CALLBACK(action_playlist_load_list) },
-
-        { "playlist save", GTK_STOCK_SAVE, N_("Save List"), "<Shift>S",
-          N_("Saves the selected playlist."), G_CALLBACK(action_playlist_save_list) },
-
-        { "playlist save default", GTK_STOCK_SAVE, N_("Save Default List"), "<Alt>S",
-          N_("Saves the selected playlist to the default location."),
-          G_CALLBACK(action_playlist_save_default_list) },
-
-        { "playlist refresh", GTK_STOCK_REFRESH, N_("Refresh List"), "F5",
-          N_("Refreshes metadata associated with a playlist entry."),
-          G_CALLBACK(action_playlist_refresh_list) },
-
-        { "playlist manager", AUD_STOCK_PLAYLIST , N_("List Manager"), "P",
-          N_("Opens the playlist manager."),
-          G_CALLBACK(action_open_list_manager) }
-};
-
-static GtkActionEntry action_entries_view[] = {
-
-	{ "view", NULL, N_("View") }
-};
-
-static GtkActionEntry action_entries_playlist_add[] = {
-        { "playlist add url", GTK_STOCK_NETWORK, N_("Add Internet Address..."), "<Ctrl>H",
-          N_("Adds a remote track to the playlist."),
-          G_CALLBACK(action_playlist_add_url) },
-
-        { "playlist add files", GTK_STOCK_ADD, N_("Add Files..."), "F",
-          N_("Adds files to the playlist."),
-          G_CALLBACK(action_playlist_add_files) },
-};
-
-static GtkActionEntry action_entries_playlist_select[] = {
-        { "playlist search and select", GTK_STOCK_FIND, N_("Search and Select"), "<Ctrl>F",
-          N_("Searches the playlist and selects playlist entries based on specific criteria."),
-          G_CALLBACK(action_playlist_search_and_select) },
-
-        { "playlist invert selection", NULL , N_("Invert Selection"), NULL,
-          N_("Inverts the selected and unselected entries."),
-          G_CALLBACK(action_playlist_invert_selection) },
-
-        { "playlist select all", NULL , N_("Select All"), "<Ctrl>A",
-          N_("Selects all of the playlist entries."),
-          G_CALLBACK(action_playlist_select_all) },
-
-        { "playlist select none", NULL , N_("Select None"), "<Shift><Ctrl>A",
-          N_("Deselects all of the playlist entries."),
-          G_CALLBACK(action_playlist_select_none) },
-};
-
-static GtkActionEntry action_entries_playlist_delete[] = {
-	{ "playlist remove all", GTK_STOCK_CLEAR, N_("Remove All"), NULL, 
-	  N_("Removes all entries from the playlist."),
-	  G_CALLBACK(action_playlist_remove_all) },
-
-	{ "playlist clear queue", GTK_STOCK_CLEAR, N_("Clear Queue"), "<Shift>Q",
-	  N_("Clears the queue associated with this playlist."),
-	  G_CALLBACK(action_playlist_clear_queue) },
-
-	{ "playlist remove unavailable", GTK_STOCK_DIALOG_ERROR , N_("Remove Unavailable Files"), NULL,
-	  N_("Removes unavailable files from the playlist."),
-	  G_CALLBACK(action_playlist_remove_unavailable) },
-
-	{ "playlist remove dups menu", NULL , N_("Remove Duplicates") },
-
-	{ "playlist remove dups by title", NULL , N_("By Title"), NULL,
-	  N_("Removes duplicate entries from the playlist by title."),
-	  G_CALLBACK(action_playlist_remove_dupes_by_title) },
-
-	{ "playlist remove dups by filename", NULL , N_("By Filename"), NULL, 
-	  N_("Removes duplicate entries from the playlist by filename."),
-	  G_CALLBACK(action_playlist_remove_dupes_by_filename) },
-
-	{ "playlist remove dups by full path", NULL , N_("By Path + Filename"), NULL, 
-	  N_("Removes duplicate entries from the playlist by their full path."),
-	  G_CALLBACK(action_playlist_remove_dupes_by_full_path) },
-
-	{ "playlist remove unselected", GTK_STOCK_REMOVE, N_("Remove Unselected"), NULL,
-	  N_("Remove unselected entries from the playlist."),
-	  G_CALLBACK(action_playlist_remove_unselected) },
-
-	{ "playlist remove selected", GTK_STOCK_REMOVE, N_("Remove Selected"), "Delete", 
-	  N_("Remove selected entries from the playlist."),
-	  G_CALLBACK(action_playlist_remove_selected) },
-};
-
-static GtkActionEntry action_entries_playlist_sort[] = {
-	{ "playlist randomize list", AUD_STOCK_RANDOMIZEPL , N_("Randomize List"), "<Ctrl><Shift>R",
-	  N_("Randomizes the playlist."),
-	  G_CALLBACK(action_playlist_randomize_list) },
-
-	{ "playlist reverse list", GTK_STOCK_GO_UP , N_("Reverse List"), NULL,
-	  N_("Reverses the playlist."),
-	  G_CALLBACK(action_playlist_reverse_list) },
-
-	{ "playlist sort menu", GTK_STOCK_GO_DOWN , N_("Sort List") },
-
-	{ "playlist sort by title", NULL , N_("By Title"), NULL,
-	  N_("Sorts the list by title."),
-	  G_CALLBACK(action_playlist_sort_by_title) },
-
-	{ "playlist sort by artist", NULL , N_("By Artist"), NULL,
-	  N_("Sorts the list by artist."),
-	  G_CALLBACK(action_playlist_sort_by_artist) },
-
-	{ "playlist sort by filename", NULL , N_("By Filename"), NULL,
-	  N_("Sorts the list by filename."),
-	  G_CALLBACK(action_playlist_sort_by_filename) },
-
-	{ "playlist sort by full path", NULL , N_("By Path + Filename"), NULL,
-	  N_("Sorts the list by full pathname."),
-	  G_CALLBACK(action_playlist_sort_by_full_path) },
-
-	{ "playlist sort by date", NULL , N_("By Date"), NULL,
-	  N_("Sorts the list by modification time."),
-	  G_CALLBACK(action_playlist_sort_by_date) },
-
-	{ "playlist sort by track number", NULL , N_("By Track Number"), NULL,
-	  N_("Sorts the list by track number."),
-	  G_CALLBACK(action_playlist_sort_by_track_number) },
-
-	{ "playlist sort by playlist entry", NULL , N_("By Playlist Entry"), NULL,
-	  N_("Sorts the list by playlist entry."),
-	  G_CALLBACK(action_playlist_sort_by_playlist_entry) },
-
-	{ "playlist sort selected menu", GTK_STOCK_GO_DOWN , N_("Sort Selected") },
-
-	{ "playlist sort selected by title", NULL , N_("By Title"), NULL,
-	  N_("Sorts the list by title."),
-	  G_CALLBACK(action_playlist_sort_selected_by_title) },
-
-	{ "playlist sort selected by artist", NULL, N_("By Artist"), NULL,
-	  N_("Sorts the list by artist."),
-	  G_CALLBACK(action_playlist_sort_selected_by_artist) },
-
-	{ "playlist sort selected by filename", NULL , N_("By Filename"), NULL,
-	  N_("Sorts the list by filename."),
-	  G_CALLBACK(action_playlist_sort_selected_by_filename) },
-
-	{ "playlist sort selected by full path", NULL , N_("By Path + Filename"), NULL,
-	  N_("Sorts the list by full pathname."),
-	  G_CALLBACK(action_playlist_sort_selected_by_full_path) },
-
-	{ "playlist sort selected by date", NULL , N_("By Date"), NULL,
-	  N_("Sorts the list by modification time."),
-	  G_CALLBACK(action_playlist_sort_selected_by_date) },
-
-	{ "playlist sort selected by track number", NULL , N_("By Track Number"), NULL,
-	  N_("Sorts the list by track number."),
-	  G_CALLBACK(action_playlist_sort_selected_by_track_number) },
-
-	{ "playlist sort selected by playlist entry", NULL, N_("By Playlist Entry"), NULL,
-	  N_("Sorts the list by playlist entry."),
-	  G_CALLBACK(action_playlist_sort_selected_by_playlist_entry) },
-};
-
-static GtkActionEntry action_entries_others[] = {
-
-	{ "dummy", NULL, "dummy" },
-
-        /* XXX Carbon support */
-        { "file", NULL, N_("File") },
-        { "help", NULL, N_("Help") },
-
-	{ "plugins-menu", AUD_STOCK_PLUGIN, N_("Plugin Services") },
-
-	{ "current track info", GTK_STOCK_INFO , N_("View Track Details"), "I",
-	  N_("View track details"), G_CALLBACK(action_current_track_info) },
-
-	{ "playlist track info", GTK_STOCK_INFO , N_("View Track Details"), "<Alt>I",
-	  N_("View track details"), G_CALLBACK(action_playlist_track_info) },
-
-	{ "about audacious", GTK_STOCK_DIALOG_INFO , N_("About Audacious"), NULL,
-	  N_("About Audacious"), G_CALLBACK(action_about_audacious) },
-
-	{ "play file", GTK_STOCK_OPEN , N_("Play File"), "L",
-	  N_("Load and play a file"), G_CALLBACK(action_play_file) },
-
-	{ "play location", GTK_STOCK_NETWORK , N_("Play Location"), "<Ctrl>L",
-	  N_("Play media from the selected location"), G_CALLBACK(action_play_location) },
-
-    { "plugins", NULL , N_("Plugin services") },
-
-	{ "preferences", GTK_STOCK_PREFERENCES , N_("Preferences"), "<Ctrl>P",
-	  N_("Open preferences window"), G_CALLBACK(action_preferences) },
-
-	{ "quit", GTK_STOCK_QUIT , N_("_Quit"), NULL,
-	  N_("Quit Audacious"), G_CALLBACK(action_quit) },
-
-	{ "ab set", NULL , N_("Set A-B"), "A",
-	  N_("Set A-B"), G_CALLBACK(action_ab_set) },
-
-	{ "ab clear", NULL , N_("Clear A-B"), "<Shift>A",
-	  N_("Clear A-B"), G_CALLBACK(action_ab_clear) },
-
-	{ "jump to playlist start", GTK_STOCK_GOTO_TOP , N_("Jump to Playlist Start"), "<Ctrl>Z",
-	  N_("Jump to Playlist Start"), G_CALLBACK(action_jump_to_playlist_start) },
-
-	{ "jump to file", GTK_STOCK_JUMP_TO , N_("Jump to File"), "J",
-	  N_("Jump to File"), G_CALLBACK(action_jump_to_file) },
-
-	{ "jump to time", GTK_STOCK_JUMP_TO , N_("Jump to Time"), "<Ctrl>J",
-	  N_("Jump to Time"), G_CALLBACK(action_jump_to_time) },
-
-	{ "queue toggle", AUD_STOCK_QUEUETOGGLE , N_("Queue Toggle"), "Q", 
-	  N_("Enables/disables the entry in the playlist's queue."),
-	  G_CALLBACK(action_queue_toggle) },
-};
-
-
-static GtkActionEntry action_entries_equalizer[] = {
-
-    { "equ preset load menu", NULL, N_("Load") },
-    { "equ preset import menu", NULL, N_("Import") },
-    { "equ preset save menu", NULL, N_("Save") },
-    { "equ preset delete menu", NULL, N_("Delete") },
-
-    { "equ load preset", NULL, N_("Preset"), NULL,
-      N_("Load preset"), G_CALLBACK(action_equ_load_preset) },
-
-    { "equ load auto preset", NULL, N_("Auto-load preset"), NULL,
-      N_("Load auto-load preset"), G_CALLBACK(action_equ_load_auto_preset) },
-
-    { "equ load default preset", NULL, N_("Default"), NULL,
-      N_("Load default preset into equalizer"), G_CALLBACK(action_equ_load_default_preset) },
-
-    { "equ zero preset", NULL, N_("Zero"), NULL,
-      N_("Set equalizer preset levels to zero"), G_CALLBACK(action_equ_zero_preset) },
-
-    { "equ load preset file", NULL, N_("From file"), NULL,
-      N_("Load preset from file"), G_CALLBACK(action_equ_load_preset_file) },
-
-    { "equ load preset eqf", NULL, N_("From WinAMP EQF file"), NULL,
-      N_("Load preset from WinAMP EQF file"), G_CALLBACK(action_equ_load_preset_eqf) },
-
-    { "equ import winamp presets", NULL, N_("WinAMP Presets"), NULL,
-      N_("Import WinAMP presets"), G_CALLBACK(action_equ_import_winamp_presets) },
-
-    { "equ save preset", NULL, N_("Preset"), NULL,
-      N_("Save preset"), G_CALLBACK(action_equ_save_preset) },
-
-    { "equ save auto preset", NULL, N_("Auto-load preset"), NULL,
-      N_("Save auto-load preset"), G_CALLBACK(action_equ_save_auto_preset) },
-
-    { "equ save default preset", NULL, N_("Default"), NULL,
-      N_("Save default preset"), G_CALLBACK(action_equ_save_default_preset) },
-
-    { "equ save preset file", NULL, N_("To file"), NULL,
-      N_("Save preset to file"), G_CALLBACK(action_equ_save_preset_file) },
-
-    { "equ save preset eqf", NULL, N_("To WinAMP EQF file"), NULL,
-      N_("Save preset to WinAMP EQF file"), G_CALLBACK(action_equ_save_preset_eqf) },
-
-    { "equ delete preset", NULL, N_("Preset"), NULL,
-      N_("Delete preset"), G_CALLBACK(action_equ_delete_preset) },
-
-    { "equ delete auto preset", NULL, N_("Auto-load preset"), NULL,
-      N_("Delete auto-load preset"), G_CALLBACK(action_equ_delete_auto_preset) }
-};
-
-
-
-/* ***************************** */
-
-
-static GtkActionGroup *
-ui_manager_new_action_group( const gchar * group_name )
-{
-  GtkActionGroup *group = gtk_action_group_new( group_name );
-  gtk_action_group_set_translation_domain( group , PACKAGE_NAME );
-  return group;
-}
-
-void
-ui_manager_init ( void )
-{
-  /* toggle actions */
-  toggleaction_group_others = ui_manager_new_action_group("toggleaction_others");
-  gtk_action_group_add_toggle_actions(
-    toggleaction_group_others , toggleaction_entries_others ,
-    G_N_ELEMENTS(toggleaction_entries_others) , NULL );
-
-  /* radio actions */
-  radioaction_group_anamode = ui_manager_new_action_group("radioaction_anamode");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_anamode , radioaction_entries_anamode ,
-    G_N_ELEMENTS(radioaction_entries_anamode) , 0 , G_CALLBACK(action_anamode) , NULL );
-
-  radioaction_group_anatype = ui_manager_new_action_group("radioaction_anatype");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_anatype , radioaction_entries_anatype ,
-    G_N_ELEMENTS(radioaction_entries_anatype) , 0 , G_CALLBACK(action_anatype) , NULL );
-
-  radioaction_group_scomode = ui_manager_new_action_group("radioaction_scomode");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_scomode , radioaction_entries_scomode ,
-    G_N_ELEMENTS(radioaction_entries_scomode) , 0 , G_CALLBACK(action_scomode) , NULL );
-
-  radioaction_group_vprmode = ui_manager_new_action_group("radioaction_vprmode");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_vprmode , radioaction_entries_vprmode ,
-    G_N_ELEMENTS(radioaction_entries_vprmode) , 0 , G_CALLBACK(action_vprmode) , NULL );
-
-  radioaction_group_wshmode = ui_manager_new_action_group("radioaction_wshmode");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_wshmode , radioaction_entries_wshmode ,
-    G_N_ELEMENTS(radioaction_entries_wshmode) , 0 , G_CALLBACK(action_wshmode) , NULL );
-
-  radioaction_group_refrate = ui_manager_new_action_group("radioaction_refrate");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_refrate , radioaction_entries_refrate ,
-    G_N_ELEMENTS(radioaction_entries_refrate) , 0 , G_CALLBACK(action_refrate) , NULL );
-
-  radioaction_group_anafoff = ui_manager_new_action_group("radioaction_anafoff");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_anafoff , radioaction_entries_anafoff ,
-    G_N_ELEMENTS(radioaction_entries_anafoff) , 0 , G_CALLBACK(action_anafoff) , NULL );
-
-  radioaction_group_peafoff = ui_manager_new_action_group("radioaction_peafoff");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_peafoff , radioaction_entries_peafoff ,
-    G_N_ELEMENTS(radioaction_entries_peafoff) , 0 , G_CALLBACK(action_peafoff) , NULL );
-
-  radioaction_group_vismode = ui_manager_new_action_group("radioaction_vismode");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_vismode , radioaction_entries_vismode ,
-    G_N_ELEMENTS(radioaction_entries_vismode) , 0 , G_CALLBACK(action_vismode) , NULL );
-
-  radioaction_group_viewtime = ui_manager_new_action_group("radioaction_viewtime");
-  gtk_action_group_add_radio_actions(
-    radioaction_group_viewtime , radioaction_entries_viewtime ,
-    G_N_ELEMENTS(radioaction_entries_viewtime) , 0 , G_CALLBACK(action_viewtime) , NULL );
-
-  /* normal actions */
-  action_group_playback = ui_manager_new_action_group("action_playback");
-    gtk_action_group_add_actions(
-    action_group_playback , action_entries_playback ,
-    G_N_ELEMENTS(action_entries_playback) , NULL );
-
-  action_group_playlist = ui_manager_new_action_group("action_playlist");
-    gtk_action_group_add_actions(
-    action_group_playlist , action_entries_playlist ,
-    G_N_ELEMENTS(action_entries_playlist) , NULL );
-
-  action_group_visualization = ui_manager_new_action_group("action_visualization");
-    gtk_action_group_add_actions(
-    action_group_visualization , action_entries_visualization ,
-    G_N_ELEMENTS(action_entries_visualization) , NULL );
-
-  action_group_view = ui_manager_new_action_group("action_view");
-    gtk_action_group_add_actions(
-    action_group_view , action_entries_view ,
-    G_N_ELEMENTS(action_entries_view) , NULL );
-
-  action_group_others = ui_manager_new_action_group("action_others");
-    gtk_action_group_add_actions(
-    action_group_others , action_entries_others ,
-    G_N_ELEMENTS(action_entries_others) , NULL );
-
-  action_group_playlist_add = ui_manager_new_action_group("action_playlist_add");
-  gtk_action_group_add_actions(
-    action_group_playlist_add, action_entries_playlist_add,
-    G_N_ELEMENTS(action_entries_playlist_add), NULL );
-
-  action_group_playlist_select = ui_manager_new_action_group("action_playlist_select");
-  gtk_action_group_add_actions(
-    action_group_playlist_select, action_entries_playlist_select,
-    G_N_ELEMENTS(action_entries_playlist_select), NULL );
-
-  action_group_playlist_delete = ui_manager_new_action_group("action_playlist_delete");
-  gtk_action_group_add_actions(
-    action_group_playlist_delete, action_entries_playlist_delete,
-    G_N_ELEMENTS(action_entries_playlist_delete), NULL );
-
-  action_group_playlist_sort = ui_manager_new_action_group("action_playlist_sort");
-  gtk_action_group_add_actions(
-    action_group_playlist_sort, action_entries_playlist_sort,
-    G_N_ELEMENTS(action_entries_playlist_sort), NULL );
-
-  action_group_equalizer = ui_manager_new_action_group("action_equalizer");
-  gtk_action_group_add_actions(
-    action_group_equalizer, action_entries_equalizer,
-    G_N_ELEMENTS(action_entries_equalizer), NULL);
-
-  /* ui */
-  ui_manager = gtk_ui_manager_new();
-  gtk_ui_manager_insert_action_group( ui_manager , toggleaction_group_others , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_anamode , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_anatype , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_scomode , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_vprmode , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_wshmode , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_refrate , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_anafoff , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_peafoff , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_vismode , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , radioaction_group_viewtime , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_playback , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_visualization , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_view , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_others , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_add , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_select , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_delete , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_playlist_sort , 0 );
-  gtk_ui_manager_insert_action_group( ui_manager , action_group_equalizer , 0 );
-
-  return;
-}
-
-#ifdef GDK_WINDOWING_QUARTZ
-static GtkWidget *carbon_menubar;
-#endif
-
-static void
-ui_manager_create_menus_init_pmenu( gchar * path )
-{
-  GtkWidget *plugins_menu_item = gtk_ui_manager_get_widget( ui_manager , path );
-  if ( plugins_menu_item )
-  {
-    /* initially set count of items under plugins_menu_item to 0 */
-    g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(0) );
-    /* and since it's 0, hide the plugins_menu_item */
-    gtk_widget_hide( plugins_menu_item );
-  }
-  return;
-}
-
-
-void
-ui_manager_create_menus ( void )
-{
-  GError *gerr = NULL;
-
-  /* attach xml menu definitions */
-  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/mainwin.ui" , &gerr );
-
-  if ( gerr != NULL )
-  {
-    g_critical( "Error creating UI<ui/mainwin.ui>: %s" , gerr->message );
-    g_error_free( gerr );
-    return;
-  }
-
-  /* create GtkMenu widgets using path from xml definitions */
-  mainwin_songname_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/songname-menu" );
-  mainwin_visualization_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/visualization" );
-  mainwin_playback_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/playback" );
-  mainwin_playlist_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/playlist" );
-  mainwin_view_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/view" );
-  mainwin_general_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu" );
-
-  /* initialize plugins-menu for mainwin-menus */
-  ui_manager_create_menus_init_pmenu( "/mainwin-menus/main-menu/plugins-menu" );
-
-#ifdef GDK_WINDOWING_QUARTZ
-  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/carbon-menubar.ui" , &gerr );
-
-  if ( gerr != NULL )
-  {
-    g_critical( "Error creating UI<ui/carbon-menubar.ui>: %s" , gerr->message );
-    g_error_free( gerr );
-    return;
-  }
-
-  carbon_menubar = ui_manager_get_popup_menu( ui_manager , "/carbon-menubar/main-menu" );
-  sync_menu_takeover_menu(GTK_MENU_SHELL(carbon_menubar));
-#endif
-
-  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/playlist.ui" , &gerr );
-
-  if ( gerr != NULL )
-  {
-    g_critical( "Error creating UI<ui/playlist.ui>: %s" , gerr->message );
-    g_error_free( gerr );
-    return;
-  }
-
-  playlistwin_popup_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/playlist-rightclick-menu");
-
-  playlistwin_pladd_menu  = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/add-menu");
-  playlistwin_pldel_menu  = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/del-menu");
-  playlistwin_plsel_menu  = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/select-menu");
-  playlistwin_plsort_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/misc-menu");
-  playlistwin_pllist_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/playlist-menu");
-
-  /* initialize plugins-menu for playlist-menus */
-  ui_manager_create_menus_init_pmenu( "/playlist-menus/playlist-menu/plugins-menu" );
-  ui_manager_create_menus_init_pmenu( "/playlist-menus/add-menu/plugins-menu" );
-  ui_manager_create_menus_init_pmenu( "/playlist-menus/del-menu/plugins-menu" );
-  ui_manager_create_menus_init_pmenu( "/playlist-menus/select-menu/plugins-menu" );
-  ui_manager_create_menus_init_pmenu( "/playlist-menus/misc-menu/plugins-menu" );
-  ui_manager_create_menus_init_pmenu( "/playlist-menus/playlist-rightclick-menu/plugins-menu" );
-
-  gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/equalizer.ui" , &gerr );
-
-  if ( gerr != NULL )
-  {
-    g_critical( "Error creating UI<ui/equalizer.ui>: %s" , gerr->message );
-    g_error_free( gerr );
-    return;
-  }
-
-  equalizerwin_presets_menu = ui_manager_get_popup_menu(ui_manager, "/equalizer-menus/preset-menu");
-
-  menu_created = TRUE;
-
-  return;
-}
-
-
-GtkAccelGroup *
-ui_manager_get_accel_group ( void )
-{
-  return gtk_ui_manager_get_accel_group( ui_manager );
-}
-
-
-GtkWidget *
-ui_manager_get_popup_menu ( GtkUIManager * self , const gchar * path )
-{
-  GtkWidget *menu_item = gtk_ui_manager_get_widget( self , path );
-
-  if (GTK_IS_MENU_ITEM(menu_item))
-    return gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item));
-  else
-    return NULL;
-}
-
-
-static void
-menu_popup_pos_func (GtkMenu * menu , gint * x , gint * y , gboolean * push_in , gint * point )
-{
-  GtkRequisition requisition;
-  gint screen_width;
-  gint screen_height;
-
-  gtk_widget_size_request(GTK_WIDGET(menu), &requisition);
-
-  screen_width = gdk_screen_width();
-  screen_height = gdk_screen_height();
-
-  *x = CLAMP(point[0] - 2, 0, MAX(0, screen_width - requisition.width));
-  *y = CLAMP(point[1] - 2, 0, MAX(0, screen_height - requisition.height));
-
-  *push_in = FALSE;
-}
-
-
-void
-ui_manager_popup_menu_show ( GtkMenu * menu , gint x , gint y , guint button , guint time )
-{
-  gint pos[2];
-  pos[0] = x;
-  pos[1] = y;
-
-  gtk_menu_popup( menu , NULL , NULL ,
-    (GtkMenuPositionFunc) menu_popup_pos_func , pos , button , time );
-}
-
-
-
-/******************************/
-/* plugin-available functions */
-
-#define _MP_GWID(y) gtk_ui_manager_get_widget( ui_manager , y )
-
-static GtkWidget*
-audacious_menu_plugin_menuwid( menu_id )
-{
-  switch (menu_id)
-  {
-    case AUDACIOUS_MENU_MAIN:
-      return _MP_GWID("/mainwin-menus/main-menu/plugins-menu");
-    case AUDACIOUS_MENU_PLAYLIST:
-      return _MP_GWID("/playlist-menus/playlist-menu/plugins-menu");
-    case AUDACIOUS_MENU_PLAYLIST_RCLICK:
-      return _MP_GWID("/playlist-menus/playlist-rightclick-menu/plugins-menu");
-    case AUDACIOUS_MENU_PLAYLIST_ADD:
-      return _MP_GWID("/playlist-menus/add-menu/plugins-menu");
-    case AUDACIOUS_MENU_PLAYLIST_REMOVE:
-      return _MP_GWID("/playlist-menus/del-menu/plugins-menu");
-    case AUDACIOUS_MENU_PLAYLIST_SELECT:
-      return _MP_GWID("/playlist-menus/select-menu/plugins-menu");
-    case AUDACIOUS_MENU_PLAYLIST_MISC:
-      return _MP_GWID("/playlist-menus/misc-menu/plugins-menu");
-    default:
-      return NULL;
-  }
-}
-
-
-gint
-menu_plugin_item_add( gint menu_id , GtkWidget * item )
-{
-  if ( menu_created )
-  {
-    GtkWidget *plugins_menu = NULL;
-    GtkWidget *plugins_menu_item = audacious_menu_plugin_menuwid( menu_id );
-    if ( plugins_menu_item )
-    {
-      gint ic = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(plugins_menu_item),"ic"));
-      if ( ic == 0 ) /* no items under plugins_menu_item, create the submenu */
-      {
-        plugins_menu = gtk_menu_new();
-        gtk_menu_item_set_submenu( GTK_MENU_ITEM(plugins_menu_item), plugins_menu );
-      }
-      else /* items available under plugins_menu_item, pick the existing submenu */
-      {
-        plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
-        if ( !plugins_menu ) return -1;
-      }
-      gtk_menu_shell_append( GTK_MENU_SHELL(plugins_menu) , item );
-      gtk_widget_show( plugins_menu_item );
-      g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(++ic) );
-      return 0; /* success */
-    }
-  }
-  return -1; /* failure */
-}
-
-
-gint
-menu_plugin_item_remove( gint menu_id , GtkWidget * item )
-{
-  if ( menu_created )
-  {
-    GtkWidget *plugins_menu = NULL;
-    GtkWidget *plugins_menu_item = audacious_menu_plugin_menuwid( menu_id );
-    if ( plugins_menu_item )
-    {
-      gint ic = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(plugins_menu_item),"ic"));
-      if ( ic > 0 )
-      {
-        plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
-        if ( plugins_menu )
-        {
-          /* remove the plugin-added entry */
-          gtk_container_remove( GTK_CONTAINER(plugins_menu) , item );
-          g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(--ic) );
-          if ( ic == 0 ) /* if the menu is empty now, destroy it */
-          {
-            gtk_menu_item_remove_submenu( GTK_MENU_ITEM(plugins_menu_item) );
-            gtk_widget_destroy( plugins_menu );
-            gtk_widget_hide( plugins_menu_item );
-          }
-          return 0; /* success */
-        }
-      }
-    }
-  }
-  return -1; /* failure */
-}
--- a/src/audacious/ui_manager.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_MANAGER_H
-#define AUDACIOUS_UI_MANAGER_H
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-GtkWidget *mainwin_songname_menu;
-GtkWidget *mainwin_general_menu;
-GtkWidget *mainwin_visualization_menu;
-GtkWidget *mainwin_playback_menu;
-GtkWidget *mainwin_playlist_menu;
-GtkWidget *mainwin_view_menu;
-
-GtkWidget *playlistwin_pladd_menu;
-GtkWidget *playlistwin_pldel_menu;
-GtkWidget *playlistwin_plsel_menu;
-GtkWidget *playlistwin_plsort_menu;
-GtkWidget *playlistwin_pllist_menu;
-GtkWidget *playlistwin_popup_menu;
-
-GtkWidget *equalizerwin_presets_menu;
-
-GtkActionGroup *toggleaction_group_others;
-GtkActionGroup *radioaction_group_anamode; /* Analyzer mode */
-GtkActionGroup *radioaction_group_anatype; /* Analyzer type */
-GtkActionGroup *radioaction_group_scomode; /* Scope mode */
-GtkActionGroup *radioaction_group_vprmode; /* Voiceprint mode */
-GtkActionGroup *radioaction_group_wshmode; /* WindowShade VU mode */
-GtkActionGroup *radioaction_group_refrate; /* Refresh rate */
-GtkActionGroup *radioaction_group_anafoff; /* Analyzer Falloff */
-GtkActionGroup *radioaction_group_peafoff; /* Peak Falloff */
-GtkActionGroup *radioaction_group_vismode; /* Visualization mode */
-GtkActionGroup *radioaction_group_viewtime; /* View time (remaining/elapsed) */
-GtkActionGroup *action_group_playback;
-GtkActionGroup *action_group_visualization;
-GtkActionGroup *action_group_view;
-GtkActionGroup *action_group_others;
-GtkActionGroup *action_group_playlist;
-GtkActionGroup *action_group_playlist_add;
-GtkActionGroup *action_group_playlist_select;
-GtkActionGroup *action_group_playlist_delete;
-GtkActionGroup *action_group_playlist_sort;
-GtkActionGroup *action_group_equalizer;
-
-
-void ui_manager_init ( void );
-void ui_manager_create_menus ( void );
-GtkAccelGroup * ui_manager_get_accel_group ( void );
-GtkWidget * ui_manager_get_popup_menu ( GtkUIManager * , const gchar * );
-void ui_manager_popup_menu_show( GtkMenu * , gint , gint , guint , guint );
-#define popup_menu_show(x1,x2,x3,x4,x5) ui_manager_popup_menu_show(x1,x2,x3,x4,x5)
-
-G_END_DECLS
-
-#endif /* AUDACIOUS_UI_MANAGER_H */
--- a/src/audacious/ui_new.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_new.c	Wed Aug 06 22:33:27 2008 +0300
@@ -25,9 +25,11 @@
 #include "playlist.h"
 #include "ui_fileopener.h"
 #include "ui_new.h"
+#include "ui_playlist_widget.h"
 
-static GtkWidget *label_prev, *label_current, *label_next, *label_time;
+static GtkWidget *label_time;
 static GtkWidget *slider;
+static GtkWidget *treeview;
 
 static gulong slider_change_handler_id;
 static gboolean slider_is_moving = FALSE;
@@ -73,6 +75,12 @@
 }
 
 static void
+button_stop_pressed()
+{
+    playback_stop();
+}
+
+static void
 button_previous_pressed()
 {
     playlist_prev(playlist_get_active());
@@ -87,16 +95,17 @@
 static void
 ui_set_song_info(gchar *text, gpointer user_data)
 {
-    gchar *esc_title = g_markup_escape_text(text, -1);
-    gchar *title = g_strdup_printf("<big>%s</big>", esc_title);
-
     gint length = playback_get_length();
 
-    gtk_label_set_markup(GTK_LABEL(label_current), title);
+    /* block "value-changed" signal handler to prevent skipping track
+       if the next track is shorter than the previous one --desowin */
+    g_signal_handler_block(slider, slider_change_handler_id);
     gtk_range_set_range(GTK_RANGE(slider), 0.0, (gdouble)length);
+    g_signal_handler_unblock(slider, slider_change_handler_id);
 
-    g_free(esc_title);
-    g_free(title);
+    gtk_widget_show(label_time);
+
+    ui_playlist_widget_set_current(treeview, playlist_get_position(playlist_get_active()));
 }
 
 static void
@@ -105,6 +114,8 @@
     gchar *text = playlist_get_info_text(playlist);
     ui_set_song_info(text, NULL);
     g_free(text);
+
+    ui_playlist_widget_update(treeview);
 }
 
 static void
@@ -128,7 +139,7 @@
 {
     if (!playback_get_playing())
     {
-        gtk_range_set_value(GTK_RANGE(slider), (gdouble)0);
+        gtk_range_set_value(GTK_RANGE(slider), 0.0);
         return FALSE;
     }
 
@@ -146,12 +157,23 @@
     return TRUE;
 }
 
+static void
+ui_clear_song_info()
+{
+    gtk_widget_hide(label_time);
+    gtk_range_set_value(GTK_RANGE(slider), 0);
+}
+
 static gboolean
 ui_slider_value_changed_cb(GtkRange *range, gpointer user_data)
 {
-    /* we are not allowed to do a playback_seek() with values < 1, therefore
-     * we add 1 to be on the safe side --mf0102 */
-    playback_seek(gtk_range_get_value(range)/1000 + 1);
+    gint seek_;
+
+    seek_ = gtk_range_get_value(range) / 1000;
+
+    /* XXX: work around a horrible bug in playback_seek(), also
+       we should do mseek here. --nenolod */
+    playback_seek(seek_ != 0 ? seek_ : 1);
 
     return TRUE;
 }
@@ -196,6 +218,9 @@
         g_source_remove(update_song_timeout_source);
         update_song_timeout_source = 0;
     }
+
+    ui_clear_song_info();
+    ui_playlist_widget_set_current(treeview, -1);
 }
 
 static void
@@ -251,17 +276,15 @@
     GtkWidget *window;      /* the main window */
     GtkWidget *vbox;        /* the main vertical box */
     GtkWidget *toolbar;     /* contains buttons like "open", "next" */
-    GtkWidget *pcnbox;      /* box containing information about previous,
-                               current and next track */
 
-    GtkWidget *chbox;   /* box containing album art and information
-                           about current track */
-    GtkWidget *cvbox;   /* box containing information about current track
-                           and some control elements like position bar */
     GtkWidget *shbox;   /* box for slider + time combo --nenolod */
 
+    GtkWidget *scrollwin;   /* widget to hold playlist widget */
+
+    GtkWidget *paned;
+
     GtkToolItem *button_open, *button_add,
-                *button_play, *button_pause,
+                *button_play, *button_pause, *button_stop,
                 *button_previous, *button_next;
 
     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -276,6 +299,9 @@
     gtk_container_add(GTK_CONTAINER(window), vbox);
 
 
+    paned = gtk_hpaned_new();
+    gtk_box_pack_start(GTK_BOX(vbox), paned, FALSE, TRUE, 0);
+
     toolbar = gtk_toolbar_new();
     gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
     button_open = gtk_toolbar_button_add(toolbar, button_open_pressed,
@@ -286,34 +312,17 @@
                                          GTK_STOCK_MEDIA_PLAY);
     button_pause = gtk_toolbar_button_add(toolbar, button_pause_pressed,
                                           GTK_STOCK_MEDIA_PAUSE);
+    button_stop = gtk_toolbar_button_add(toolbar, button_stop_pressed,
+                                         GTK_STOCK_MEDIA_STOP);
     button_previous = gtk_toolbar_button_add(toolbar, button_previous_pressed,
                                              GTK_STOCK_MEDIA_PREVIOUS);
     button_next = gtk_toolbar_button_add(toolbar, button_next_pressed,
                                          GTK_STOCK_MEDIA_NEXT);
-    gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, TRUE, 0);
 
-
-    pcnbox = gtk_vbox_new(FALSE, 0);
-
-    chbox = gtk_hbox_new(FALSE, 0);
-    cvbox = gtk_vbox_new(FALSE, 0);
-    label_current = gtk_markup_label_new("<big>Current: ?</big>");
-    gtk_misc_set_alignment(GTK_MISC(label_current), 0.0, 0.5);
-    gtk_box_pack_start(GTK_BOX(cvbox), label_current, TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(chbox), cvbox, TRUE, TRUE, 0);
-
-    label_prev = gtk_markup_label_new("<small>Previous: ?</small>");
-    label_next = gtk_markup_label_new("<small>Next: ?</small>");
-    gtk_misc_set_alignment(GTK_MISC(label_prev), 0.0, 0.5);
-    gtk_misc_set_alignment(GTK_MISC(label_next), 1.0, 0.5);
-    gtk_box_pack_start(GTK_BOX(pcnbox), label_prev, TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(pcnbox), chbox, TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(pcnbox), label_next, TRUE, TRUE, 0);
-
-    gtk_box_pack_start(GTK_BOX(vbox), pcnbox, TRUE, TRUE, 0);
+    gtk_paned_pack1(GTK_PANED(paned), toolbar, TRUE, TRUE);
 
     shbox = gtk_hbox_new(FALSE, 0);
-    gtk_box_pack_end(GTK_BOX(cvbox), shbox, TRUE, TRUE, 0);
+    gtk_paned_add2(GTK_PANED(paned), shbox);
 
     slider = gtk_hscale_new(NULL);
     gtk_scale_set_draw_value(GTK_SCALE(slider), FALSE);
@@ -321,9 +330,19 @@
     gtk_range_set_update_policy(GTK_RANGE(slider), GTK_UPDATE_DISCONTINUOUS);
     gtk_box_pack_start(GTK_BOX(shbox), slider, TRUE, TRUE, 0);
 
-    label_time = gtk_markup_label_new("<tt><b>0:00/0:00</b></tt>");
+    label_time = gtk_markup_label_new(NULL);
     gtk_box_pack_start(GTK_BOX(shbox), label_time, FALSE, FALSE, 0);
 
+    treeview = ui_playlist_widget_new();
+    scrollwin = gtk_scrolled_window_new(NULL, NULL);
+    gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
+                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin),
+                                        GTK_SHADOW_IN);
+
+    gtk_box_pack_end(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
+
     ui_hooks_associate();
 
     slider_change_handler_id =
@@ -340,6 +359,9 @@
     ui_playlist_update(playlist_get_active(), NULL);
 
     gtk_widget_show_all(window);
+
+    ui_clear_song_info();
+
     gtk_main();
 
     return TRUE;
--- a/src/audacious/ui_playlist.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1923 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2006  Audacious development team.
- *
- *  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-/* #define AUD_DEBUG 1 */
-
-#include "ui_playlist.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <string.h>
-
-#include "platform/smartinclude.h"
-
-#include <unistd.h>
-#include <errno.h>
-
-#include "actions-playlist.h"
-#include "dnd.h"
-#include "input.h"
-#include "main.h"
-#include "playback.h"
-#include "playlist.h"
-#include "playlist_container.h"
-#include "strings.h"
-#include "ui_dock.h"
-#include "ui_equalizer.h"
-#include "ui_fileinfo.h"
-#include "ui_fileopener.h"
-#include "ui_main.h"
-#include "ui_manager.h"
-#include "ui_playlist_evlisteners.h"
-#include "ui_playlist_manager.h"
-#include "util.h"
-#include "config.h"
-
-#include "ui_skinned_window.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_textbox.h"
-#include "ui_skinned_playlist_slider.h"
-#include "ui_skinned_playlist.h"
-
-#include "icons-stock.h"
-#include "images/audacious_playlist.xpm"
-
-GtkWidget *playlistwin;
-
-static GMutex *resize_mutex = NULL;
-
-static GtkWidget *playlistwin_list = NULL;
-static GtkWidget *playlistwin_shade, *playlistwin_close;
-
-static gboolean playlistwin_hint_flag = FALSE;
-
-static GtkWidget *playlistwin_slider;
-static GtkWidget *playlistwin_time_min, *playlistwin_time_sec;
-static GtkWidget *playlistwin_info, *playlistwin_sinfo;
-static GtkWidget *playlistwin_srew, *playlistwin_splay;
-static GtkWidget *playlistwin_spause, *playlistwin_sstop;
-static GtkWidget *playlistwin_sfwd, *playlistwin_seject;
-static GtkWidget *playlistwin_sscroll_up, *playlistwin_sscroll_down;
-
-static void playlistwin_select_search_cbt_cb(GtkWidget *called_cbt,
-                                             gpointer other_cbt);
-static gboolean playlistwin_select_search_kp_cb(GtkWidget *entry,
-                                                GdkEventKey *event,
-                                                gpointer searchdlg_win);
-
-static gboolean playlistwin_resizing = FALSE;
-static gint playlistwin_resize_x, playlistwin_resize_y;
-
-gboolean
-playlistwin_is_shaded(void)
-{
-    return cfg.playlist_shaded;
-}
-
-gint
-playlistwin_get_width(void)
-{
-    cfg.playlist_width /= PLAYLISTWIN_WIDTH_SNAP;
-    cfg.playlist_width *= PLAYLISTWIN_WIDTH_SNAP;
-    return cfg.playlist_width;
-}
-
-gint
-playlistwin_get_height_unshaded(void)
-{
-    cfg.playlist_height /= PLAYLISTWIN_HEIGHT_SNAP;
-    cfg.playlist_height *= PLAYLISTWIN_HEIGHT_SNAP;
-    return cfg.playlist_height;
-}
-
-gint
-playlistwin_get_height_shaded(void)
-{
-    return PLAYLISTWIN_SHADED_HEIGHT;
-}
-
-gint
-playlistwin_get_height(void)
-{
-    if (playlistwin_is_shaded())
-        return playlistwin_get_height_shaded();
-    else
-        return playlistwin_get_height_unshaded();
-}
-
-static void
-playlistwin_update_info(Playlist *playlist)
-{
-    gchar *text, *sel_text, *tot_text;
-    gulong selection, total;
-    gboolean selection_more, total_more;
-
-    playlist_get_total_time(playlist, &total, &selection, &total_more, &selection_more);
-
-    if (selection > 0 || (selection == 0 && !selection_more)) {
-        if (selection > 3600)
-            sel_text =
-                g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", selection / 3600,
-                                (selection / 60) % 60, selection % 60,
-                                (selection_more ? "+" : ""));
-        else
-            sel_text =
-                g_strdup_printf("%lu:%-2.2lu%s", selection / 60,
-                                selection % 60, (selection_more ? "+" : ""));
-    }
-    else
-        sel_text = g_strdup("?");
-    if (total > 0 || (total == 0 && !total_more)) {
-        if (total > 3600)
-            tot_text =
-                g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", total / 3600,
-                                (total / 60) % 60, total % 60,
-                                total_more ? "+" : "");
-        else
-            tot_text =
-                g_strdup_printf("%lu:%-2.2lu%s", total / 60, total % 60,
-                                total_more ? "+" : "");
-    }
-    else
-        tot_text = g_strdup("?");
-    text = g_strconcat(sel_text, "/", tot_text, NULL);
-    ui_skinned_textbox_set_text(playlistwin_info, text ? text : "");
-    g_free(text);
-    g_free(tot_text);
-    g_free(sel_text);
-}
-
-static void
-playlistwin_update_sinfo(Playlist *playlist)
-{
-    gchar *posstr, *timestr, *title, *info;
-    gint pos, time;
-
-    pos = playlist_get_position(playlist);
-    title = playlist_get_songtitle(playlist, pos);
-
-    if (!title) {
-        ui_skinned_textbox_set_text(playlistwin_sinfo, "");
-        return;
-    }
-
-    convert_title_text(title);
-
-    time = playlist_get_songtime(playlist, pos);
-
-    if (cfg.show_numbers_in_pl)
-        posstr = g_strdup_printf("%d. ", pos + 1);
-    else
-        posstr = g_strdup("");
-
-    if (time != -1) {
-        timestr = g_strdup_printf(" (%d:%-2.2d)", time / 60000,
-                                      (time / 1000) % 60);
-    }
-    else
-        timestr = g_strdup("");
-
-    info = g_strdup_printf("%s%s%s", posstr, title, timestr);
-
-    g_free(posstr);
-    g_free(title);
-    g_free(timestr);
-
-    ui_skinned_textbox_set_text(playlistwin_sinfo, info ? info : "");
-    g_free(info);
-}
-
-gboolean
-playlistwin_item_visible(gint index)
-{
-    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), FALSE);
-
-    if (index >= UI_SKINNED_PLAYLIST(playlistwin_list)->first &&
-        index < (UI_SKINNED_PLAYLIST(playlistwin_list)->first + UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible) ) {
-        return TRUE;
-    }
-    return FALSE;
-}
-
-gint
-playlistwin_list_get_visible_count(void)
-{
-    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1);
-
-    return UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible;
-}
-
-gint
-playlistwin_list_get_first(void)
-{
-    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1);
-
-    return UI_SKINNED_PLAYLIST(playlistwin_list)->first;
-}
-
-gint
-playlistwin_get_toprow(void)
-{
-    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), -1);
-
-    return (UI_SKINNED_PLAYLIST(playlistwin_list)->first);
-}
-
-void
-playlistwin_set_toprow(gint toprow)
-{
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list))
-        UI_SKINNED_PLAYLIST(playlistwin_list)->first = toprow;
-    g_cond_signal(cond_scan);
-    playlistwin_update_list(playlist_get_active());
-}
-
-void
-playlistwin_update_list(Playlist *playlist)
-{
-    /* this can happen early on. just bail gracefully. */
-    g_return_if_fail(playlistwin_list);
-
-    playlistwin_update_info(playlist);
-    playlistwin_update_sinfo(playlist);
-    gtk_widget_queue_draw(playlistwin_list);
-    gtk_widget_queue_draw(playlistwin_slider);
-}
-
-static void
-playlistwin_set_geometry_hints(gboolean shaded)
-{
-    GdkGeometry geometry;
-    GdkWindowHints mask;
-
-    geometry.min_width = PLAYLISTWIN_MIN_WIDTH;
-    geometry.max_width = G_MAXUINT16;
-
-    geometry.width_inc = PLAYLISTWIN_WIDTH_SNAP;
-    geometry.height_inc = PLAYLISTWIN_HEIGHT_SNAP;
-
-    if (shaded) {
-        geometry.min_height = PLAYLISTWIN_SHADED_HEIGHT;
-        geometry.max_height = PLAYLISTWIN_SHADED_HEIGHT;
-        geometry.base_height = PLAYLISTWIN_SHADED_HEIGHT;
-    }
-    else {
-        geometry.min_height = PLAYLISTWIN_MIN_HEIGHT;
-        geometry.max_height = G_MAXUINT16;
-    }
-
-    mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_RESIZE_INC;
-
-    gtk_window_set_geometry_hints(GTK_WINDOW(playlistwin),
-                                  playlistwin, &geometry, mask);
-}
-
-void
-playlistwin_set_sinfo_font(gchar *font)
-{
-    gchar *tmp = NULL, *tmp2 = NULL;
-
-    g_return_if_fail(font);
-    AUDDBG("Attempt to set font \"%s\"\n", font);
-
-    tmp = g_strdup(font);
-    g_return_if_fail(tmp);
-
-    *strrchr(tmp, ' ') = '\0';
-    tmp2 = g_strdup_printf("%s 8", tmp);
-    g_return_if_fail(tmp2);
-
-    ui_skinned_textbox_set_xfont(playlistwin_sinfo, !cfg.mainwin_use_bitmapfont, tmp2);
-
-    g_free(tmp);
-    g_free(tmp2);
-}
-
-void
-playlistwin_set_sinfo_scroll(gboolean scroll)
-{
-    if(playlistwin_is_shaded())
-        ui_skinned_textbox_set_scroll(playlistwin_sinfo, cfg.autoscroll);
-    else
-        ui_skinned_textbox_set_scroll(playlistwin_sinfo, FALSE);
-}
-
-void
-playlistwin_set_shade(gboolean shaded)
-{
-    cfg.playlist_shaded = shaded;
-
-    if (shaded) {
-        playlistwin_set_sinfo_font(cfg.playlist_font);
-        playlistwin_set_sinfo_scroll(cfg.autoscroll);
-        gtk_widget_show(playlistwin_sinfo);
-        ui_skinned_set_push_button_data(playlistwin_shade, 128, 45, 150, 42);
-        ui_skinned_set_push_button_data(playlistwin_close, 138, 45, -1, -1);
-    }
-    else {
-        gtk_widget_hide(playlistwin_sinfo);
-        playlistwin_set_sinfo_scroll(FALSE);
-        ui_skinned_set_push_button_data(playlistwin_shade, 157, 3, 62, 42);
-        ui_skinned_set_push_button_data(playlistwin_close, 167, 3, -1, -1);
-    }
-
-    dock_shade(get_dock_window_list(), GTK_WINDOW(playlistwin),
-               playlistwin_get_height());
-
-    playlistwin_set_geometry_hints(cfg.playlist_shaded);
-
-    gtk_window_resize(GTK_WINDOW(playlistwin),
-                      playlistwin_get_width(),
-                      playlistwin_get_height());
-}
-
-static void
-playlistwin_set_shade_menu(gboolean shaded)
-{
-    GtkAction *action = gtk_action_group_get_action(
-      toggleaction_group_others , "roll up playlist editor" );
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded );
-
-    playlistwin_set_shade(shaded);
-    playlistwin_update_list(playlist_get_active());
-}
-
-void
-playlistwin_shade_toggle(void)
-{
-    playlistwin_set_shade_menu(!cfg.playlist_shaded);
-}
-
-static gboolean
-playlistwin_release(GtkWidget * widget,
-                    GdkEventButton * event,
-                    gpointer callback_data)
-{
-    playlistwin_resizing = FALSE;
-    return FALSE;
-}
-
-void
-playlistwin_scroll(gint num)
-{
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list))
-        UI_SKINNED_PLAYLIST(playlistwin_list)->first += num;
-    playlistwin_update_list(playlist_get_active());
-}
-
-void
-playlistwin_scroll_up_pushed(void)
-{
-    playlistwin_scroll(-3);
-}
-
-void
-playlistwin_scroll_down_pushed(void)
-{
-    playlistwin_scroll(3);
-}
-
-static void
-playlistwin_select_all(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_select_all(playlist, TRUE);
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
-        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = 0;
-        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = 0;
-        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_max = playlist_get_length(playlist) - 1;
-    }
-    playlistwin_update_list(playlist);
-}
-
-static void
-playlistwin_select_none(void)
-{
-    playlist_select_all(playlist_get_active(), FALSE);
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
-        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = -1;
-        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = -1;
-    }
-    playlistwin_update_list(playlist_get_active());
-}
-
-static void
-playlistwin_select_search(void)
-{
-    Playlist *playlist = playlist_get_active();
-    GtkWidget *searchdlg_win, *searchdlg_table;
-    GtkWidget *searchdlg_hbox, *searchdlg_logo, *searchdlg_helptext;
-    GtkWidget *searchdlg_entry_title, *searchdlg_label_title;
-    GtkWidget *searchdlg_entry_album, *searchdlg_label_album;
-    GtkWidget *searchdlg_entry_file_name, *searchdlg_label_file_name;
-    GtkWidget *searchdlg_entry_performer, *searchdlg_label_performer;
-    GtkWidget *searchdlg_checkbt_clearprevsel;
-    GtkWidget *searchdlg_checkbt_newplaylist;
-    GtkWidget *searchdlg_checkbt_autoenqueue;
-    gint result;
-
-    /* create dialog */
-    searchdlg_win = gtk_dialog_new_with_buttons(
-      _("Search entries in active playlist") , GTK_WINDOW(mainwin) ,
-      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT ,
-      GTK_STOCK_CANCEL , GTK_RESPONSE_REJECT , GTK_STOCK_OK , GTK_RESPONSE_ACCEPT , NULL );
-    gtk_window_set_position(GTK_WINDOW(searchdlg_win), GTK_WIN_POS_CENTER);
-
-    /* help text and logo */
-    searchdlg_hbox = gtk_hbox_new( FALSE , 4 );
-    searchdlg_logo = gtk_image_new_from_stock( GTK_STOCK_FIND , GTK_ICON_SIZE_DIALOG );
-    searchdlg_helptext = gtk_label_new( _("Select entries in playlist by filling one or more "
-      "fields. Fields use regular expressions syntax, case-insensitive. If you don't know how "
-      "regular expressions work, simply insert a literal portion of what you're searching for.") );
-    gtk_label_set_line_wrap( GTK_LABEL(searchdlg_helptext) , TRUE );
-    gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_logo , FALSE , FALSE , 0 );
-    gtk_box_pack_start( GTK_BOX(searchdlg_hbox) , searchdlg_helptext , FALSE , FALSE , 0 );
-
-    /* title */
-    searchdlg_label_title = gtk_label_new( _("Title: ") );
-    searchdlg_entry_title = gtk_entry_new();
-    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_title) , 0 , 0.5 );
-    g_signal_connect( G_OBJECT(searchdlg_entry_title) , "key-press-event" ,
-      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
-    /* album */
-    searchdlg_label_album= gtk_label_new( _("Album: ") );
-    searchdlg_entry_album= gtk_entry_new();
-    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_album) , 0 , 0.5 );
-    g_signal_connect( G_OBJECT(searchdlg_entry_album) , "key-press-event" ,
-      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
-    /* artist */
-    searchdlg_label_performer = gtk_label_new( _("Artist: ") );
-    searchdlg_entry_performer = gtk_entry_new();
-    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_performer) , 0 , 0.5 );
-    g_signal_connect( G_OBJECT(searchdlg_entry_performer) , "key-press-event" ,
-      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
-    /* file name */
-    searchdlg_label_file_name = gtk_label_new( _("Filename: ") );
-    searchdlg_entry_file_name = gtk_entry_new();
-    gtk_misc_set_alignment( GTK_MISC(searchdlg_label_file_name) , 0 , 0.5 );
-    g_signal_connect( G_OBJECT(searchdlg_entry_file_name) , "key-press-event" ,
-      G_CALLBACK(playlistwin_select_search_kp_cb) , searchdlg_win );
-
-    /* some options that control behaviour */
-    searchdlg_checkbt_clearprevsel = gtk_check_button_new_with_label(
-      _("Clear previous selection before searching") );
-    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel) , TRUE );
-    searchdlg_checkbt_autoenqueue = gtk_check_button_new_with_label(
-      _("Automatically toggle queue for matching entries") );
-    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue) , FALSE );
-    searchdlg_checkbt_newplaylist = gtk_check_button_new_with_label(
-      _("Create a new playlist with matching entries") );
-    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist) , FALSE );
-    g_signal_connect( G_OBJECT(searchdlg_checkbt_autoenqueue) , "clicked" ,
-      G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_newplaylist );
-    g_signal_connect( G_OBJECT(searchdlg_checkbt_newplaylist) , "clicked" ,
-      G_CALLBACK(playlistwin_select_search_cbt_cb) , searchdlg_checkbt_autoenqueue );
-
-    /* place fields in searchdlg_table */
-    searchdlg_table = gtk_table_new( 8 , 2 , FALSE );
-    gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 0 , 8 );
-    gtk_table_set_row_spacing( GTK_TABLE(searchdlg_table) , 4 , 8 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_hbox ,
-      0 , 2 , 0 , 1 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_title ,
-      0 , 1 , 1 , 2 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_title ,
-      1 , 2 , 1 , 2 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_album,
-      0 , 1 , 2 , 3 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_album,
-      1 , 2 , 2 , 3 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_performer ,
-      0 , 1 , 3 , 4 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_performer ,
-      1 , 2 , 3 , 4 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_label_file_name ,
-      0 , 1 , 4 , 5 , GTK_FILL , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_entry_file_name ,
-      1 , 2 , 4 , 5 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 2 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_clearprevsel ,
-      0 , 2 , 5 , 6 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_autoenqueue ,
-      0 , 2 , 6 , 7 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
-    gtk_table_attach( GTK_TABLE(searchdlg_table) , searchdlg_checkbt_newplaylist ,
-      0 , 2 , 7 , 8 , GTK_FILL | GTK_EXPAND , GTK_FILL | GTK_EXPAND , 0 , 1 );
-
-    gtk_container_set_border_width( GTK_CONTAINER(searchdlg_table) , 5 );
-    gtk_container_add( GTK_CONTAINER(GTK_DIALOG(searchdlg_win)->vbox) , searchdlg_table );
-    gtk_widget_show_all( searchdlg_win );
-    result = gtk_dialog_run( GTK_DIALOG(searchdlg_win) );
-    switch(result)
-    {
-      case GTK_RESPONSE_ACCEPT:
-      {
-         gint matched_entries_num = 0;
-         /* create a TitleInput tuple with user search data */
-         Tuple *tuple = tuple_new();
-         gchar *searchdata = NULL;
-
-         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_title) );
-         AUDDBG("title=\"%s\"\n", searchdata);
-         tuple_associate_string(tuple, FIELD_TITLE, NULL, searchdata);
-
-         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_album) );
-         AUDDBG("album=\"%s\"\n", searchdata);
-         tuple_associate_string(tuple, FIELD_ALBUM, NULL, searchdata);
-
-         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_performer) );
-         AUDDBG("performer=\"%s\"\n", searchdata);
-         tuple_associate_string(tuple, FIELD_ARTIST, NULL, searchdata);
-
-         searchdata = (gchar*)gtk_entry_get_text( GTK_ENTRY(searchdlg_entry_file_name) );
-         AUDDBG("filename=\"%s\"\n", searchdata);
-         tuple_associate_string(tuple, FIELD_FILE_NAME, NULL, searchdata);
-
-         /* check if previous selection should be cleared before searching */
-         if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_clearprevsel)) == TRUE )
-             playlistwin_select_none();
-         /* now send this tuple to the real search function */
-         matched_entries_num = playlist_select_search( playlist , tuple , 0 );
-         /* we do not need the tuple and its data anymore */
-         mowgli_object_unref(tuple);
-         playlistwin_update_list(playlist_get_active());
-         /* check if a new playlist should be created after searching */
-         if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_newplaylist)) == TRUE )
-             playlist_new_from_selected();
-         /* check if matched entries should be queued */
-         else if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(searchdlg_checkbt_autoenqueue)) == TRUE )
-             playlist_queue(playlist_get_active());
-         break;
-      }
-      default:
-         break;
-    }
-    /* done here :) */
-    gtk_widget_destroy( searchdlg_win );
-}
-
-static void
-playlistwin_inverse_selection(void)
-{
-    playlist_select_invert_all(playlist_get_active());
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
-        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected = -1;
-        UI_SKINNED_PLAYLIST(playlistwin_list)->prev_min = -1;
-    }
-    playlistwin_update_list(playlist_get_active());
-}
-
-static void
-playlistwin_resize(gint width, gint height)
-{
-    gint tx, ty;
-    gint dx, dy;
-
-    g_return_if_fail(width > 0 && height > 0);
-
-    tx = (width - PLAYLISTWIN_MIN_WIDTH) / PLAYLISTWIN_WIDTH_SNAP;
-    tx = (tx * PLAYLISTWIN_WIDTH_SNAP) + PLAYLISTWIN_MIN_WIDTH;
-    if (tx < PLAYLISTWIN_MIN_WIDTH)
-        tx = PLAYLISTWIN_MIN_WIDTH;
-
-    if (!cfg.playlist_shaded)
-    {
-        ty = (height - PLAYLISTWIN_MIN_HEIGHT) / PLAYLISTWIN_HEIGHT_SNAP;
-        ty = (ty * PLAYLISTWIN_HEIGHT_SNAP) + PLAYLISTWIN_MIN_HEIGHT;
-        if (ty < PLAYLISTWIN_MIN_HEIGHT)
-            ty = PLAYLISTWIN_MIN_HEIGHT;
-    }
-    else
-        ty = cfg.playlist_height;
-
-    if (tx == cfg.playlist_width && ty == cfg.playlist_height)
-        return;
-
-    /* difference between previous size and new size */
-    dx = tx - cfg.playlist_width;
-    dy = ty - cfg.playlist_height;
-
-    cfg.playlist_width = width = tx;
-    cfg.playlist_height = height = ty;
-
-    g_mutex_lock(resize_mutex);
-    ui_skinned_playlist_resize_relative(playlistwin_list, dx, dy);
-
-    ui_skinned_playlist_slider_move_relative(playlistwin_slider, dx);
-    ui_skinned_playlist_slider_resize_relative(playlistwin_slider, dy);
-
-    playlistwin_update_sinfo(playlist_get_active());
-
-    ui_skinned_button_move_relative(playlistwin_shade, dx, 0);
-    ui_skinned_button_move_relative(playlistwin_close, dx, 0);
-    ui_skinned_textbox_move_relative(playlistwin_time_min, dx, dy);
-    ui_skinned_textbox_move_relative(playlistwin_time_sec, dx, dy);
-    ui_skinned_textbox_move_relative(playlistwin_info, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_srew, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_splay, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_spause, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_sstop, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_sfwd, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_seject, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_sscroll_up, dx, dy);
-    ui_skinned_button_move_relative(playlistwin_sscroll_down, dx, dy);
-
-    gtk_widget_set_size_request(playlistwin_sinfo, playlistwin_get_width() - 35,
-                                aud_active_skin->properties.textbox_bitmap_font_height);
-    GList *iter;
-    for (iter = GTK_FIXED (SKINNED_WINDOW(playlistwin)->fixed)->children; iter; iter = g_list_next (iter)) {
-         GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
-         GtkWidget *child = child_data->widget;
-         g_signal_emit_by_name(child, "redraw");
-    }
-    g_mutex_unlock(resize_mutex);
-}
-
-static void
-playlistwin_motion(GtkWidget * widget,
-                   GdkEventMotion * event,
-                   gpointer callback_data)
-{
-    /*
-     * GDK2's resize is broken and doesn't really play nice, so we have
-     * to do all of this stuff by hand.
-     */
-    if (playlistwin_resizing == TRUE)
-    {
-        if (event->x + playlistwin_resize_x != playlistwin_get_width() ||
-            event->y + playlistwin_resize_y != playlistwin_get_height())
-        {
-            playlistwin_resize(event->x + playlistwin_resize_x,
-                               event->y + playlistwin_resize_y);
-            gdk_window_resize(playlistwin->window,
-                              cfg.playlist_width, playlistwin_get_height());
-            gdk_flush();
-        }
-    }
-    else if (dock_is_moving(GTK_WINDOW(playlistwin)))
-        dock_move_motion(GTK_WINDOW(playlistwin), event);
-}
-
-static void
-playlistwin_show_filebrowser(void)
-{
-    run_filebrowser(FALSE);
-}
-
-static void
-playlistwin_fileinfo(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    /* Show the first selected file, or the current file if nothing is
-     * selected */
-    GList *list = playlist_get_selected(playlist);
-    if (list) {
-        ui_fileinfo_show(playlist, GPOINTER_TO_INT(list->data));
-        g_list_free(list);
-    }
-    else
-        ui_fileinfo_show_current(playlist);
-}
-
-static void
-show_playlist_save_error(GtkWindow *parent,
-                         const gchar *filename)
-{
-    GtkWidget *dialog;
-
-    g_return_if_fail(GTK_IS_WINDOW(parent));
-    g_return_if_fail(filename);
-
-    dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
-                                    GTK_DIALOG_DESTROY_WITH_PARENT,
-                                    GTK_MESSAGE_ERROR,
-                                    GTK_BUTTONS_OK,
-                                    _("Error writing playlist \"%s\": %s"),
-                                    filename, strerror(errno));
-
-    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
-    gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_widget_destroy(dialog);
-}
-
-static gboolean
-show_playlist_overwrite_prompt(GtkWindow * parent,
-                               const gchar * filename)
-{
-    GtkWidget *dialog;
-    gint result;
-
-    g_return_val_if_fail(GTK_IS_WINDOW(parent), FALSE);
-    g_return_val_if_fail(filename != NULL, FALSE);
-
-    dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
-                                    GTK_DIALOG_DESTROY_WITH_PARENT,
-                                    GTK_MESSAGE_QUESTION,
-                                    GTK_BUTTONS_YES_NO,
-                                    _("%s already exist. Continue?"),
-                                    filename);
-
-    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
-    result = gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_widget_destroy(dialog);
-
-    return (result == GTK_RESPONSE_YES);
-}
-
-static void
-show_playlist_save_format_error(GtkWindow * parent,
-                                const gchar * filename)
-{
-    const gchar *markup =
-        N_("<b><big>Unable to save playlist.</big></b>\n\n"
-           "Unknown file type for '%s'.\n");
-
-    GtkWidget *dialog;
-
-    g_return_if_fail(GTK_IS_WINDOW(parent));
-    g_return_if_fail(filename != NULL);
-
-    dialog =
-        gtk_message_dialog_new_with_markup(GTK_WINDOW(parent),
-                                           GTK_DIALOG_DESTROY_WITH_PARENT,
-                                           GTK_MESSAGE_ERROR,
-                                           GTK_BUTTONS_OK,
-                                           _(markup),
-                                           filename);
-
-    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
-    gtk_dialog_run(GTK_DIALOG(dialog));
-    gtk_widget_destroy(dialog);
-}
-
-static void
-playlistwin_save_playlist(const gchar * filename)
-{
-    PlaylistContainer *plc;
-    gchar *ext = strrchr(filename, '.') + 1;
-
-    plc = playlist_container_find(ext);
-    if (plc == NULL) {
-        show_playlist_save_format_error(GTK_WINDOW(playlistwin), filename);
-        return;
-    }
-
-    str_replace_in(&cfg.playlist_path, g_path_get_dirname(filename));
-
-    if (g_file_test(filename, G_FILE_TEST_IS_REGULAR))
-        if (!show_playlist_overwrite_prompt(GTK_WINDOW(playlistwin), filename))
-            return;
-
-    if (!playlist_save(playlist_get_active(), filename))
-        show_playlist_save_error(GTK_WINDOW(playlistwin), filename);
-}
-
-static void
-playlistwin_load_playlist(const gchar * filename)
-{
-    const gchar *title;
-    Playlist *playlist = playlist_get_active();
-
-    g_return_if_fail(filename != NULL);
-
-    str_replace_in(&cfg.playlist_path, g_path_get_dirname(filename));
-
-    playlist_clear(playlist);
-    mainwin_clear_song_info();
-
-    playlist_load(playlist, filename);
-    title = playlist_get_current_name(playlist);
-    if(!title || !title[0])
-        playlist_set_current_name(playlist, filename);
-}
-
-static gchar *
-playlist_file_selection_load(const gchar * title,
-                        const gchar * default_filename)
-{
-    GtkWidget *dialog;
-    gchar *filename;
-
-    g_return_val_if_fail(title != NULL, NULL);
-
-    dialog = make_filebrowser(title, FALSE);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), cfg.playlist_path);
-    if (default_filename)
-        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), default_filename);
-    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); /* centering */
-
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
-    else
-        filename = NULL;
-
-    gtk_widget_destroy(dialog);
-    return filename;
-}
-
-static void
-on_static_toggle(GtkToggleButton *button, gpointer data)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist->attribute =
-        gtk_toggle_button_get_active(button) ?
-        playlist->attribute | PLAYLIST_STATIC :
-        playlist->attribute & ~PLAYLIST_STATIC;
-}
-
-static void
-on_relative_toggle(GtkToggleButton *button, gpointer data)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist->attribute =
-        gtk_toggle_button_get_active(button) ?
-        playlist->attribute | PLAYLIST_USE_RELATIVE :
-        playlist->attribute & ~PLAYLIST_USE_RELATIVE;
-}
-
-static gchar *
-playlist_file_selection_save(const gchar * title,
-                        const gchar * default_filename)
-{
-    GtkWidget *dialog;
-    gchar *filename;
-    GtkWidget *hbox;
-    GtkWidget *toggle, *toggle2;
-
-    g_return_val_if_fail(title != NULL, NULL);
-
-    dialog = make_filebrowser(title, TRUE);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), cfg.playlist_path);
-    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), default_filename);
-
-    hbox = gtk_hbox_new(FALSE, 5);
-
-    /* static playlist */
-    toggle = gtk_check_button_new_with_label(_("Save as Static Playlist"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle),
-                                 (playlist_get_active()->attribute & PLAYLIST_STATIC) ? TRUE : FALSE);
-    g_signal_connect(G_OBJECT(toggle), "toggled", G_CALLBACK(on_static_toggle), dialog);
-    gtk_box_pack_start(GTK_BOX(hbox), toggle, FALSE, FALSE, 0);
-
-    /* use relative path */
-    toggle2 = gtk_check_button_new_with_label(_("Use Relative Path"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle2),
-                                 (playlist_get_active()->attribute & PLAYLIST_USE_RELATIVE) ? TRUE : FALSE);
-    g_signal_connect(G_OBJECT(toggle2), "toggled", G_CALLBACK(on_relative_toggle), dialog);
-    gtk_box_pack_start(GTK_BOX(hbox), toggle2, FALSE, FALSE, 0);
-
-    gtk_widget_show_all(hbox);
-    gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), hbox);
-
-    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
-    else
-        filename = NULL;
-
-    gtk_widget_destroy(dialog);
-    return filename;
-}
-
-void
-playlistwin_select_playlist_to_load(const gchar * default_filename)
-{
-    gchar *filename =
-        playlist_file_selection_load(_("Load Playlist"), default_filename);
-
-    if (filename) {
-        playlistwin_load_playlist(filename);
-        g_free(filename);
-    }
-}
-
-static void
-playlistwin_select_playlist_to_save(const gchar * default_filename)
-{
-    gchar *dot = NULL, *basename = NULL;
-    gchar *filename =
-        playlist_file_selection_save(_("Save Playlist"), default_filename);
-
-    if (filename) {
-        /* Default extension */
-        basename = g_path_get_basename(filename);
-        dot = strrchr(basename, '.');
-        if( dot == NULL || dot == basename) {
-            gchar *oldname = filename;
-#ifdef HAVE_XSPF_PLAYLIST
-            filename = g_strconcat(oldname, ".xspf", NULL);
-#else
-            filename = g_strconcat(oldname, ".m3u", NULL);
-#endif
-            g_free(oldname);
-        }
-        g_free(basename);
-
-        playlistwin_save_playlist(filename);
-        g_free(filename);
-    }
-}
-
-#define REGION_L(x1,x2,y1,y2)                   \
-    (event->x >= (x1) && event->x < (x2) &&     \
-     event->y >= cfg.playlist_height - (y1) &&  \
-     event->y < cfg.playlist_height - (y2))
-
-#define REGION_R(x1,x2,y1,y2)                      \
-    (event->x >= playlistwin_get_width() - (x1) && \
-     event->x < playlistwin_get_width() - (x2) &&  \
-     event->y >= cfg.playlist_height - (y1) &&     \
-     event->y < cfg.playlist_height - (y2))
-
-static void
-playlistwin_scrolled(GtkWidget * widget,
-                     GdkEventScroll * event,
-                     gpointer callback_data)
-{
-    if (event->direction == GDK_SCROLL_DOWN)
-        playlistwin_scroll(cfg.scroll_pl_by);
-
-    if (event->direction == GDK_SCROLL_UP)
-        playlistwin_scroll(-cfg.scroll_pl_by);
-
-    g_cond_signal(cond_scan);
-}
-
-static gboolean
-playlistwin_press(GtkWidget * widget,
-                  GdkEventButton * event,
-                  gpointer callback_data)
-{
-    gint xpos, ypos;
-    GtkRequisition req;
-
-    gtk_window_get_position(GTK_WINDOW(playlistwin), &xpos, &ypos);
-
-    if (event->button == 1 && !cfg.show_wm_decorations &&
-        ((!cfg.playlist_shaded &&
-          event->x > playlistwin_get_width() - 20 &&
-          event->y > cfg.playlist_height - 20) ||
-         (cfg.playlist_shaded &&
-          event->x >= playlistwin_get_width() - 31 &&
-          event->x < playlistwin_get_width() - 22))) {
-
-        if (event->type != GDK_2BUTTON_PRESS &&
-            event->type != GDK_3BUTTON_PRESS) {
-            playlistwin_resizing = TRUE;
-            playlistwin_resize_x = cfg.playlist_width - event->x;
-            playlistwin_resize_y = cfg.playlist_height - event->y;
-        }
-    }
-    else if (event->button == 1 && REGION_L(12, 37, 29, 11)) {
-        /* ADD button menu */
-        gtk_widget_size_request(playlistwin_pladd_menu, &req);
-        ui_manager_popup_menu_show(GTK_MENU(playlistwin_pladd_menu),
-                   xpos + 12,
-                   (ypos + playlistwin_get_height()) - 8 - req.height,
-                   event->button,
-                   event->time);
-    }
-    else if (event->button == 1 && REGION_L(41, 66, 29, 11)) {
-        /* SUB button menu */
-        gtk_widget_size_request(playlistwin_pldel_menu, &req);
-        ui_manager_popup_menu_show(GTK_MENU(playlistwin_pldel_menu),
-                   xpos + 40,
-                   (ypos + playlistwin_get_height()) - 8 - req.height,
-                   event->button,
-                   event->time);
-    }
-    else if (event->button == 1 && REGION_L(70, 95, 29, 11)) {
-        /* SEL button menu */
-        gtk_widget_size_request(playlistwin_plsel_menu, &req);
-        ui_manager_popup_menu_show(GTK_MENU(playlistwin_plsel_menu),
-                   xpos + 68,
-                   (ypos + playlistwin_get_height()) - 8 - req.height,
-                   event->button,
-                   event->time);
-    }
-    else if (event->button == 1 && REGION_L(99, 124, 29, 11)) {
-        /* MISC button menu */
-        gtk_widget_size_request(playlistwin_plsort_menu, &req);
-        ui_manager_popup_menu_show(GTK_MENU(playlistwin_plsort_menu),
-                   xpos + 100,
-                   (ypos + playlistwin_get_height()) - 8 - req.height,
-                   event->button,
-                   event->time);
-    }
-    else if (event->button == 1 && REGION_R(46, 23, 29, 11)) {
-        /* LIST button menu */
-        gtk_widget_size_request(playlistwin_pllist_menu, &req);
-        ui_manager_popup_menu_show(GTK_MENU(playlistwin_pllist_menu),
-                   xpos + playlistwin_get_width() - req.width - 12,
-                   (ypos + playlistwin_get_height()) - 8 - req.height,
-                   event->button,
-                   event->time);
-    }
-    else if (event->button == 1 && event->type == GDK_BUTTON_PRESS &&
-             (cfg.easy_move || event->y < 14))
-    {
-        return FALSE;
-    }
-    else if (event->button == 1 && event->type == GDK_2BUTTON_PRESS
-             && event->y < 14) {
-        /* double click on title bar */
-        playlistwin_shade_toggle();
-        if (dock_is_moving(GTK_WINDOW(playlistwin)))
-            dock_move_release(GTK_WINDOW(playlistwin));
-        return TRUE;
-    }
-    else if (event->button == 3) {
-        /*
-         * Pop up the main menu a few pixels down to avoid
-         * anything to be selected initially.
-         */
-        ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), event->x_root,
-                                event->y_root + 2, 3, event->time);
-    }
-
-    return TRUE;
-}
-
-static gboolean
-playlistwin_delete(GtkWidget * w, gpointer data)
-{
-    playlistwin_hide();
-    return TRUE;
-}
-
-static gboolean
-playlistwin_keypress_up_down_handler(UiSkinnedPlaylist * pl,
-                                     gboolean up, guint state)
-{
-    Playlist *playlist = playlist_get_active();
-    if ((!(pl->prev_selected || pl->first) && up) ||
-       ((pl->prev_selected >= playlist_get_length(playlist) - 1) && !up))
-         return FALSE;
-
-    if ((state & GDK_MOD1_MASK) && (state & GDK_SHIFT_MASK))
-        return FALSE;
-    if (!(state & GDK_MOD1_MASK))
-        playlist_select_all(playlist, FALSE);
-
-    if (pl->prev_selected == -1 ||
-        (!playlistwin_item_visible(pl->prev_selected) &&
-         !(state & GDK_SHIFT_MASK && pl->prev_min != -1))) {
-        pl->prev_selected = pl->first;
-    }
-    else if (state & GDK_SHIFT_MASK) {
-        if (pl->prev_min == -1) {
-            pl->prev_max = pl->prev_selected;
-            pl->prev_min = pl->prev_selected;
-        }
-        pl->prev_max += (up ? -1 : 1);
-        pl->prev_max =
-            CLAMP(pl->prev_max, 0, playlist_get_length(playlist) - 1);
-
-        pl->first = MIN(pl->first, pl->prev_max);
-        pl->first = MAX(pl->first, pl->prev_max -
-                           pl->num_visible + 1);
-        playlist_select_range(playlist, pl->prev_min, pl->prev_max, TRUE);
-        return TRUE;
-    }
-    else if (state & GDK_MOD1_MASK) {
-        if (up)
-            ui_skinned_playlist_move_up(pl);
-        else
-            ui_skinned_playlist_move_down(pl);
-        if (pl->prev_min < pl->first)
-            pl->first = pl->prev_min;
-        else if (pl->prev_max >= (pl->first + pl->num_visible))
-            pl->first = pl->prev_max - pl->num_visible + 1;
-        return TRUE;
-    }
-    else if (up)
-        pl->prev_selected--;
-    else
-        pl->prev_selected++;
-
-    pl->prev_selected =
-        CLAMP(pl->prev_selected, 0, playlist_get_length(playlist) - 1);
-
-    if (pl->prev_selected < pl->first)
-        pl->first--;
-    else if (pl->prev_selected >= (pl->first + pl->num_visible))
-        pl->first++;
-
-    playlist_select_range(playlist, pl->prev_selected, pl->prev_selected, TRUE);
-    pl->prev_min = -1;
-
-    return TRUE;
-}
-
-/* FIXME: Handle the keys through menu */
-
-static gboolean
-playlistwin_keypress(GtkWidget * w, GdkEventKey * event, gpointer data)
-{
-    g_return_val_if_fail(UI_SKINNED_IS_PLAYLIST(playlistwin_list), FALSE);
-    Playlist *playlist = playlist_get_active();
-
-    guint keyval;
-    gboolean refresh = FALSE;
-    guint cur_pos;
-
-    if (cfg.playlist_shaded)
-        return FALSE;
-
-    switch (keyval = event->keyval) {
-    case GDK_KP_Up:
-    case GDK_KP_Down:
-    case GDK_Up:
-    case GDK_Down:
-        refresh = playlistwin_keypress_up_down_handler(UI_SKINNED_PLAYLIST(playlistwin_list),
-                                                       keyval == GDK_Up
-                                                       || keyval == GDK_KP_Up,
-                                                       event->state);
-        break;
-    case GDK_Page_Up:
-        playlistwin_scroll(-UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible);
-        refresh = TRUE;
-        break;
-    case GDK_Page_Down:
-        playlistwin_scroll(UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible);
-        refresh = TRUE;
-        break;
-    case GDK_Home:
-        UI_SKINNED_PLAYLIST(playlistwin_list)->first = 0;
-        refresh = TRUE;
-        break;
-    case GDK_End:
-        UI_SKINNED_PLAYLIST(playlistwin_list)->first =
-            playlist_get_length(playlist) - UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible;
-        refresh = TRUE;
-        break;
-    case GDK_Return:
-        if (UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected > -1
-            && playlistwin_item_visible(UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected)) {
-            playlist_set_position(playlist, UI_SKINNED_PLAYLIST(playlistwin_list)->prev_selected);
-            if (!playback_get_playing())
-                playback_initiate();
-        }
-        refresh = TRUE;
-        break;
-    case GDK_3:
-        if (event->state & GDK_CONTROL_MASK)
-            playlistwin_fileinfo();
-        break;
-    case GDK_Delete:
-        if (event->state & GDK_CONTROL_MASK)
-            playlist_delete(playlist, TRUE);
-        else
-            playlist_delete(playlist, FALSE);
-        break;
-    case GDK_Insert:
-        if (event->state & GDK_MOD1_MASK)
-            mainwin_show_add_url_window();
-        else
-            playlistwin_show_filebrowser();
-        break;
-    case GDK_Left:
-    case GDK_KP_Left:
-    case GDK_KP_7:
-        if (playlist_get_current_length(playlist) != -1)
-            playback_seek(CLAMP
-                              (playback_get_time() - 5000, 0,
-                              playlist_get_current_length(playlist)) / 1000);
-        break;
-    case GDK_Right:
-    case GDK_KP_Right:
-    case GDK_KP_9:
-        if (playlist_get_current_length(playlist) != -1)
-            playback_seek(CLAMP
-                              (playback_get_time() + 5000, 0,
-                              playlist_get_current_length(playlist)) / 1000);
-        break;
-    case GDK_KP_4:
-        playlist_prev(playlist);
-        break;
-    case GDK_KP_6:
-        playlist_next(playlist);
-        break;
-
-    case GDK_Escape:
-        mainwin_minimize_cb();
-        break;
-    case GDK_Tab:
-        if (event->state & GDK_CONTROL_MASK) {
-            if (cfg.player_visible)
-                gtk_window_present(GTK_WINDOW(mainwin));
-            else if (cfg.equalizer_visible)
-                gtk_window_present(GTK_WINDOW(equalizerwin));
-        }
-        break;
-    case GDK_space:
-        cur_pos=playlist_get_position(playlist);
-        UI_SKINNED_PLAYLIST(playlistwin_list)->first =
-            cur_pos - (UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible >> 1);
-        refresh = TRUE;
-        break;
-    default:
-        return FALSE;
-    }
-
-    if (refresh) {
-        g_cond_signal(cond_scan);
-        playlistwin_update_list(playlist_get_active());
-    }
-
-    return TRUE;
-}
-
-void
-playlistwin_hide_timer(void)
-{
-    ui_skinned_textbox_set_text(playlistwin_time_min, "   ");
-    ui_skinned_textbox_set_text(playlistwin_time_sec, "  ");
-}
-
-void
-playlistwin_set_time(gint time, gint length, TimerMode mode)
-{
-    gchar *text, sign;
-
-    if (mode == TIMER_REMAINING && length != -1) {
-        time = length - time;
-        sign = '-';
-    }
-    else
-        sign = ' ';
-
-    time /= 1000;
-
-    if (time < 0)
-        time = 0;
-    if (time > 99 * 60)
-        time /= 60;
-
-    text = g_strdup_printf("%c%-2.2d", sign, time / 60);
-    ui_skinned_textbox_set_text(playlistwin_time_min, text);
-    g_free(text);
-
-    text = g_strdup_printf("%-2.2d", time % 60);
-    ui_skinned_textbox_set_text(playlistwin_time_sec, text);
-    g_free(text);
-}
-
-static void
-playlistwin_drag_motion(GtkWidget * widget,
-                        GdkDragContext * context,
-                        gint x, gint y,
-                        GtkSelectionData * selection_data,
-                        guint info, guint time, gpointer user_data)
-{
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list)) {
-        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion = TRUE;
-        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion_x = x;
-        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion_y = y;
-    }
-    playlistwin_update_list(playlist_get_active());
-    playlistwin_hint_flag = TRUE;
-}
-
-static void
-playlistwin_drag_end(GtkWidget * widget,
-                     GdkDragContext * context, gpointer user_data)
-{
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list))
-        UI_SKINNED_PLAYLIST(playlistwin_list)->drag_motion = FALSE;
-    playlistwin_hint_flag = FALSE;
-    playlistwin_update_list(playlist_get_active());
-}
-
-static void
-playlistwin_drag_data_received(GtkWidget * widget,
-                               GdkDragContext * context,
-                               gint x, gint y,
-                               GtkSelectionData *
-                               selection_data, guint info,
-                               guint time, gpointer user_data)
-{
-    gint pos;
-    Playlist *playlist = playlist_get_active();
-
-    g_return_if_fail(selection_data);
-
-    if (!selection_data->data) {
-        g_message("Received no DND data!");
-        return;
-    }
-    if (UI_SKINNED_IS_PLAYLIST(playlistwin_list) &&
-        (x < playlistwin_get_width() - 20 || y < cfg.playlist_height - 38)) {
-        pos = y / UI_SKINNED_PLAYLIST(playlistwin_list)->fheight + UI_SKINNED_PLAYLIST(playlistwin_list)->first;
-
-        pos = MIN(pos, playlist_get_length(playlist));
-        playlist_ins_url(playlist, (gchar *) selection_data->data, pos);
-    }
-    else
-        playlist_add_url(playlist, (gchar *) selection_data->data);
-}
-
-static void
-local_playlist_prev(void)
-{
-    playlist_prev(playlist_get_active());
-}
-
-static void
-local_playlist_next(void)
-{
-    playlist_next(playlist_get_active());
-}
-
-static void
-playlistwin_create_widgets(void)
-{
-    /* This function creates the custom widgets used by the playlist editor */
-
-    /* text box for displaying song title in shaded mode */
-    playlistwin_sinfo = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
-                                               4, 4, playlistwin_get_width() - 35, TRUE, SKIN_TEXT);
-
-    playlistwin_set_sinfo_font(cfg.playlist_font);
-
-    playlistwin_shade = ui_skinned_button_new();
-    /* shade/unshade window push button */
-    if (cfg.playlist_shaded)
-        ui_skinned_push_button_setup(playlistwin_shade, SKINNED_WINDOW(playlistwin)->fixed,
-                                     playlistwin_get_width() - 21, 3,
-                                     9, 9, 128, 45, 150, 42, SKIN_PLEDIT);
-    else
-        ui_skinned_push_button_setup(playlistwin_shade, SKINNED_WINDOW(playlistwin)->fixed,
-                                     playlistwin_get_width() - 21, 3,
-                                     9, 9, 157, 3, 62, 42, SKIN_PLEDIT);
-
-    g_signal_connect(playlistwin_shade, "clicked", playlistwin_shade_toggle, NULL );
-
-    /* close window push button */
-    playlistwin_close = ui_skinned_button_new();
-    ui_skinned_push_button_setup(playlistwin_close, SKINNED_WINDOW(playlistwin)->fixed,
-                                 playlistwin_get_width() - 11, 3, 9, 9,
-                                 cfg.playlist_shaded ? 138 : 167,
-                                 cfg.playlist_shaded ? 45 : 3, 52, 42, SKIN_PLEDIT);
-
-    g_signal_connect(playlistwin_close, "clicked", playlistwin_hide, NULL );
-
-    /* playlist list box */
-    playlistwin_list = ui_skinned_playlist_new(SKINNED_WINDOW(playlistwin)->fixed, 12, 20,
-                             playlistwin_get_width() - 31,
-                             cfg.playlist_height - 58);
-    ui_skinned_playlist_set_font(cfg.playlist_font);
-
-    /* playlist list box slider */
-    playlistwin_slider = ui_skinned_playlist_slider_new(SKINNED_WINDOW(playlistwin)->fixed, playlistwin_get_width() - 15,
-                              20, cfg.playlist_height - 58);
-
-    /* track time (minute) */
-    playlistwin_time_min = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
-                       playlistwin_get_width() - 82,
-                       cfg.playlist_height - 15, 15, FALSE, SKIN_TEXT);
-    g_signal_connect(playlistwin_time_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    /* track time (second) */
-    playlistwin_time_sec = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
-                       playlistwin_get_width() - 64,
-                       cfg.playlist_height - 15, 10, FALSE, SKIN_TEXT);
-    g_signal_connect(playlistwin_time_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
-
-    /* playlist information (current track length / total track length) */
-    playlistwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
-                       playlistwin_get_width() - 143,
-                       cfg.playlist_height - 28, 90, FALSE, SKIN_TEXT);
-
-    /* mini play control buttons at right bottom corner */
-
-    /* rewind button */
-    playlistwin_srew = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_srew, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 144,
-                                  cfg.playlist_height - 16, 8, 7);
-    g_signal_connect(playlistwin_srew, "clicked", local_playlist_prev, NULL);
-
-    /* play button */
-    playlistwin_splay = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_splay, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 138,
-                                  cfg.playlist_height - 16, 10, 7);
-    g_signal_connect(playlistwin_splay, "clicked", mainwin_play_pushed, NULL);
-
-    /* pause button */
-    playlistwin_spause = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_spause, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 128,
-                                  cfg.playlist_height - 16, 10, 7);
-    g_signal_connect(playlistwin_spause, "clicked", playback_pause, NULL);
-
-    /* stop button */
-    playlistwin_sstop = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_sstop, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 118,
-                                  cfg.playlist_height - 16, 9, 7);
-    g_signal_connect(playlistwin_sstop, "clicked", mainwin_stop_pushed, NULL);
-
-    /* forward button */
-    playlistwin_sfwd = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_sfwd, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 109,
-                                  cfg.playlist_height - 16, 8, 7);
-    g_signal_connect(playlistwin_sfwd, "clicked", local_playlist_next, NULL);
-
-    /* eject button */
-    playlistwin_seject = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_seject, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 100,
-                                  cfg.playlist_height - 16, 9, 7);
-    g_signal_connect(playlistwin_seject, "clicked", mainwin_eject_pushed, NULL);
-
-    playlistwin_sscroll_up = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_sscroll_up, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 14,
-                                  cfg.playlist_height - 35, 8, 5);
-    g_signal_connect(playlistwin_sscroll_up, "clicked", playlistwin_scroll_up_pushed, NULL);
-
-    playlistwin_sscroll_down = ui_skinned_button_new();
-    ui_skinned_small_button_setup(playlistwin_sscroll_down, SKINNED_WINDOW(playlistwin)->fixed,
-                                  playlistwin_get_width() - 14,
-                                  cfg.playlist_height - 30, 8, 5);
-    g_signal_connect(playlistwin_sscroll_down, "clicked", playlistwin_scroll_down_pushed, NULL);
-
-    ui_playlist_evlistener_init();
-}
-
-static void
-selection_received(GtkWidget * widget,
-                   GtkSelectionData * selection_data, gpointer data)
-{
-    if (selection_data->type == GDK_SELECTION_TYPE_STRING &&
-        selection_data->length > 0)
-        playlist_add_url(playlist_get_active(), (gchar *) selection_data->data);
-}
-
-static void
-playlistwin_create_window(void)
-{
-    GdkPixbuf *icon;
-
-    playlistwin = ui_skinned_window_new("playlist");
-    gtk_window_set_title(GTK_WINDOW(playlistwin), _("Audacious Playlist Editor"));
-    gtk_window_set_role(GTK_WINDOW(playlistwin), "playlist");
-    gtk_window_set_default_size(GTK_WINDOW(playlistwin),
-                                playlistwin_get_width(),
-                                playlistwin_get_height());
-    gtk_window_set_resizable(GTK_WINDOW(playlistwin), TRUE);
-    playlistwin_set_geometry_hints(cfg.playlist_shaded);
-
-    gtk_window_set_transient_for(GTK_WINDOW(playlistwin),
-                                 GTK_WINDOW(mainwin));
-    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(playlistwin), TRUE);
-
-    icon = gdk_pixbuf_new_from_xpm_data((const gchar **) audacious_playlist_icon);
-    gtk_window_set_icon(GTK_WINDOW(playlistwin), icon);
-    g_object_unref(icon);
-
-    if (cfg.playlist_x != -1 && cfg.save_window_position)
-        gtk_window_move(GTK_WINDOW(playlistwin),
-                        cfg.playlist_x, cfg.playlist_y);
-
-    gtk_widget_add_events(playlistwin, GDK_POINTER_MOTION_MASK |
-                          GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK |
-                          GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
-                          GDK_SCROLL_MASK | GDK_VISIBILITY_NOTIFY_MASK);
-    gtk_widget_realize(playlistwin);
-
-    g_signal_connect(playlistwin, "delete_event",
-                     G_CALLBACK(playlistwin_delete), NULL);
-    g_signal_connect(playlistwin, "button_press_event",
-                     G_CALLBACK(playlistwin_press), NULL);
-    g_signal_connect(playlistwin, "button_release_event",
-                     G_CALLBACK(playlistwin_release), NULL);
-    g_signal_connect(playlistwin, "scroll_event",
-                     G_CALLBACK(playlistwin_scrolled), NULL);
-    g_signal_connect(playlistwin, "motion_notify_event",
-                     G_CALLBACK(playlistwin_motion), NULL);
-
-    aud_drag_dest_set(playlistwin);
-
-    /* DnD stuff */
-    g_signal_connect(playlistwin, "drag-leave",
-                     G_CALLBACK(playlistwin_drag_end), NULL);
-    g_signal_connect(playlistwin, "drag-data-delete",
-                     G_CALLBACK(playlistwin_drag_end), NULL);
-    g_signal_connect(playlistwin, "drag-end",
-                     G_CALLBACK(playlistwin_drag_end), NULL);
-    g_signal_connect(playlistwin, "drag-drop",
-                     G_CALLBACK(playlistwin_drag_end), NULL);
-    g_signal_connect(playlistwin, "drag-data-received",
-                     G_CALLBACK(playlistwin_drag_data_received), NULL);
-    g_signal_connect(playlistwin, "drag-motion",
-                     G_CALLBACK(playlistwin_drag_motion), NULL);
-
-    g_signal_connect(playlistwin, "key_press_event",
-                     G_CALLBACK(playlistwin_keypress), NULL);
-    g_signal_connect(playlistwin, "selection_received",
-                     G_CALLBACK(selection_received), NULL);
-}
-
-void
-playlistwin_create(void)
-{
-    resize_mutex = g_mutex_new();
-    playlistwin_create_window();
-
-    playlistwin_create_widgets();
-    playlistwin_update_info(playlist_get_active());
-
-    gtk_window_add_accel_group(GTK_WINDOW(playlistwin), ui_manager_get_accel_group());
-}
-
-
-void
-playlistwin_show(void)
-{
-    gtk_window_move(GTK_WINDOW(playlistwin), cfg.playlist_x, cfg.playlist_y);
-    GtkAction *action = gtk_action_group_get_action(
-      toggleaction_group_others , "show playlist editor" );
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , TRUE );
-
-    cfg.playlist_visible = TRUE;
-    UI_SKINNED_BUTTON(mainwin_pl)->inside = TRUE;
-    gtk_widget_queue_draw(mainwin_pl);
-
-    playlistwin_set_toprow(0);
-    playlist_check_pos_current(playlist_get_active());
-
-    gtk_widget_show_all(playlistwin);
-    if (!cfg.playlist_shaded)
-        gtk_widget_hide(playlistwin_sinfo);
-    gtk_window_present(GTK_WINDOW(playlistwin));
-}
-
-void
-playlistwin_hide(void)
-{
-    GtkAction *action = gtk_action_group_get_action(
-      toggleaction_group_others , "show playlist editor" );
-    gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , FALSE );
-
-    gtk_widget_hide(playlistwin);
-    cfg.playlist_visible = FALSE;
-    UI_SKINNED_BUTTON(mainwin_pl)->inside = FALSE;
-    gtk_widget_queue_draw(mainwin_pl);
-
-    if ( cfg.player_visible )
-    {
-      gtk_window_present(GTK_WINDOW(mainwin));
-      gtk_widget_grab_focus(mainwin);
-    }
-}
-
-void action_playlist_track_info(void)
-{
-    playlistwin_fileinfo();
-}
-
-void action_queue_toggle(void)
-{
-    playlist_queue(playlist_get_active());
-}
-
-void action_playlist_sort_by_playlist_entry(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort(playlist, PLAYLIST_SORT_PLAYLIST);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_by_track_number(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort(playlist, PLAYLIST_SORT_TRACK);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_by_title(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort(playlist, PLAYLIST_SORT_TITLE);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_by_artist(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort(playlist, PLAYLIST_SORT_ARTIST);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_by_full_path(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort(playlist, PLAYLIST_SORT_PATH);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_by_date(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort(playlist, PLAYLIST_SORT_DATE);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_by_filename(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort(playlist, PLAYLIST_SORT_FILENAME);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_selected_by_playlist_entry(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort_selected(playlist, PLAYLIST_SORT_PLAYLIST);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_selected_by_track_number(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort_selected(playlist, PLAYLIST_SORT_TRACK);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_selected_by_title(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort_selected(playlist, PLAYLIST_SORT_TITLE);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_selected_by_artist(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort_selected(playlist, PLAYLIST_SORT_ARTIST);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_selected_by_full_path(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort_selected(playlist, PLAYLIST_SORT_PATH);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_selected_by_date(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort_selected(playlist, PLAYLIST_SORT_DATE);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_sort_selected_by_filename(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_sort_selected(playlist, PLAYLIST_SORT_FILENAME);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_randomize_list(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_random(playlist);
-    playlistwin_update_list(playlist);
-}
-
-void action_playlist_reverse_list(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_reverse(playlist);
-    playlistwin_update_list(playlist);
-}
-
-void
-action_playlist_clear_queue(void)
-{
-    playlist_clear_queue(playlist_get_active());
-}
-
-void
-action_playlist_remove_unavailable(void)
-{
-    playlist_remove_dead_files(playlist_get_active());
-}
-
-void
-action_playlist_remove_dupes_by_title(void)
-{
-    playlist_remove_duplicates(playlist_get_active(), PLAYLIST_DUPS_TITLE);
-}
-
-void
-action_playlist_remove_dupes_by_filename(void)
-{
-    playlist_remove_duplicates(playlist_get_active(), PLAYLIST_DUPS_FILENAME);
-}
-
-void
-action_playlist_remove_dupes_by_full_path(void)
-{
-    playlist_remove_duplicates(playlist_get_active(), PLAYLIST_DUPS_PATH);
-}
-
-void
-action_playlist_remove_all(void)
-{
-    playlist_clear(playlist_get_active());
-
-    /* XXX -- should this really be coupled here? -nenolod */
-    mainwin_clear_song_info();
-}
-
-void
-action_playlist_remove_selected(void)
-{
-    playlist_delete(playlist_get_active(), FALSE);
-}
-
-void
-action_playlist_remove_unselected(void)
-{
-    playlist_delete(playlist_get_active(), TRUE);
-}
-
-void
-action_playlist_add_files(void)
-{
-    run_filebrowser(FALSE);
-}
-
-void
-action_playlist_add_url(void)
-{
-    mainwin_show_add_url_window();
-}
-
-void
-action_playlist_new( void )
-{
-  Playlist *new_pl = playlist_new();
-  playlist_add_playlist(new_pl);
-  playlist_select_playlist(new_pl);
-}
-
-void
-action_playlist_prev( void )
-{
-    playlist_select_prev();
-}
-
-void
-action_playlist_next( void )
-{
-    playlist_select_next();
-}
-
-void
-action_playlist_delete( void )
-{
-    playlist_remove_playlist( playlist_get_active() );
-}
-
-void
-action_playlist_save_list(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlistwin_select_playlist_to_save(playlist_get_current_name(playlist));
-}
-
-void
-action_playlist_save_default_list(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_save(playlist, aud_paths[BMP_PATH_PLAYLIST_FILE]);
-}
-
-void
-action_playlist_load_list(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlistwin_select_playlist_to_load(playlist_get_current_name(playlist));
-}
-
-void
-action_playlist_refresh_list(void)
-{
-    Playlist *playlist = playlist_get_active();
-
-    playlist_read_info_selection(playlist);
-    playlistwin_update_list(playlist);
-}
-
-void
-action_open_list_manager(void)
-{
-    playlist_manager_ui_show();
-}
-
-void
-action_playlist_search_and_select(void)
-{
-    playlistwin_select_search();
-}
-
-void
-action_playlist_invert_selection(void)
-{
-    playlistwin_inverse_selection();
-}
-
-void
-action_playlist_select_none(void)
-{
-    playlistwin_select_none();
-}
-
-void
-action_playlist_select_all(void)
-{
-    playlistwin_select_all();
-}
-
-
-static void
-playlistwin_select_search_cbt_cb(GtkWidget *called_cbt, gpointer other_cbt)
-{
-    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(called_cbt)) == TRUE)
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_cbt), FALSE);
-    return;
-}
-
-static gboolean
-playlistwin_select_search_kp_cb(GtkWidget *entry, GdkEventKey *event,
-                                gpointer searchdlg_win)
-{
-    switch (event->keyval)
-    {
-        case GDK_Return:
-            if (gtk_im_context_filter_keypress (GTK_ENTRY (entry)->im_context, event)) {
-                GTK_ENTRY (entry)->need_im_reset = TRUE;
-                return TRUE;
-            } else {
-                gtk_dialog_response(GTK_DIALOG(searchdlg_win), GTK_RESPONSE_ACCEPT);
-                return TRUE;
-            }
-        default:
-            return FALSE;
-    }
-}
--- a/src/audacious/ui_playlist.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_PLAYLIST_H
-#define AUDACIOUS_UI_PLAYLIST_H
-
-#include <glib.h>
-
-#include "ui_main.h"
-#include "playlist.h"
-
-#define PLAYLISTWIN_FRAME_TOP_HEIGHT    20
-#define PLAYLISTWIN_FRAME_BOTTOM_HEIGHT 38
-#define PLAYLISTWIN_FRAME_LEFT_WIDTH    12
-#define PLAYLISTWIN_FRAME_RIGHT_WIDTH   19
-
-#define PLAYLISTWIN_MIN_WIDTH           MAINWIN_WIDTH
-#define PLAYLISTWIN_MIN_HEIGHT          MAINWIN_HEIGHT
-#define PLAYLISTWIN_WIDTH_SNAP          25
-#define PLAYLISTWIN_HEIGHT_SNAP         29
-#define PLAYLISTWIN_SHADED_HEIGHT       MAINWIN_SHADED_HEIGHT
-#define PLAYLISTWIN_WIDTH               cfg.playlist_width
-#define PLAYLISTWIN_HEIGHT \
-    (cfg.playlist_shaded ? PLAYLISTWIN_SHADED_HEIGHT : cfg.playlist_height)
-
-#define PLAYLISTWIN_DEFAULT_WIDTH       275
-#define PLAYLISTWIN_DEFAULT_HEIGHT      232
-#define PLAYLISTWIN_DEFAULT_POS_X       295
-#define PLAYLISTWIN_DEFAULT_POS_Y       20
-
-#define PLAYLISTWIN_DEFAULT_FONT        "Sans Bold 8"
-
-gboolean playlistwin_is_shaded(void);
-gint playlistwin_get_width(void);
-gint playlistwin_get_height(void);
-void playlistwin_update_list(Playlist *playlist);
-gboolean playlistwin_item_visible(gint index);
-gint playlistwin_get_toprow(void);
-void playlistwin_set_toprow(gint top);
-void playlistwin_set_shade_menu_cb(gboolean shaded);
-void playlistwin_set_shade(gboolean shaded);
-void playlistwin_shade_toggle(void);
-void playlistwin_create(void);
-void playlistwin_hide_timer(void);
-void playlistwin_set_time(gint time, gint length, TimerMode mode);
-void playlistwin_show(void);
-void playlistwin_hide(void);
-void playlistwin_scroll(gint num);
-void playlistwin_scroll_up_pushed(void);
-void playlistwin_scroll_down_pushed(void);
-void playlistwin_select_playlist_to_load(const gchar * default_filename);
-void playlistwin_set_sinfo_font(gchar *font);
-void playlistwin_set_sinfo_scroll(gboolean scroll);
-gint playlistwin_list_get_visible_count(void);
-gint playlistwin_list_get_first(void);
-
-extern GtkWidget *playlistwin;
-
-extern gboolean playlistwin_focus;
-
-#endif /* AUDACIOUS_UI_PLAYLIST_H */
--- a/src/audacious/ui_playlist_evlisteners.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Audacious
- * Copyright (c) 2006-2007 Audacious development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_playlist_evlisteners.h"
-
-#include <glib.h>
-
-#include "hook.h"
-#include "playlist.h"
-#include "ui_playlist.h"
-#include "ui_playlist_manager.h"
-
-static void
-ui_playlist_evlistener_playlist_update(gpointer hook_data, gpointer user_data)
-{
-    Playlist *playlist = (Playlist *) hook_data;
-    if (playlist != NULL)
-        playlistwin_update_list(playlist);
-
-    playlist_manager_update();
-}
-
-static void
-ui_playlist_evlistener_playlistwin_show(gpointer hook_data, gpointer user_data)
-{
-    gboolean *show = (gboolean*)hook_data;
-    if (*show == TRUE)
-        playlistwin_show();
-    else
-        playlistwin_hide();
-}
-
-void ui_playlist_evlistener_init(void)
-{
-    hook_associate("playlist update", ui_playlist_evlistener_playlist_update, NULL);
-    hook_associate("playlistwin show", ui_playlist_evlistener_playlistwin_show, NULL);
-}
--- a/src/audacious/ui_playlist_evlisteners.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Audacious
- * Copyright (c) 2006-2007 Audacious development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H
-#define AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H
-
-void ui_playlist_evlistener_init(void);
-
-#endif /* AUDACIOUS_UI_PLAYLIST_EVLISTENERS_H */
--- a/src/audacious/ui_playlist_manager.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,498 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#include "ui_playlist_manager.h"
-#include "ui_playlist.h"
-#include "playlist.h"
-#include "ui_main.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-
-
-#define DISABLE_MANAGER_UPDATE() g_object_set_data(G_OBJECT(listview),"opt1",GINT_TO_POINTER(1))
-#define ENABLE_MANAGER_UPDATE() g_object_set_data(G_OBJECT(listview),"opt1",GINT_TO_POINTER(0))
-
-
-static GtkWidget *playman_win = NULL;
-
-
-/* in this enum, place the columns according to visualization order
-   (information not displayed in columns should be placed right before PLLIST_NUMCOLS) */
-enum
-{
-    PLLIST_COL_NAME = 0,
-    PLLIST_COL_ENTRIESNUM,
-    PLLIST_PLPOINTER,
-    PLLIST_TEXT_WEIGHT,
-    PLLIST_NUMCOLS
-};
-
-
-static GtkTreeIter
-playlist_manager_populate ( GtkListStore * store )
-{
-    GList *playlists = NULL;
-    Playlist *active, *iter_playlist, *next_playlist;
-    GtkTreeIter iter, insert, next, active_iter;
-    gboolean valid, have_active_iter;
-
-    active = playlist_get_active();
-    playlists = playlist_get_playlists();
-    valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(store) , &iter );
-    have_active_iter = FALSE;
-    while ( playlists != NULL )
-    {
-        GList *entries = NULL;
-        gint entriesnum = 0;
-        gchar *pl_name = NULL;
-        Playlist *playlist = (Playlist*)playlists->data;
-
-        if(playlist != active) //XXX the active playlist has been locked in playlist_new_from_selected()
-            PLAYLIST_LOCK(playlist);
-
-        /* for each playlist, pick name and number of entries */
-        pl_name = (gchar*)playlist_get_current_name( playlist );
-        for (entries = playlist->entries; entries; entries = g_list_next(entries))
-            entriesnum++;
-
-        if(playlist != active)
-            PLAYLIST_UNLOCK(playlist);
-
-        /* update the tree model conservatively */
-
-        if ( !valid )
-        {
-            /* append */
-            gtk_list_store_append( store , &insert );
-            goto store_set;
-        }
-
-        gtk_tree_model_get( GTK_TREE_MODEL(store) , &iter ,
-                PLLIST_PLPOINTER , &iter_playlist , -1 );
-
-        if ( playlist == iter_playlist )
-        {
-            /* already have - just update */
-            insert = iter;
-            valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(store) , &iter );
-            goto store_set;
-        }
-
-        /* handle movement/deletion/insertion of single elements */
-        if ( gtk_tree_model_iter_next( GTK_TREE_MODEL(store) , &next ) )
-        {
-            gtk_tree_model_get( GTK_TREE_MODEL(store) , &next ,
-                    PLLIST_PLPOINTER , &next_playlist , -1 );
-            if ( playlist == next_playlist )
-            {
-                /* remove */
-                gtk_list_store_remove( store , &iter );
-                iter = next;
-                valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
-                goto next_playlist;
-            }
-        }
-
-        /* insert */
-        gtk_list_store_insert_before( store , &insert , &iter );
-
-store_set:
-        gtk_list_store_set( store, &insert,
-                            PLLIST_COL_NAME , pl_name ,
-                            PLLIST_COL_ENTRIESNUM , entriesnum ,
-                            PLLIST_PLPOINTER , playlist ,
-                            PLLIST_TEXT_WEIGHT , playlist == active ?
-                                PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL ,
-                            -1 );
-        if ( !have_active_iter && playlist == active )
-        {
-            active_iter = insert;
-            have_active_iter = TRUE;
-        }
-
-next_playlist:
-        playlists = g_list_next(playlists);
-    }
-
-    while (valid)
-    {
-        /* remove any other elements */
-        next = iter;
-        valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(store) , &next );
-        gtk_list_store_remove( store , &iter );
-        iter = next;
-    }
-
-    if ( !have_active_iter )
-        gtk_tree_model_get_iter_first( GTK_TREE_MODEL(store) , &active_iter );
-
-    return active_iter;
-}
-
-
-static void
-playlist_manager_cb_new ( gpointer listview )
-{
-    GList *playlists = NULL;
-    Playlist *newpl = NULL;
-    GtkTreeIter iter;
-    GtkListStore *store;
-    gchar *pl_name = NULL;
-
-    /* this ensures that playlist_manager_update() will
-       not perform update, since we're already doing it here */
-    DISABLE_MANAGER_UPDATE();
-
-    newpl = playlist_new();
-    pl_name = (gchar*)playlist_get_current_name( newpl );
-    playlists = playlist_get_playlists();
-    playlist_add_playlist( newpl );
-
-    store = (GtkListStore*)gtk_tree_view_get_model( GTK_TREE_VIEW(listview) );
-    gtk_list_store_append( store , &iter );
-    gtk_list_store_set( store, &iter,
-                        PLLIST_COL_NAME , pl_name ,
-                        PLLIST_COL_ENTRIESNUM , 0 ,
-                        PLLIST_PLPOINTER , newpl ,
-                        PLLIST_TEXT_WEIGHT , PANGO_WEIGHT_NORMAL ,
-                        -1 );
-
-    ENABLE_MANAGER_UPDATE();
-
-    return;
-}
-
-
-static void
-playlist_manager_cb_del ( gpointer listview )
-{
-    GtkTreeSelection *listsel = gtk_tree_view_get_selection( GTK_TREE_VIEW(listview) );
-    GtkTreeModel *store;
-    GtkTreeIter iter;
-    Playlist *active;
-    gboolean was_active;
-
-    if ( gtk_tree_selection_get_selected( listsel , &store , &iter ) == TRUE )
-    {
-        Playlist *playlist = NULL;
-        gtk_tree_model_get( store, &iter, PLLIST_PLPOINTER , &playlist , -1 );
-
-        active = playlist_get_active();
-        was_active = ( playlist == active );
-
-        if ( gtk_tree_model_iter_n_children( store , NULL ) < 2 )
-        {
-            /* let playlist_manager_update() handle the deletion of the last playlist */
-            playlist_remove_playlist( playlist );
-        }
-        else
-        {
-            gtk_list_store_remove( (GtkListStore*)store , &iter );
-            /* this ensures that playlist_manager_update() will
-               not perform update, since we're already doing it here */
-            DISABLE_MANAGER_UPDATE();
-            playlist_remove_playlist( playlist );
-            ENABLE_MANAGER_UPDATE();
-        }
-
-        if ( was_active && gtk_tree_model_get_iter_first( store , &iter ) )
-        {
-            /* update bolded playlist */
-            active = playlist_get_active();
-            do {
-                gtk_tree_model_get( store , &iter ,
-                        PLLIST_PLPOINTER , &playlist , -1 );
-                gtk_list_store_set( GTK_LIST_STORE(store) , &iter ,
-                        PLLIST_TEXT_WEIGHT , playlist == active ?
-                            PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL ,
-                       -1 );
-            } while ( gtk_tree_model_iter_next( store , &iter ) );
-        }
-    }
-
-    return;
-}
-
-
-static void
-playlist_manager_cb_lv_dclick ( GtkTreeView * listview , GtkTreePath * path ,
-                                GtkTreeViewColumn * col , gpointer userdata )
-{
-    GtkTreeModel *store;
-    GtkTreeIter iter;
-    Playlist *playlist = NULL, *active;
-
-    store = gtk_tree_view_get_model( GTK_TREE_VIEW(listview) );
-    if ( gtk_tree_model_get_iter( store , &iter , path ) == TRUE )
-    {
-        gtk_tree_model_get( store , &iter , PLLIST_PLPOINTER , &playlist , -1 );
-        DISABLE_MANAGER_UPDATE();
-        playlist_select_playlist( playlist );
-        ENABLE_MANAGER_UPDATE();
-    }
-
-    if ( gtk_tree_model_get_iter_first( store , &iter ) )
-    {
-        /* update bolded playlist */
-        active = playlist_get_active();
-        do {
-            gtk_tree_model_get( store , &iter ,
-                    PLLIST_PLPOINTER , &playlist , -1 );
-            gtk_list_store_set( GTK_LIST_STORE(store) , &iter ,
-                    PLLIST_TEXT_WEIGHT , playlist == active ?
-                        PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL ,
-                   -1 );
-        } while ( gtk_tree_model_iter_next( store , &iter ) );
-    }
-
-    return;
-}
-
-
-static void
-playlist_manager_cb_lv_pmenu_rename ( GtkMenuItem *menuitem , gpointer lv )
-{
-    GtkTreeSelection *listsel = gtk_tree_view_get_selection( GTK_TREE_VIEW(lv) );
-    GtkTreeModel *store;
-    GtkTreeIter iter;
-
-    if ( gtk_tree_selection_get_selected( listsel , &store , &iter ) == TRUE )
-    {
-        GtkTreePath *path = gtk_tree_model_get_path( GTK_TREE_MODEL(store) , &iter );
-        GtkCellRenderer *rndrname = g_object_get_data( G_OBJECT(lv) , "rn" );
-        /* set the name renderer to editable and start editing */
-        g_object_set( G_OBJECT(rndrname) , "editable" , TRUE , NULL );
-        gtk_tree_view_set_cursor_on_cell( GTK_TREE_VIEW(lv) , path ,
-                                          gtk_tree_view_get_column( GTK_TREE_VIEW(lv) , PLLIST_COL_NAME ) , rndrname , TRUE );
-        gtk_tree_path_free( path );
-    }
-}
-
-static void
-playlist_manager_cb_lv_name_edited ( GtkCellRendererText *cell , gchar *path_string ,
-                                     gchar *new_text , gpointer listview )
-{
-    /* this is currently used to change playlist names */
-    GtkTreeModel *store = gtk_tree_view_get_model( GTK_TREE_VIEW(listview) );
-    GtkTreeIter iter;
-
-    if ( gtk_tree_model_get_iter_from_string( store , &iter , path_string ) == TRUE )
-    {
-        Playlist *playlist = NULL;
-        gtk_tree_model_get( GTK_TREE_MODEL(store), &iter, PLLIST_PLPOINTER , &playlist , -1 );
-        DISABLE_MANAGER_UPDATE();
-        playlist_set_current_name( playlist , new_text );
-        ENABLE_MANAGER_UPDATE();
-        gtk_list_store_set( GTK_LIST_STORE(store), &iter, PLLIST_COL_NAME , new_text , -1 );
-    }
-    /* set the renderer uneditable again */
-    g_object_set( G_OBJECT(cell) , "editable" , FALSE , NULL );
-}
-
-
-static gboolean
-playlist_manager_cb_lv_btpress ( GtkWidget *lv , GdkEventButton *event )
-{
-    if (( event->type == GDK_BUTTON_PRESS ) && ( event->button == 3 ))
-    {
-        GtkWidget *pmenu = (GtkWidget*)g_object_get_data( G_OBJECT(lv) , "menu" );
-        gtk_menu_popup( GTK_MENU(pmenu) , NULL , NULL , NULL , NULL ,
-                        (event != NULL) ? event->button : 0,
-                        event->time);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-
-static gboolean
-playlist_manager_cb_keypress ( GtkWidget *win , GdkEventKey *event )
-{
-    switch (event->keyval)
-    {
-        case GDK_Escape:
-            gtk_widget_destroy( playman_win );
-            return TRUE;
-        default:
-            return FALSE;
-    }
-}
-
-
-void
-playlist_manager_ui_show ( void )
-{
-    GtkWidget *playman_vbox;
-    GtkWidget *playman_pl_lv, *playman_pl_lv_frame, *playman_pl_lv_sw;
-    GtkCellRenderer *playman_pl_lv_textrndr_name, *playman_pl_lv_textrndr_entriesnum;
-    GtkTreeViewColumn *playman_pl_lv_col_name, *playman_pl_lv_col_entriesnum;
-    GtkListStore *pl_store;
-    GtkWidget *playman_pl_lv_pmenu, *playman_pl_lv_pmenu_rename;
-    GtkWidget *playman_bbar_hbbox;
-    GtkWidget *playman_bbar_bt_new, *playman_bbar_bt_del, *playman_bbar_bt_close;
-    GdkGeometry playman_win_hints;
-    GtkTreeIter active_iter;
-    GtkTreePath *active_path;
-
-    if ( playman_win != NULL )
-    {
-        gtk_window_present( GTK_WINDOW(playman_win) );
-        return;
-    }
-
-    playman_win = gtk_window_new( GTK_WINDOW_TOPLEVEL );
-    gtk_window_set_type_hint( GTK_WINDOW(playman_win), GDK_WINDOW_TYPE_HINT_DIALOG );
-    gtk_window_set_transient_for( GTK_WINDOW(playman_win) , GTK_WINDOW(mainwin) );
-    gtk_window_set_position( GTK_WINDOW(playman_win), GTK_WIN_POS_CENTER );
-    gtk_window_set_title( GTK_WINDOW(playman_win), _("Playlist Manager") );
-    gtk_container_set_border_width( GTK_CONTAINER(playman_win), 10 );
-    g_signal_connect( G_OBJECT(playman_win) , "destroy" ,
-                      G_CALLBACK(gtk_widget_destroyed) , &playman_win );
-    g_signal_connect( G_OBJECT(playman_win) , "key-press-event" ,
-                      G_CALLBACK(playlist_manager_cb_keypress) , NULL );
-    playman_win_hints.min_width = 400;
-    playman_win_hints.min_height = 250;
-    gtk_window_set_geometry_hints( GTK_WINDOW(playman_win) , GTK_WIDGET(playman_win) ,
-                                   &playman_win_hints , GDK_HINT_MIN_SIZE );
-
-    playman_vbox = gtk_vbox_new( FALSE , 10 );
-    gtk_container_add( GTK_CONTAINER(playman_win) , playman_vbox );
-
-    /* current liststore model
-       ----------------------------------------------
-       G_TYPE_STRING -> playlist name
-       G_TYPE_UINT -> number of entries in playlist
-       G_TYPE_POINTER -> playlist pointer (Playlist*)
-       PANGO_TYPE_WEIGHT -> font weight
-       ----------------------------------------------
-       */
-    pl_store = gtk_list_store_new( PLLIST_NUMCOLS ,
-            G_TYPE_STRING , G_TYPE_UINT , G_TYPE_POINTER , PANGO_TYPE_WEIGHT );
-    active_iter = playlist_manager_populate( pl_store );
-
-    playman_pl_lv_frame = gtk_frame_new( NULL );
-    playman_pl_lv = gtk_tree_view_new_with_model( GTK_TREE_MODEL(pl_store) );
-
-    g_object_set_data( G_OBJECT(playman_win) , "lv" , playman_pl_lv );
-    g_object_set_data( G_OBJECT(playman_pl_lv) , "opt1" , GINT_TO_POINTER(0) );
-    playman_pl_lv_textrndr_entriesnum = gtk_cell_renderer_text_new(); /* uneditable */
-    playman_pl_lv_textrndr_name = gtk_cell_renderer_text_new(); /* can become editable */
-    g_object_set( G_OBJECT(playman_pl_lv_textrndr_entriesnum) , "weight-set" , TRUE , NULL );
-    g_object_set( G_OBJECT(playman_pl_lv_textrndr_name) , "weight-set" , TRUE , NULL );
-    g_signal_connect( G_OBJECT(playman_pl_lv_textrndr_name) , "edited" ,
-                      G_CALLBACK(playlist_manager_cb_lv_name_edited) , playman_pl_lv );
-    g_object_set_data( G_OBJECT(playman_pl_lv) , "rn" , playman_pl_lv_textrndr_name );
-    playman_pl_lv_col_name = gtk_tree_view_column_new_with_attributes(
-            _("Playlist") , playman_pl_lv_textrndr_name ,
-            "text" , PLLIST_COL_NAME ,
-            "weight", PLLIST_TEXT_WEIGHT ,
-            NULL );
-    gtk_tree_view_column_set_expand( GTK_TREE_VIEW_COLUMN(playman_pl_lv_col_name) , TRUE );
-    gtk_tree_view_append_column( GTK_TREE_VIEW(playman_pl_lv), playman_pl_lv_col_name );
-    playman_pl_lv_col_entriesnum = gtk_tree_view_column_new_with_attributes(
-            _("Entries") , playman_pl_lv_textrndr_entriesnum ,
-            "text" , PLLIST_COL_ENTRIESNUM ,
-            "weight", PLLIST_TEXT_WEIGHT ,
-            NULL );
-    gtk_tree_view_column_set_expand( GTK_TREE_VIEW_COLUMN(playman_pl_lv_col_entriesnum) , FALSE );
-    gtk_tree_view_append_column( GTK_TREE_VIEW(playman_pl_lv), playman_pl_lv_col_entriesnum );
-    playman_pl_lv_sw = gtk_scrolled_window_new( NULL , NULL );
-    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(playman_pl_lv_sw) ,
-                                    GTK_POLICY_NEVER , GTK_POLICY_ALWAYS );
-    gtk_container_add( GTK_CONTAINER(playman_pl_lv_sw) , playman_pl_lv );
-    gtk_container_add( GTK_CONTAINER(playman_pl_lv_frame) , playman_pl_lv_sw );
-    gtk_box_pack_start( GTK_BOX(playman_vbox) , playman_pl_lv_frame , TRUE , TRUE , 0 );
-
-    /* listview popup menu */
-    playman_pl_lv_pmenu = gtk_menu_new();
-    playman_pl_lv_pmenu_rename = gtk_menu_item_new_with_mnemonic( _( "_Rename" ) );
-    g_signal_connect( G_OBJECT(playman_pl_lv_pmenu_rename) , "activate" ,
-                      G_CALLBACK(playlist_manager_cb_lv_pmenu_rename) , playman_pl_lv );
-    gtk_menu_shell_append( GTK_MENU_SHELL(playman_pl_lv_pmenu) , playman_pl_lv_pmenu_rename );
-    gtk_widget_show_all( playman_pl_lv_pmenu );
-    g_object_set_data( G_OBJECT(playman_pl_lv) , "menu" , playman_pl_lv_pmenu );
-    g_signal_connect_swapped( G_OBJECT(playman_win) , "destroy" ,
-                              G_CALLBACK(gtk_widget_destroy) , playman_pl_lv_pmenu );
-
-    /* button bar */
-    playman_bbar_hbbox = gtk_hbutton_box_new();
-    gtk_button_box_set_layout( GTK_BUTTON_BOX(playman_bbar_hbbox) , GTK_BUTTONBOX_END );
-	gtk_button_box_set_spacing(GTK_BUTTON_BOX(playman_bbar_hbbox), 5);
-    playman_bbar_bt_close = gtk_button_new_from_stock( GTK_STOCK_CLOSE );
-    playman_bbar_bt_del = gtk_button_new_from_stock( GTK_STOCK_DELETE );
-    playman_bbar_bt_new = gtk_button_new_from_stock( GTK_STOCK_NEW );
-    gtk_container_add( GTK_CONTAINER(playman_bbar_hbbox) , playman_bbar_bt_close );
-    gtk_container_add( GTK_CONTAINER(playman_bbar_hbbox) , playman_bbar_bt_del );
-    gtk_container_add( GTK_CONTAINER(playman_bbar_hbbox) , playman_bbar_bt_new );
-    gtk_button_box_set_child_secondary( GTK_BUTTON_BOX(playman_bbar_hbbox) ,
-                                        playman_bbar_bt_close , TRUE );
-    gtk_box_pack_start( GTK_BOX(playman_vbox) , playman_bbar_hbbox , FALSE , FALSE , 0 );
-
-    g_signal_connect( G_OBJECT(playman_pl_lv) , "button-press-event" ,
-                      G_CALLBACK(playlist_manager_cb_lv_btpress) , NULL );
-    g_signal_connect( G_OBJECT(playman_pl_lv) , "row-activated" ,
-                      G_CALLBACK(playlist_manager_cb_lv_dclick) , NULL );
-    g_signal_connect_swapped( G_OBJECT(playman_bbar_bt_new) , "clicked" ,
-                              G_CALLBACK(playlist_manager_cb_new) , playman_pl_lv );
-    g_signal_connect_swapped( G_OBJECT(playman_bbar_bt_del) , "clicked" ,
-                              G_CALLBACK(playlist_manager_cb_del) , playman_pl_lv );
-    g_signal_connect_swapped( G_OBJECT(playman_bbar_bt_close) , "clicked" ,
-                              G_CALLBACK(gtk_widget_destroy) , playman_win );
-
-    /* have active playlist selected and scrolled to */
-    active_path = gtk_tree_model_get_path( GTK_TREE_MODEL(pl_store) ,
-            &active_iter );
-    gtk_tree_view_set_cursor( GTK_TREE_VIEW(playman_pl_lv) ,
-            active_path , NULL , FALSE );
-    gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(playman_pl_lv) ,
-            active_path , NULL , TRUE , 0.5 , 0.0 );
-    gtk_tree_path_free( active_path );
-
-    g_object_unref( pl_store );
-
-    gtk_widget_show_all( playman_win );
-}
-
-
-void
-playlist_manager_update ( void )
-{
-    /* this function is called whenever there is a change in playlist, such as
-       playlist created/deleted or entry added/deleted in a playlist; if the playlist
-       manager is active, it should be updated to keep consistency of information */
-
-    /* CAREFUL! this currently locks/unlocks all the playlists */
-
-    if ( playman_win != NULL )
-    {
-        GtkWidget *lv = (GtkWidget*)g_object_get_data( G_OBJECT(playman_win) , "lv" );
-        if ( GPOINTER_TO_INT(g_object_get_data(G_OBJECT(lv),"opt1")) == 0 )
-        {
-            GtkListStore *store = (GtkListStore*)gtk_tree_view_get_model( GTK_TREE_VIEW(lv) );
-            playlist_manager_populate( store );
-        }
-        return;
-    }
-    else
-        return; /* if the playlist manager is not active, simply return */
-}
--- a/src/audacious/ui_playlist_manager.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_PLAYLIST_MANAGER_H
-#define AUDACIOUS_UI_PLAYLIST_MANAGER_H
-
-void playlist_manager_update ( void );
-void playlist_manager_ui_show ( void );
-
-#endif /* AUDACIOUS_UI_PLAYLIST_MANAGER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/ui_playlist_widget.c	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,289 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2008 Tomasz Moń <desowin@gmail.com>
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "playlist.h"
+#include "playback.h"
+#include "strings.h"
+
+enum {
+    COLUMN_NUM = 0,
+    COLUMN_TEXT,
+    COLUMN_TIME,
+    COLUMN_WEIGHT,
+    N_COLUMNS
+};
+
+static void
+ui_playlist_widget_change_song(guint pos)
+{
+    playlist_set_position(playlist_get_active(), pos);
+
+    if (!playback_get_playing())
+        playback_initiate();
+}
+
+static void
+ui_playlist_widget_set_title_active(GtkTreeModel *model, gint pos,
+                                    gboolean active)
+{
+    GtkTreeIter iter;
+    GtkTreePath *path;
+    gchar *path_str;
+
+    path_str = g_strdup_printf("%d", pos);
+    path = gtk_tree_path_new_from_string(path_str);
+    gtk_tree_model_get_iter(model, &iter, path);
+
+    gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+                       3, active ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1);
+
+    g_free(path_str);
+    gtk_tree_path_free(path);
+}
+
+void
+ui_playlist_widget_set_current(GtkWidget *treeview, gint pos)
+{
+    GtkTreeModel *model;
+    gint old_pos;
+
+    model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
+    old_pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview), "current"));
+
+    if (old_pos != -1)
+        ui_playlist_widget_set_title_active(model, old_pos, FALSE);
+    if (pos != -1)
+        ui_playlist_widget_set_title_active(model, pos, TRUE);
+
+    g_object_set_data(G_OBJECT(treeview), "current", GINT_TO_POINTER(pos));
+}
+
+static void
+ui_playlist_widget_jump(GtkTreeView * treeview, gpointer data)
+{
+    GtkTreeModel *model;
+    GtkTreeSelection *selection;
+    GtkTreeIter iter;
+    guint pos;
+
+    model = gtk_tree_view_get_model(treeview);
+    selection = gtk_tree_view_get_selection(treeview);
+
+    if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
+        return;
+
+    gtk_tree_model_get(model, &iter, 0, &pos, -1);
+
+    ui_playlist_widget_change_song(pos - 1);
+}
+
+static gboolean
+ui_playlist_widget_keypress_cb(GtkWidget * widget,
+                            GdkEventKey * event,
+                            gpointer data)
+{
+    switch (event->keyval) {
+    case GDK_KP_Enter:
+        ui_playlist_widget_jump(GTK_TREE_VIEW(widget), NULL);
+        return TRUE;
+    default:
+        return FALSE;
+    };
+}
+
+void
+ui_playlist_widget_update(GtkWidget *widget)
+{
+    guint row;
+    gboolean valid;
+
+    GList *playlist_glist;
+    gchar *desc_buf = NULL;
+    gchar *length = NULL;
+    GtkTreeIter iter;
+    Playlist *playlist;
+    GtkTreeModel *store;
+    GtkTreeView *tree = GTK_TREE_VIEW(widget);
+
+    store = gtk_tree_view_get_model(tree);
+    valid = gtk_tree_model_get_iter_first(store, &iter);
+
+    row = 1;
+    playlist = playlist_get_active();
+
+    for (playlist_glist = playlist->entries; playlist_glist;
+         playlist_glist = g_list_next(playlist_glist)) {
+        PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data);
+
+        if (entry->title)
+            desc_buf = g_strdup(entry->title);
+        else {
+            gchar *realfn = NULL;
+            realfn = g_filename_from_uri(entry->filename, NULL, NULL);
+            if (strchr(realfn ? realfn : entry->filename, '/'))
+                desc_buf = str_assert_utf8(strrchr(realfn ? realfn : entry->filename, '/') + 1);
+            else
+                desc_buf = str_assert_utf8(realfn ? realfn : entry->filename);
+            g_free(realfn); realfn = NULL;
+        }
+
+        if (entry->length != -1) {
+            length = g_strdup_printf("%d:%-2.2d", entry->length / 60000, (entry->length / 1000) % 60);
+        }
+
+        if (!valid)
+            gtk_list_store_append(GTK_LIST_STORE(store), &iter);
+        gtk_list_store_set(GTK_LIST_STORE(store), &iter,
+                           COLUMN_NUM, row, COLUMN_TEXT, desc_buf,
+                           COLUMN_TIME, length,
+                           COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, -1);
+        row++;
+
+        g_free(desc_buf);
+        desc_buf = NULL;
+
+        if (length) g_free(length);
+        length = NULL;
+
+        valid = gtk_tree_model_iter_next(store, &iter);
+    }
+
+    /* remove additional rows */
+    while (valid) {
+        valid = gtk_list_store_remove(GTK_LIST_STORE(store), &iter);
+    }
+
+    ui_playlist_widget_set_current(widget, playlist_get_position(playlist));
+}
+
+static gboolean
+ui_playlist_widget_fill(gpointer treeview)
+{
+    GList *playlist_glist;
+    Playlist *playlist;
+    gchar *desc_buf = NULL;
+    gchar *length = NULL;
+    guint row;
+    GtkTreeIter iter;
+    GtkListStore *store = (GtkListStore*)gtk_tree_view_get_model( GTK_TREE_VIEW(treeview) );
+
+    /* detach model from treeview before fill */
+    g_object_ref(store);
+    gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), NULL );
+
+    gtk_list_store_clear(store);
+
+    row = 1;
+    playlist = playlist_get_active();
+
+    PLAYLIST_LOCK(playlist);
+    for (playlist_glist = playlist->entries; playlist_glist;
+         playlist_glist = g_list_next(playlist_glist)) {
+
+        PlaylistEntry *entry = PLAYLIST_ENTRY(playlist_glist->data);
+
+        if (entry->title)
+            desc_buf = g_strdup(entry->title);
+        else {
+            gchar *realfn = NULL;
+            realfn = g_filename_from_uri(entry->filename, NULL, NULL);
+            if (strchr(realfn ? realfn : entry->filename, '/'))
+                desc_buf = str_assert_utf8(strrchr(realfn ? realfn : entry->filename, '/') + 1);
+            else
+                desc_buf = str_assert_utf8(realfn ? realfn : entry->filename);
+            g_free(realfn); realfn = NULL;
+        }
+
+        if (entry->length != -1) {
+            length = g_strdup_printf("%d:%-2.2d", entry->length / 60000, (entry->length / 1000) % 60);
+        }
+
+        gtk_list_store_append(GTK_LIST_STORE(store), &iter);
+        gtk_list_store_set(GTK_LIST_STORE(store), &iter,
+                           COLUMN_NUM, row, COLUMN_TEXT, desc_buf,
+                           COLUMN_TIME, length,
+                           COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL, -1);
+        row++;
+
+        g_free(desc_buf);
+        desc_buf = NULL;
+
+        if (length) g_free(length);
+        length = NULL;
+    }
+    PLAYLIST_UNLOCK(playlist);
+
+    /* attach liststore to treeview */
+    gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(store));
+    g_object_unref(store);
+
+    return FALSE;
+}
+
+GtkWidget *
+ui_playlist_widget_new(void)
+{
+    GtkWidget *treeview;
+    GtkListStore *store;
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+
+    store = gtk_list_store_new(N_COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, PANGO_TYPE_WEIGHT);
+    treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+    g_object_unref(store);
+
+    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
+
+    column = gtk_tree_view_column_new();
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+    gtk_tree_view_column_set_spacing(column, 4);
+
+    renderer = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, renderer, FALSE);
+    gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_NUM, NULL);
+    g_object_set(G_OBJECT(renderer), "ypad", 0, NULL);
+
+    renderer = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, renderer, TRUE);
+    gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_TEXT, "weight", COLUMN_WEIGHT, NULL);
+    g_object_set(G_OBJECT(renderer), "ypad", 0, "ellipsize-set", TRUE,
+                 "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+
+    renderer = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, renderer, FALSE);
+    gtk_tree_view_column_set_attributes(column, renderer, "text", COLUMN_TIME, NULL);
+    g_object_set(G_OBJECT(renderer), "ypad", 0, NULL);
+
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+    g_signal_connect(treeview, "row-activated",
+                     G_CALLBACK(ui_playlist_widget_jump), NULL);
+
+    g_signal_connect(treeview, "key-press-event",
+                     G_CALLBACK(ui_playlist_widget_keypress_cb), NULL);
+
+    ui_playlist_widget_fill(treeview);
+
+    g_object_set_data(G_OBJECT(treeview), "current", GINT_TO_POINTER(-1));
+
+    return treeview;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/ui_playlist_widget.h	Wed Aug 06 22:33:27 2008 +0300
@@ -0,0 +1,29 @@
+/*  Audacious - Cross-platform multimedia player
+ *  Copyright (C) 2008 Tomasz Moń <desowin@gmail.com>
+ *
+ *  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; under version 3 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef UI_PLAYLIST_WIDGET_H
+#define UI_PLAYLIST_WIDGET_H
+
+#include <gtk/gtk.h>
+
+void ui_playlist_widget_set_current(GtkWidget *treeview, gint pos);
+void ui_playlist_widget_update(GtkWidget *widget);
+GtkWidget * ui_playlist_widget_new(void);
+
+#endif
--- a/src/audacious/ui_preferences.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_preferences.c	Wed Aug 06 22:33:27 2008 +0300
@@ -46,20 +46,13 @@
 #include "visualization.h"
 #include "playlist.h"
 
-#include "ui_skinned_textbox.h"
 #include "strings.h"
 #include "util.h"
 #include "dnd.h"
 #include "configdb.h"
 #include "preferences.h"
 
-#include "ui_main.h"
-#include "ui_playlist.h"
-#include "ui_skinselector.h"
 #include "ui_preferences.h"
-#include "ui_equalizer.h"
-#include "ui_skinned_playlist.h"
-#include "ui_skinned_window.h"
 
 #include "build_stamp.h"
 
@@ -105,7 +98,6 @@
 
 static GtkWidget *prefswin = NULL;
 static GtkWidget *filepopup_settings = NULL;
-static GtkWidget *colorize_settings = NULL;
 static GtkWidget *category_treeview = NULL;
 static GtkWidget *category_notebook = NULL;
 GtkWidget *filepopupbutton = NULL;
@@ -127,14 +119,11 @@
 
 /* prefswin widgets */
 GtkWidget *titlestring_entry;
-GtkWidget *skin_view;
-GtkWidget *skin_refresh_button;
 GtkWidget *filepopup_for_tuple_settings_button;
 GtkTooltips *tooltips;
 static gint titlestring_timeout_counter = 0;
 
 static Category categories[] = {
-    {DATA_DIR "/images/appearance.png",   N_("Appearance")},
     {DATA_DIR "/images/audio.png",        N_("Audio")},
     {DATA_DIR "/images/replay_gain.png",  N_("Replay Gain")},
     {DATA_DIR "/images/connectivity.png", N_("Connectivity")},
@@ -190,36 +179,10 @@
 
 CategoryQueueEntry *category_queue = NULL;
 
-static void playlist_show_pl_separator_numbers_cb();
-static void show_wm_decorations_cb();
-static void bitmap_fonts_cb();
-static void mainwin_font_set_cb();
-static void playlist_font_set_cb();
 GtkWidget *ui_preferences_chardet_table_populate(void);
 static GtkWidget *ui_preferences_bit_depth(void);
 static GtkWidget *ui_preferences_rg_params(void);
 
-static PreferencesWidget appearance_misc_widgets[] = {
-    {WIDGET_LABEL, N_("<b>_Fonts</b>"), NULL, NULL, NULL, FALSE},
-    {WIDGET_FONT_BTN, N_("_Player:"), &cfg.mainwin_font, G_CALLBACK(mainwin_font_set_cb), N_("Select main player window font:"), FALSE},
-    {WIDGET_FONT_BTN, N_("_Playlist:"), &cfg.playlist_font, G_CALLBACK(playlist_font_set_cb), N_("Select playlist font:"), FALSE},
-    {WIDGET_CHK_BTN, N_("Use Bitmap fonts if available"), &cfg.mainwin_use_bitmapfont, G_CALLBACK(bitmap_fonts_cb), N_("Use bitmap fonts if they are available. Bitmap fonts do not support Unicode strings."), FALSE},
-    {WIDGET_LABEL, N_("<b>_Miscellaneous</b>"), NULL, NULL, NULL, FALSE},
-    {WIDGET_CHK_BTN, N_("Show track numbers in playlist"), &cfg.show_numbers_in_pl,
-        G_CALLBACK(playlist_show_pl_separator_numbers_cb), NULL, FALSE},
-    {WIDGET_CHK_BTN, N_("Show separators in playlist"), &cfg.show_separator_in_pl,
-        G_CALLBACK(playlist_show_pl_separator_numbers_cb), NULL, FALSE},
-    {WIDGET_CHK_BTN, N_("Show window manager decoration"), &cfg.show_wm_decorations, G_CALLBACK(show_wm_decorations_cb),
-        N_("This enables the window manager to show decorations for windows."), FALSE},
-    {WIDGET_CHK_BTN, N_("Use XMMS-style file selector instead of the default selector"), &cfg.use_xmms_style_fileselector, NULL, 
-        N_("This enables the XMMS/GTK1-style file selection dialogs. This selector is provided by Audacious itself and is faster than the default GTK2 selector (but sadly not as user-friendly)."), FALSE},
-    {WIDGET_CHK_BTN, N_("Use two-way text scroller"), &cfg.twoway_scroll, NULL,
-        N_("If selected, the file information text in the main window will scroll back and forth. If not selected, the text will only scroll in one direction."), FALSE},
-    {WIDGET_CHK_BTN, N_("Disable inline gtk theme"), &cfg.disable_inline_gtk, NULL, NULL, FALSE},
-    {WIDGET_CHK_BTN, N_("Allow loading incomplete skins"), &cfg.allow_broken_skins, NULL,
-        N_("If selected, audacious won't refuse loading broken skins. Use only if your favourite skin doesn't work"), FALSE},
-};
-
 static PreferencesWidget audio_page_widgets[] = {
     {WIDGET_LABEL, N_("<b>Format Detection</b>"), NULL, NULL, NULL, FALSE},
     {WIDGET_CHK_BTN, N_("Detect file formats on demand, instead of immediately."), &cfg.playlist_detect, NULL,
@@ -285,7 +248,6 @@
     {WIDGET_SPIN_BTN, N_("Scrolls playlist by"), &cfg.scroll_pl_by, NULL, N_("lines"), FALSE},
 };
 
-static void create_colorize_settings(void);
 static void prefswin_page_queue_destroy(CategoryQueueEntry *ent);
 
 static void
@@ -684,27 +646,6 @@
     if (callback) callback();
 }
 
-static void
-mainwin_font_set_cb()
-{
-    ui_skinned_textbox_set_xfont(mainwin_info, !cfg.mainwin_use_bitmapfont, cfg.mainwin_font);
-}
-
-static void
-playlist_font_set_cb()
-{
-    AUDDBG("Attempt to set font \"%s\"\n", cfg.playlist_font);
-    ui_skinned_playlist_set_font(cfg.playlist_font);
-    playlistwin_set_sinfo_font(cfg.playlist_font);  /* propagate font setting to playlistwin_sinfo */
-    playlistwin_update_list(playlist_get_active());
-}
-
-static void
-playlist_show_pl_separator_numbers_cb()
-{
-    playlistwin_update_list(playlist_get_active());
-}
-
 /* proxy */
 static void
 on_proxy_button_realize(GtkToggleButton *button, gchar *cfg)
@@ -958,27 +899,6 @@
 }
 
 static void
-on_skin_refresh_button_clicked(GtkButton * button,
-                               gpointer data)
-{
-    const mode_t mode755 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
-
-    del_directory(aud_paths[BMP_PATH_SKIN_THUMB_DIR]);
-    make_directory(aud_paths[BMP_PATH_SKIN_THUMB_DIR], mode755);
-
-    skin_view_update(GTK_TREE_VIEW(skin_view), GTK_WIDGET(skin_refresh_button));
-}
-
-static gboolean
-on_skin_view_realize(GtkTreeView * treeview,
-                     gpointer data)
-{
-    skin_view_realize(treeview);
-
-    return TRUE;
-}
-
-static void
 on_category_treeview_realize(GtkTreeView * treeview,
                              GtkNotebook * notebook)
 {
@@ -1041,48 +961,6 @@
     }
 }
 
-void
-on_skin_view_drag_data_received(GtkWidget * widget,
-                                GdkDragContext * context,
-                                gint x, gint y,
-                                GtkSelectionData * selection_data,
-                                guint info, guint time,
-                                gpointer user_data) 
-{
-    mcs_handle_t *db;
-    gchar *path;
-
-    if (!selection_data->data) {
-        g_warning("DND data string is NULL");
-        return;
-    }
-
-    path = (gchar *) selection_data->data;
-
-    /* FIXME: use a real URL validator/parser */
-
-    if (str_has_prefix_nocase(path, "file:///")) {
-        path[strlen(path) - 2] = 0; /* Why the hell a CR&LF? */
-        path += 7;
-    }
-    else if (str_has_prefix_nocase(path, "file:")) {
-        path += 5;
-    }
-
-    if (file_is_archive(path)) {
-        if (!aud_active_skin_load(path))
-            return;
-        skin_install_skin(path);
-        skin_view_update(GTK_TREE_VIEW(widget),
-                         GTK_WIDGET(skin_refresh_button));
-
-        /* Change skin name in the config file */
-        db = cfg_db_open();
-        cfg_db_set_string(db, NULL, "skin", path);
-        cfg_db_close(db);
-    }
-}
-
 static void
 on_chardet_detector_cbox_changed(GtkComboBox * combobox, gpointer data)
 {
@@ -1211,53 +1089,6 @@
 }
 
 static void
-on_colorize_button_clicked(GtkButton *button, gpointer data)
-{
-    if (colorize_settings)
-        gtk_window_present(GTK_WINDOW(colorize_settings));
-    else
-        create_colorize_settings();
-}
-
-static void
-reload_skin()
-{
-    /* reload the skin to apply the change */
-    skin_reload_forced();
-    ui_skinned_window_draw_all(mainwin);
-    ui_skinned_window_draw_all(equalizerwin);
-    ui_skinned_window_draw_all(playlistwin);
-}
-
-static void
-on_red_scale_value_changed(GtkHScale *scale, gpointer data)
-{
-    cfg.colorize_r = gtk_range_get_value(GTK_RANGE(scale));
-    reload_skin();
-}
-
-static void
-on_green_scale_value_changed(GtkHScale *scale, gpointer data)
-{
-    cfg.colorize_g = gtk_range_get_value(GTK_RANGE(scale));
-    reload_skin();
-}
-
-static void
-on_blue_scale_value_changed(GtkHScale *scale, gpointer data)
-{
-    cfg.colorize_b = gtk_range_get_value(GTK_RANGE(scale));
-    reload_skin();
-}
-
-static void
-on_colorize_close_clicked(GtkButton *button, gpointer data)
-{
-    gtk_widget_destroy(colorize_settings);
-    colorize_settings = NULL;
-}
-
-static void
 on_filepopup_for_tuple_settings_clicked(GtkButton *button, gpointer data)
 {
     gtk_entry_set_text(GTK_ENTRY(filepopup_settings_cover_name_include), cfg.cover_name_include);
@@ -1314,130 +1145,6 @@
     if (child) gtk_widget_set_sensitive(GTK_WIDGET(child), *cfg);
 }
 
-static void
-bitmap_fonts_cb()
-{
-    ui_skinned_textbox_set_xfont(mainwin_info, !cfg.mainwin_use_bitmapfont, cfg.mainwin_font);
-    playlistwin_set_sinfo_font(cfg.playlist_font);
-
-    if (cfg.playlist_shaded) {
-        playlistwin_update_list(playlist_get_active());
-        ui_skinned_window_draw_all(playlistwin);
-    }
-}
-
-static void
-show_wm_decorations_cb()
-{
-    gtk_window_set_decorated(GTK_WINDOW(mainwin), cfg.show_wm_decorations);
-    gtk_window_set_decorated(GTK_WINDOW(playlistwin), cfg.show_wm_decorations);
-    gtk_window_set_decorated(GTK_WINDOW(equalizerwin), cfg.show_wm_decorations);
-}
-
-void
-create_colorize_settings(void)
-{
-    GtkWidget *vbox;
-    GtkWidget *label;
-    GtkWidget *table;
-    GtkWidget *hbuttonbox;
-    GtkWidget *colorize_close;
-
-    GtkWidget *green_label;
-    GtkWidget *red_label;
-    GtkWidget *blue_label;
-
-    colorize_settings = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_container_set_border_width(GTK_CONTAINER(colorize_settings), 12);
-    gtk_window_set_title(GTK_WINDOW(colorize_settings), _("Color Adjustment"));
-    gtk_window_set_type_hint(GTK_WINDOW(colorize_settings), GDK_WINDOW_TYPE_HINT_DIALOG);
-    gtk_window_set_transient_for(GTK_WINDOW(colorize_settings), GTK_WINDOW(prefswin));
-
-    vbox = gtk_vbox_new(FALSE, 12);
-    gtk_container_add(GTK_CONTAINER(colorize_settings), vbox);
-
-    label = gtk_label_new(_("Audacious allows you to alter the color balance of the skinned UI. The sliders below will allow you to do this."));
-    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-    gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
-    gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-
-    table = gtk_table_new(3, 2, FALSE);
-    gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
-    gtk_table_set_row_spacings(GTK_TABLE(table), 6);
-    gtk_table_set_col_spacings(GTK_TABLE(table), 12);
-
-    blue_label = gtk_label_new(_("Blue"));
-    gtk_table_attach(GTK_TABLE(table), blue_label, 0, 1, 2, 3,
-                     (GtkAttachOptions) (0),
-                     (GtkAttachOptions) (0), 0, 0);
-    gtk_label_set_justify(GTK_LABEL(blue_label), GTK_JUSTIFY_RIGHT);
-    gtk_misc_set_alignment(GTK_MISC(blue_label), 1, 0.5);
-
-    green_label = gtk_label_new(_("Green"));
-    gtk_table_attach(GTK_TABLE(table), green_label, 0, 1, 1, 2,
-                     (GtkAttachOptions) (0),
-                     (GtkAttachOptions) (0), 0, 0);
-    gtk_label_set_justify(GTK_LABEL(green_label), GTK_JUSTIFY_RIGHT);
-    gtk_misc_set_alignment(GTK_MISC(green_label), 1, 0.5);
-
-    red_label = gtk_label_new(_("Red"));
-    gtk_table_attach(GTK_TABLE(table), red_label, 0, 1, 0, 1,
-                     (GtkAttachOptions) (0),
-                     (GtkAttachOptions) (0), 0, 0);
-    gtk_label_set_justify(GTK_LABEL(red_label), GTK_JUSTIFY_RIGHT);
-    gtk_misc_set_alignment(GTK_MISC(red_label), 1, 0.5);
-
-    red_scale = gtk_hscale_new(GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 255, 0, 0, 0)));
-    gtk_table_attach(GTK_TABLE(table), red_scale, 1, 2, 0, 1,
-                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
-                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-    gtk_scale_set_draw_value(GTK_SCALE(red_scale), FALSE);
-    gtk_scale_set_digits(GTK_SCALE(red_scale), 3);
-
-    green_scale = gtk_hscale_new(GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 255, 0, 0, 0)));
-    gtk_table_attach(GTK_TABLE(table), green_scale, 1, 2, 1, 2,
-                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
-                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-    gtk_scale_set_draw_value(GTK_SCALE(green_scale), FALSE);
-    gtk_scale_set_digits(GTK_SCALE(green_scale), 3);
-
-    blue_scale = gtk_hscale_new(GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 255, 0, 0, 0)));
-    gtk_table_attach(GTK_TABLE(table), blue_scale, 1, 2, 2, 3,
-                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
-                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-    gtk_scale_set_draw_value(GTK_SCALE(blue_scale), FALSE);
-    gtk_scale_set_digits(GTK_SCALE(blue_scale), 3);
-
-    hbuttonbox = gtk_hbutton_box_new();
-    gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 0);
-    gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END);
-    gtk_box_set_spacing(GTK_BOX(hbuttonbox), 6);
-
-    colorize_close = gtk_button_new_from_stock("gtk-close");
-    gtk_container_add(GTK_CONTAINER(hbuttonbox), colorize_close);
-    GTK_WIDGET_SET_FLAGS(colorize_close, GTK_CAN_DEFAULT);
-
-    g_signal_connect((gpointer) red_scale, "value_changed",
-                     G_CALLBACK(on_red_scale_value_changed),
-                     NULL);
-    g_signal_connect((gpointer) green_scale, "value_changed",
-                     G_CALLBACK(on_green_scale_value_changed),
-                     NULL);
-    g_signal_connect((gpointer) blue_scale, "value_changed",
-                     G_CALLBACK(on_blue_scale_value_changed),
-                     NULL);
-    g_signal_connect((gpointer) colorize_close, "clicked",
-                     G_CALLBACK(on_colorize_close_clicked),
-                     NULL);
-
-    gtk_range_set_value(GTK_RANGE(red_scale), cfg.colorize_r);
-    gtk_range_set_value(GTK_RANGE(green_scale), cfg.colorize_g);
-    gtk_range_set_value(GTK_RANGE(blue_scale), cfg.colorize_b);
-
-    gtk_widget_grab_default(colorize_close);
-    gtk_widget_show_all(colorize_settings);
-}
-
 void
 create_filepopup_settings(void)
 {
@@ -1938,100 +1645,6 @@
 }
 
 static void
-create_appearence_category(void)
-{
-    GtkWidget *appearance_page_vbox;
-    GtkWidget *vbox37;
-    GtkWidget *vbox38;
-    GtkWidget *hbox12;
-    GtkWidget *alignment94;
-    GtkWidget *hbox13;
-    GtkWidget *label103;
-    GtkWidget *colorspace_button;
-    GtkWidget *image11;
-    GtkWidget *image12;
-    GtkWidget *alignment95;
-    GtkWidget *skin_view_scrolled_window;
-
-    appearance_page_vbox = gtk_vbox_new (FALSE, 0);
-    gtk_container_add (GTK_CONTAINER (category_notebook), appearance_page_vbox);
-
-    vbox37 = gtk_vbox_new (FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (appearance_page_vbox), vbox37, TRUE, TRUE, 0);
-
-    vbox38 = gtk_vbox_new (FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (vbox37), vbox38, FALSE, TRUE, 0);
-
-    hbox12 = gtk_hbox_new (FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (vbox38), hbox12, TRUE, TRUE, 0);
-
-    alignment94 = gtk_alignment_new (0.5, 0.5, 1, 1);
-    gtk_box_pack_start (GTK_BOX (hbox12), alignment94, TRUE, TRUE, 0);
-    gtk_alignment_set_padding (GTK_ALIGNMENT (alignment94), 0, 4, 0, 0);
-
-    hbox13 = gtk_hbox_new (FALSE, 0);
-    gtk_container_add (GTK_CONTAINER (alignment94), hbox13);
-
-    label103 = gtk_label_new_with_mnemonic (_("<b>_Skin</b>"));
-    gtk_box_pack_start (GTK_BOX (hbox13), label103, TRUE, TRUE, 0);
-    gtk_label_set_use_markup (GTK_LABEL (label103), TRUE);
-    gtk_misc_set_alignment (GTK_MISC (label103), 0, 0);
-
-    colorspace_button = gtk_button_new ();
-    gtk_box_pack_start (GTK_BOX (hbox13), colorspace_button, FALSE, FALSE, 0);
-
-    image11 = gtk_image_new_from_stock ("gtk-properties", GTK_ICON_SIZE_BUTTON);
-    gtk_container_add (GTK_CONTAINER (colorspace_button), image11);
-
-    skin_refresh_button = gtk_button_new ();
-    gtk_box_pack_start (GTK_BOX (hbox13), skin_refresh_button, FALSE, FALSE, 0);
-    GTK_WIDGET_UNSET_FLAGS (skin_refresh_button, GTK_CAN_FOCUS);
-    gtk_tooltips_set_tip (tooltips, skin_refresh_button, _("Refresh skin list"), NULL);
-    gtk_button_set_relief (GTK_BUTTON (skin_refresh_button), GTK_RELIEF_HALF);
-    gtk_button_set_focus_on_click (GTK_BUTTON (skin_refresh_button), FALSE);
-
-    image12 = gtk_image_new_from_stock ("gtk-refresh", GTK_ICON_SIZE_BUTTON);
-    gtk_container_add (GTK_CONTAINER (skin_refresh_button), image12);
-
-    alignment95 = gtk_alignment_new (0.5, 0.5, 1, 1);
-    gtk_box_pack_start (GTK_BOX (vbox38), alignment95, TRUE, TRUE, 0);
-    gtk_widget_set_size_request (alignment95, -1, 172);
-    gtk_alignment_set_padding (GTK_ALIGNMENT (alignment95), 0, 0, 12, 0);
-
-    skin_view_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-    gtk_container_add (GTK_CONTAINER (alignment95), skin_view_scrolled_window);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (skin_view_scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
-    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (skin_view_scrolled_window), GTK_SHADOW_IN);
-
-    skin_view = gtk_tree_view_new ();
-    gtk_container_add (GTK_CONTAINER (skin_view_scrolled_window), skin_view);
-    gtk_widget_set_size_request (skin_view, -1, 100);
-
-    create_widgets(GTK_BOX(vbox37), appearance_misc_widgets, G_N_ELEMENTS(appearance_misc_widgets));
-
-
-
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label103), category_notebook);
-
-    g_signal_connect(G_OBJECT(colorspace_button), "clicked",
-                     G_CALLBACK(on_colorize_button_clicked),
-                     NULL);
-
-    g_signal_connect(skin_view, "drag-data-received",
-                     G_CALLBACK(on_skin_view_drag_data_received),
-                     NULL);
-    aud_drag_dest_set(skin_view);
-
-    g_signal_connect(mainwin, "drag-data-received",
-                     G_CALLBACK(mainwin_drag_data_received),
-                     skin_view);
-
-    g_signal_connect(skin_refresh_button, "clicked",
-                     G_CALLBACK(on_skin_refresh_button_clicked),
-                     NULL);
-}
-
-static void
 create_mouse_category(void)
 {
     GtkWidget *mouse_page_vbox;
@@ -3062,8 +2675,6 @@
 
 
 
-
-    create_appearence_category();
     create_audio_category();
     create_replay_gain_category();
     create_connectivity_category();
@@ -3109,12 +2720,6 @@
     g_signal_connect(G_OBJECT(prefswin), "delete_event",
                      G_CALLBACK(gtk_widget_hide_on_delete),
                      NULL);
-    g_signal_connect_swapped(G_OBJECT(skin_refresh_button), "clicked",
-                             G_CALLBACK(on_skin_refresh_button_clicked),
-                             prefswin);
-    g_signal_connect_after(G_OBJECT(skin_view), "realize",
-                           G_CALLBACK(on_skin_view_realize),
-                           NULL);
     g_signal_connect_swapped(G_OBJECT(close), "clicked",
                              G_CALLBACK(gtk_widget_hide),
                              GTK_OBJECT (prefswin));
@@ -3140,15 +2745,7 @@
 void
 show_prefs_window(void)
 {
-    static gboolean skinlist_filled = FALSE;
-
     gtk_window_present(GTK_WINDOW(prefswin)); /* show or raise prefs window */
-
-    if ( !skinlist_filled )
-    {
-        skin_view_update(GTK_TREE_VIEW(skin_view), GTK_WIDGET(skin_refresh_button));
-        skinlist_filled = TRUE;
-    }
 }
 
 void
--- a/src/audacious/ui_preferences.h	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_preferences.h	Wed Aug 06 22:33:27 2008 +0300
@@ -26,10 +26,5 @@
 
 gint prefswin_page_new(GtkWidget *container, gchar *name, gchar *imgurl);
 void prefswin_page_destroy(GtkWidget *container);
-void on_skin_view_drag_data_received(GtkWidget * widget,
-                                GdkDragContext * context,
-                                gint x, gint y,
-                                GtkSelectionData * selection_data,
-                                guint info, guint time,
-                                gpointer user_data);
+
 #endif /* AUDACIOUS_UI_PREFERENCES_H */
--- a/src/audacious/ui_skin.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2048 +0,0 @@
-/*  Audacious
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-/*#define AUD_DEBUG*/
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-/* TODO: enforce default sizes! */
-
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "ui_skin.h"
-#include "ui_equalizer.h"
-#include "main.h"
-#include "ui_playlist.h"
-#include "ui_skinselector.h"
-#include "util.h"
-
-#include "debug.h"
-
-#include "platform/smartinclude.h"
-#include "vfs.h"
-
-#include "ui_skinned_window.h"
-#include "ui_skinned_button.h"
-#include "ui_skinned_number.h"
-#include "ui_skinned_horizontal_slider.h"
-#include "ui_skinned_playstatus.h"
-
-#define EXTENSION_TARGETS 7
-
-static gchar *ext_targets[EXTENSION_TARGETS] =
-{ "bmp", "xpm", "png", "svg", "gif", "jpg", "jpeg" };
-
-struct _SkinPixmapIdMapping {
-    SkinPixmapId id;
-    const gchar *name;
-    const gchar *alt_name;
-    gint width, height;
-};
-
-struct _SkinMaskInfo {
-    gint width, height;
-    gchar *inistr;
-};
-
-typedef struct _SkinPixmapIdMapping SkinPixmapIdMapping;
-typedef struct _SkinMaskInfo SkinMaskInfo;
-
-
-Skin *aud_active_skin = NULL;
-
-static gint skin_current_num;
-
-static SkinMaskInfo skin_mask_info[] = {
-    {275, 116, "Normal"},
-    {275, 16,  "WindowShade"},
-    {275, 116, "Equalizer"},
-    {275, 16,  "EqualizerWS"}
-};
-
-static SkinPixmapIdMapping skin_pixmap_id_map[] = {
-    {SKIN_MAIN, "main", NULL, 0, 0},
-    {SKIN_CBUTTONS, "cbuttons", NULL, 0, 0},
-    {SKIN_SHUFREP, "shufrep", NULL, 0, 0},
-    {SKIN_TEXT, "text", NULL, 0, 0},
-    {SKIN_TITLEBAR, "titlebar", NULL, 0, 0},
-    {SKIN_VOLUME, "volume", NULL, 0, 0},
-    {SKIN_BALANCE, "balance", "volume", 0, 0},
-    {SKIN_MONOSTEREO, "monoster", NULL, 0, 0},
-    {SKIN_PLAYPAUSE, "playpaus", NULL, 0, 0},
-    {SKIN_NUMBERS, "nums_ex", "numbers", 0, 0},
-    {SKIN_POSBAR, "posbar", NULL, 0, 0},
-    {SKIN_EQMAIN, "eqmain", NULL, 0, 0},
-    {SKIN_PLEDIT, "pledit", NULL, 0, 0},
-    {SKIN_EQ_EX, "eq_ex", NULL, 0, 0}
-};
-
-static guint skin_pixmap_id_map_size = G_N_ELEMENTS(skin_pixmap_id_map);
-
-static const guchar skin_default_viscolor[24][3] = {
-    {9, 34, 53},
-    {10, 18, 26},
-    {0, 54, 108},
-    {0, 58, 116},
-    {0, 62, 124},
-    {0, 66, 132},
-    {0, 70, 140},
-    {0, 74, 148},
-    {0, 78, 156},
-    {0, 82, 164},
-    {0, 86, 172},
-    {0, 92, 184},
-    {0, 98, 196},
-    {0, 104, 208},
-    {0, 110, 220},
-    {0, 116, 232},
-    {0, 122, 244},
-    {0, 128, 255},
-    {0, 128, 255},
-    {0, 104, 208},
-    {0, 80, 160},
-    {0, 56, 112},
-    {0, 32, 64},
-    {200, 200, 200}
-};
-
-static gchar *original_gtk_theme = NULL;
-
-static GdkBitmap *skin_create_transparent_mask(const gchar *,
-                                               const gchar *,
-                                               const gchar *,
-                                               GdkWindow *,
-                                               gint, gint, gboolean);
-
-static void skin_set_default_vis_color(Skin * skin);
-
-void
-skin_lock(Skin * skin)
-{
-    g_mutex_lock(skin->lock);
-}
-
-void
-skin_unlock(Skin * skin)
-{
-    g_mutex_unlock(skin->lock);
-}
-
-gboolean
-aud_active_skin_reload(void) 
-{
-    AUDDBG("\n");
-    return aud_active_skin_load(aud_active_skin->path); 
-}
-
-gboolean
-aud_active_skin_load(const gchar * path)
-{
-    AUDDBG("%s\n", path);
-    g_return_val_if_fail(aud_active_skin != NULL, FALSE);
-
-    if (!skin_load(aud_active_skin, path)) {
-        AUDDBG("loading failed\n");
-        return FALSE;
-    }
-
-    ui_skinned_window_draw_all(mainwin);
-    ui_skinned_window_draw_all(equalizerwin);
-    ui_skinned_window_draw_all(playlistwin);
-
-    playlistwin_update_list(playlist_get_active());
-
-    SkinPixmap *pixmap;
-    pixmap = &aud_active_skin->pixmaps[SKIN_POSBAR];
-    /* last 59 pixels of SKIN_POSBAR are knobs (normal and selected) */
-    gtk_widget_set_size_request(mainwin_position, pixmap->width - 59, pixmap->height);
-
-    return TRUE;
-}
-
-void
-skin_pixmap_free(SkinPixmap * p)
-{
-    g_return_if_fail(p != NULL);
-    g_return_if_fail(p->pixbuf != NULL);
-
-    g_object_unref(p->pixbuf);
-    p->pixbuf = NULL;
-}
-
-Skin *
-skin_new(void)
-{
-    Skin *skin;
-    skin = g_new0(Skin, 1);
-    skin->lock = g_mutex_new();
-    return skin;
-}
-
-/**
- * Frees the data associated for skin.
- *
- * Does not free skin itself or lock variable so that the skin can immediately
- * populated with new skin data if needed.
- */
-void
-skin_free(Skin * skin)
-{
-    gint i;
-
-    g_return_if_fail(skin != NULL);
-
-    for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
-        skin_pixmap_free(&skin->pixmaps[i]);
-
-    for (i = 0; i < SKIN_MASK_COUNT; i++) {
-        if (skin->masks[i])
-            g_object_unref(skin->masks[i]);
-        if (skin->scaled_masks[i])
-            g_object_unref(skin->scaled_masks[i]);
-
-        skin->masks[i] = NULL;
-        skin->scaled_masks[i] = NULL;
-    }
-
-    for (i = 0; i < SKIN_COLOR_COUNT; i++) {
-        if (skin->colors[i])
-            g_free(skin->colors[i]);
-
-        skin->colors[i] = NULL;
-    }
-
-    g_free(skin->path);
-    skin->path = NULL;
-
-    skin_set_default_vis_color(skin);
-}
-
-void
-skin_destroy(Skin * skin)
-{
-    g_return_if_fail(skin != NULL);
-    skin_free(skin);
-    g_mutex_free(skin->lock);
-    g_free(skin);
-}
-
-const SkinPixmapIdMapping *
-skin_pixmap_id_lookup(guint id)
-{
-    guint i;
-
-    for (i = 0; i < skin_pixmap_id_map_size; i++) {
-        if (id == skin_pixmap_id_map[i].id) {
-            return &skin_pixmap_id_map[i];
-        }
-    }
-
-    return NULL;
-}
-
-const gchar *
-skin_pixmap_id_to_name(SkinPixmapId id)
-{
-    guint i;
-
-    for (i = 0; i < skin_pixmap_id_map_size; i++) {
-        if (id == skin_pixmap_id_map[i].id)
-            return skin_pixmap_id_map[i].name;
-    }
-    return NULL;
-}
-
-static void
-skin_set_default_vis_color(Skin * skin)
-{
-    memcpy(skin->vis_color, skin_default_viscolor,
-           sizeof(skin_default_viscolor));
-}
-
-/*
- * I have rewritten this to take an array of possible targets,
- * once we find a matching target we now return, instead of loop
- * recursively. This allows for us to support many possible format
- * targets for our skinning engine than just the original winamp 
- * formats.
- *
- *    -- nenolod, 16 January 2006
- */
-gchar *
-skin_pixmap_locate(const gchar * dirname, gchar ** basenames)
-{
-    gchar *filename;
-    gint i;
-
-    for (i = 0; basenames[i]; i++)
-    if (!(filename = find_path_recursively(dirname, basenames[i]))) 
-        g_free(filename);
-    else
-        return filename;
-
-    /* can't find any targets -- sorry */
-    return NULL;
-}
-
-/**
- * Creates possible file names for a pixmap.
- *
- * Basically this makes list of all possible file names that pixmap data
- * can be found from by using the static ext_targets variable to get all
- * possible extensions that pixmap file might have.
- */
-static gchar **
-skin_pixmap_create_basenames(const SkinPixmapIdMapping * pixmap_id_mapping)
-{
-    gchar **basenames = g_malloc0(sizeof(gchar*) * (EXTENSION_TARGETS * 2 + 1));
-    gint i, y;
-
-    // Create list of all possible image formats that can be loaded
-    for (i = 0, y = 0; i < EXTENSION_TARGETS; i++, y++)
-    {
-        basenames[y] =
-            g_strdup_printf("%s.%s", pixmap_id_mapping->name, ext_targets[i]);
-
-        if (pixmap_id_mapping->alt_name)
-            basenames[++y] =
-                g_strdup_printf("%s.%s", pixmap_id_mapping->alt_name,
-                                ext_targets[i]);
-    }
-
-    return basenames;
-}
-
-/**
- * Frees the data allocated by skin_pixmap_create_basenames
- */
-static void
-skin_pixmap_free_basenames(gchar ** basenames)
-{
-    int i;
-    for (i = 0; basenames[i] != NULL; i++)
-    {
-        g_free(basenames[i]);
-        basenames[i] = NULL;
-    }
-    g_free(basenames);
-}
-
-/**
- * Locates a pixmap file for skin.
- */
-static gchar *
-skin_pixmap_locate_basenames(const Skin * skin,
-                             const SkinPixmapIdMapping * pixmap_id_mapping,
-                             const gchar * path_p)
-{
-    gchar *filename = NULL;
-    const gchar *path = path_p ? path_p : skin->path;
-    gchar **basenames = skin_pixmap_create_basenames(pixmap_id_mapping);
-
-    filename = skin_pixmap_locate(path, basenames);
-
-    skin_pixmap_free_basenames(basenames);
-
-    return filename;
-}
-
-
-static gboolean
-skin_load_pixmap_id(Skin * skin, SkinPixmapId id, const gchar * path_p)
-{
-    const SkinPixmapIdMapping *pixmap_id_mapping;
-    gchar *filename;
-    SkinPixmap *pm = NULL;
-
-    g_return_val_if_fail(skin != NULL, FALSE);
-    g_return_val_if_fail(id < SKIN_PIXMAP_COUNT, FALSE);
-
-    pixmap_id_mapping = skin_pixmap_id_lookup(id);
-    g_return_val_if_fail(pixmap_id_mapping != NULL, FALSE);
-
-    filename = skin_pixmap_locate_basenames(skin, pixmap_id_mapping, path_p);
-
-    if (filename == NULL)
-        return FALSE;
-
-    AUDDBG("loaded %s\n", filename);
-
-    pm = &skin->pixmaps[id];
-    GdkPixbuf *pix = gdk_pixbuf_new_from_file(filename, NULL);
-    pm->pixbuf = audacious_create_colorized_pixbuf(pix, cfg.colorize_r, cfg.colorize_g, cfg.colorize_b);
-    g_object_unref(pix);
-    pm->width = gdk_pixbuf_get_width(pm->pixbuf);
-    pm->height = gdk_pixbuf_get_height(pm->pixbuf);
-    pm->current_width = pm->width;
-    pm->current_height = pm->height;
-
-    g_free(filename);
-
-    return TRUE;
-}
-
-void
-skin_mask_create(Skin * skin,
-                 const gchar * path,
-                 gint id,
-                 GdkWindow * window)
-{
-    skin->masks[id] =
-        skin_create_transparent_mask(path, "region.txt",
-                                     skin_mask_info[id].inistr, window,
-                                     skin_mask_info[id].width,
-                                     skin_mask_info[id].height, FALSE);
-
-    skin->scaled_masks[id] =
-        skin_create_transparent_mask(path, "region.txt",
-                                     skin_mask_info[id].inistr, window,
-                                     skin_mask_info[id].width * 2,
-                                     skin_mask_info[id].height * 2, TRUE);
-}
-
-static GdkBitmap *
-create_default_mask(GdkWindow * parent, gint w, gint h)
-{
-    GdkBitmap *ret;
-    GdkGC *gc;
-    GdkColor pattern;
-
-    ret = gdk_pixmap_new(parent, w, h, 1);
-    gc = gdk_gc_new(ret);
-    pattern.pixel = 1;
-    gdk_gc_set_foreground(gc, &pattern);
-    gdk_draw_rectangle(ret, gc, TRUE, 0, 0, w, h);
-    g_object_unref(gc);
-
-    return ret;
-}
-
-static void
-skin_query_color(GdkColormap * cm, GdkColor * c)
-{
-#ifdef GDK_WINDOWING_X11
-    XColor xc = { 0,0,0,0,0,0 };
-
-    xc.pixel = c->pixel;
-    XQueryColor(GDK_COLORMAP_XDISPLAY(cm), GDK_COLORMAP_XCOLORMAP(cm), &xc);
-    c->red = xc.red;
-    c->green = xc.green;
-    c->blue = xc.blue;
-#else
-    /* do nothing. see what breaks? */
-#endif
-}
-
-static glong
-skin_calc_luminance(GdkColor * c)
-{
-    return (0.212671 * c->red + 0.715160 * c->green + 0.072169 * c->blue);
-}
-
-static void
-skin_get_textcolors(GdkPixbuf * pix, GdkColor * bgc, GdkColor * fgc)
-{
-    /*
-     * Try to extract reasonable background and foreground colors
-     * from the font pixmap
-     */
-
-    GdkImage *gi;
-    GdkColormap *cm;
-    gint i;
-
-    g_return_if_fail(pix != NULL);
-
-    GdkPixmap *text = gdk_pixmap_new(NULL, gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix), gdk_rgb_get_visual()->depth);
-    gdk_draw_pixbuf(text, NULL, pix, 0, 0, 0, 0, gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix),
-                    GDK_RGB_DITHER_NONE, 0, 0);
-    /* Get the first line of text */
-    gi = gdk_drawable_get_image(text, 0, 0, 152, 6);
-    cm = gdk_colormap_get_system();
-
-    for (i = 0; i < 6; i++) {
-        GdkColor c;
-        gint x;
-        glong d, max_d;
-
-        /* Get a pixel from the middle of the space character */
-        bgc[i].pixel = gdk_image_get_pixel(gi, 151, i);
-        skin_query_color(cm, &bgc[i]);
-
-        max_d = 0;
-        for (x = 1; x < 150; x++) {
-            c.pixel = gdk_image_get_pixel(gi, x, i);
-            skin_query_color(cm, &c);
-
-            d = labs(skin_calc_luminance(&c) - skin_calc_luminance(&bgc[i]));
-            if (d > max_d) {
-                memcpy(&fgc[i], &c, sizeof(GdkColor));
-                max_d = d;
-            }
-        }
-    }
-    g_object_unref(gi);
-    g_object_unref(text);
-}
-
-gboolean
-init_skins(const gchar * path)
-{
-    aud_active_skin = skin_new();
-
-    skin_parse_hints(aud_active_skin, NULL);
-
-    /* create the windows if they haven't been created yet, needed for bootstrapping */
-    if (mainwin == NULL)
-    {
-        mainwin_create();
-        equalizerwin_create();
-        playlistwin_create();
-    }
-
-    if (!aud_active_skin_load(path)) {
-        if (path != NULL)
-            AUDDBG("Unable to load skin (%s), trying default...\n", path);
-        else
-            AUDDBG("Skin not defined: trying default...\n");
-
-        /* can't load configured skin, retry with default */
-        if (!aud_active_skin_load(BMP_DEFAULT_SKIN_PATH)) {
-            AUDDBG("Unable to load default skin (%s)! Giving up.\n",
-                      BMP_DEFAULT_SKIN_PATH);
-            return FALSE;
-        }
-    }
-
-    if (cfg.random_skin_on_play)
-        skinlist_update();
-
-    return TRUE;
-}
-
-void cleanup_skins()
-{
-    skin_destroy(aud_active_skin);
-    aud_active_skin = NULL;
-}
-
-
-/*
- * Opens and parses a skin's hints file.
- * Hints files are somewhat like "scripts" in Winamp3/5.
- * We'll probably add scripts to it next.
- */
-void
-skin_parse_hints(Skin * skin, gchar *path_p)
-{
-    gchar *filename, *tmp;
-    INIFile *inifile;
-
-    path_p = path_p ? path_p : skin->path;
-
-    skin->properties.mainwin_othertext = FALSE;
-    skin->properties.mainwin_vis_x = 24;
-    skin->properties.mainwin_vis_y = 43;
-    skin->properties.mainwin_vis_width = 76;
-    skin->properties.mainwin_text_x = 112;
-    skin->properties.mainwin_text_y = 27;
-    skin->properties.mainwin_text_width = 153;
-    skin->properties.mainwin_infobar_x = 112;
-    skin->properties.mainwin_infobar_y = 43;
-    skin->properties.mainwin_number_0_x = 36;
-    skin->properties.mainwin_number_0_y = 26;
-    skin->properties.mainwin_number_1_x = 48;
-    skin->properties.mainwin_number_1_y = 26;
-    skin->properties.mainwin_number_2_x = 60;
-    skin->properties.mainwin_number_2_y = 26;
-    skin->properties.mainwin_number_3_x = 78;
-    skin->properties.mainwin_number_3_y = 26;
-    skin->properties.mainwin_number_4_x = 90;
-    skin->properties.mainwin_number_4_y = 26;
-    skin->properties.mainwin_playstatus_x = 24;
-    skin->properties.mainwin_playstatus_y = 28;
-    skin->properties.mainwin_menurow_visible = TRUE;
-    skin->properties.mainwin_volume_x = 107;
-    skin->properties.mainwin_volume_y = 57;
-    skin->properties.mainwin_balance_x = 177;
-    skin->properties.mainwin_balance_y = 57;
-    skin->properties.mainwin_position_x = 16;
-    skin->properties.mainwin_position_y = 72;
-    skin->properties.mainwin_othertext_is_status = FALSE;
-    skin->properties.mainwin_othertext_visible = skin->properties.mainwin_othertext;
-    skin->properties.mainwin_text_visible = TRUE;
-    skin->properties.mainwin_vis_visible = TRUE;
-    skin->properties.mainwin_previous_x = 16;
-    skin->properties.mainwin_previous_y = 88;
-    skin->properties.mainwin_play_x = 39;
-    skin->properties.mainwin_play_y = 88;
-    skin->properties.mainwin_pause_x = 62;
-    skin->properties.mainwin_pause_y = 88;
-    skin->properties.mainwin_stop_x = 85;
-    skin->properties.mainwin_stop_y = 88;
-    skin->properties.mainwin_next_x = 108;
-    skin->properties.mainwin_next_y = 88;
-    skin->properties.mainwin_eject_x = 136;
-    skin->properties.mainwin_eject_y = 89;
-    skin->properties.mainwin_width = 275;
-    skin_mask_info[0].width = skin->properties.mainwin_width;
-    skin->properties.mainwin_height = 116;
-    skin_mask_info[0].height = skin->properties.mainwin_height;
-    skin->properties.mainwin_about_x = 247;
-    skin->properties.mainwin_about_y = 83;
-    skin->properties.mainwin_shuffle_x = 164;
-    skin->properties.mainwin_shuffle_y = 89;
-    skin->properties.mainwin_repeat_x = 210;
-    skin->properties.mainwin_repeat_y = 89;
-    skin->properties.mainwin_eqbutton_x = 219;
-    skin->properties.mainwin_eqbutton_y = 58;
-    skin->properties.mainwin_plbutton_x = 242;
-    skin->properties.mainwin_plbutton_y = 58;
-    skin->properties.textbox_bitmap_font_width = 5;
-    skin->properties.textbox_bitmap_font_height = 6;
-    skin->properties.mainwin_minimize_x = 244;
-    skin->properties.mainwin_minimize_y = 3;
-    skin->properties.mainwin_shade_x = 254;
-    skin->properties.mainwin_shade_y = 3;
-    skin->properties.mainwin_close_x = 264;
-    skin->properties.mainwin_close_y = 3;
-
-    if (path_p == NULL)
-        return;
-
-    filename = find_file_recursively(path_p, "skin.hints");
-
-    if (filename == NULL)
-        return;
-
-    inifile = open_ini_file(filename);
-    if (!inifile)
-        return;
-
-    tmp = read_ini_string(inifile, "skin", "mainwinOthertext");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_othertext = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinVisX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_vis_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinVisY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_vis_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinVisWidth");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_vis_width = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinTextX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_text_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinTextY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_text_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinTextWidth");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_text_width = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinInfoBarX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_infobar_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinInfoBarY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_infobar_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber0X");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_0_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber0Y");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_0_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber1X");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_1_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber1Y");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_1_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber2X");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_2_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber2Y");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_2_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber3X");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_3_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber3Y");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_3_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber4X");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_4_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNumber4Y");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_number_4_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPlayStatusX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_playstatus_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPlayStatusY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_playstatus_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinMenurowVisible");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_menurow_visible = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinVolumeX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_volume_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinVolumeY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_volume_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinBalanceX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_balance_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinBalanceY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_balance_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPositionX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_position_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPositionY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_position_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinOthertextIsStatus");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_othertext_is_status = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinOthertextVisible");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_othertext_visible = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinTextVisible");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_text_visible = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinVisVisible");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_vis_visible = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPreviousX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_previous_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPreviousY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_previous_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPlayX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_play_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPlayY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_play_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPauseX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_pause_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPauseY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_pause_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinStopX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_stop_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinStopY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_stop_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNextX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_next_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinNextY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_next_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinEjectX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_eject_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinEjectY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_eject_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinWidth");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_width = atoi(tmp);
-        g_free(tmp);
-    }
-
-    skin_mask_info[0].width = skin->properties.mainwin_width;
-
-    tmp = read_ini_string(inifile, "skin", "mainwinHeight");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_height = atoi(tmp);
-        g_free(tmp);
-    }
-
-    skin_mask_info[0].height = skin->properties.mainwin_height;
-
-    tmp = read_ini_string(inifile, "skin", "mainwinAboutX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_about_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinAboutY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_about_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinShuffleX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_shuffle_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinShuffleY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_shuffle_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinRepeatX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_repeat_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinRepeatY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_repeat_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinEQButtonX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_eqbutton_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinEQButtonY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_eqbutton_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPLButtonX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_plbutton_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinPLButtonY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_plbutton_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "textboxBitmapFontWidth");
-
-    if (tmp != NULL)
-    {
-        skin->properties.textbox_bitmap_font_width = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "textboxBitmapFontHeight");
-
-    if (tmp != NULL)
-    {
-        skin->properties.textbox_bitmap_font_height = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinMinimizeX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_minimize_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinMinimizeY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_minimize_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinShadeX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_shade_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinShadeY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_shade_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinCloseX");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_close_x = atoi(tmp);
-        g_free(tmp);
-    }
-
-    tmp = read_ini_string(inifile, "skin", "mainwinCloseY");
-
-    if (tmp != NULL)
-    {
-        skin->properties.mainwin_close_y = atoi(tmp);
-        g_free(tmp);
-    }
-
-    if (filename != NULL)
-        g_free(filename);
-
-    close_ini_file(inifile);
-}
-
-static guint
-hex_chars_to_int(gchar hi, gchar lo)
-{
-    /*
-     * Converts a value in the range 0x00-0xFF
-     * to a integer in the range 0-65535
-     */
-    gchar str[3];
-
-    str[0] = hi;
-    str[1] = lo;
-    str[2] = 0;
-
-    return (CLAMP(strtol(str, NULL, 16), 0, 0xFF) << 8);
-}
-
-static GdkColor *
-skin_load_color(INIFile *inifile,
-                const gchar * section, const gchar * key,
-                gchar * default_hex)
-{
-    gchar *value;
-    GdkColor *color = NULL;
-
-    if (inifile || default_hex) {
-        if (inifile) {
-            value = read_ini_string(inifile, section, key);
-            if (value == NULL) {
-                value = g_strdup(default_hex);
-            }
-        } else {
-            value = g_strdup(default_hex);
-        }
-        if (value) {
-            gchar *ptr = value;
-            gint len;
-
-            color = g_new0(GdkColor, 1);
-            g_strstrip(value);
-
-            if (value[0] == '#')
-                ptr++;
-            len = strlen(ptr);
-            /*
-             * The handling of incomplete values is done this way
-             * to maximize winamp compatibility
-             */
-            if (len >= 6) {
-                color->red = hex_chars_to_int(*ptr, *(ptr + 1));
-                ptr += 2;
-            }
-            if (len >= 4) {
-                color->green = hex_chars_to_int(*ptr, *(ptr + 1));
-                ptr += 2;
-            }
-            if (len >= 2)
-                color->blue = hex_chars_to_int(*ptr, *(ptr + 1));
-
-            g_free(value);
-        }
-    }
-    return color;
-}
-
-
-
-GdkBitmap *
-skin_create_transparent_mask(const gchar * path,
-                             const gchar * file,
-                             const gchar * section,
-                             GdkWindow * window,
-                             gint width,
-                             gint height, gboolean scale)
-{
-    GdkBitmap *mask = NULL;
-    GdkGC *gc = NULL;
-    GdkColor pattern;
-    GdkPoint *gpoints;
-
-    gchar *filename = NULL;
-    INIFile *inifile = NULL;
-    gboolean created_mask = FALSE;
-    GArray *num, *point;
-    guint i, j;
-    gint k;
-
-    if (path)
-        filename = find_file_recursively(path, file);
-
-    /* filename will be null if path wasn't set */
-    if (!filename)
-        return create_default_mask(window, width, height);
-
-    inifile = open_ini_file(filename);
-
-    if ((num = read_ini_array(inifile, section, "NumPoints")) == NULL) {
-        g_free(filename);
-        close_ini_file(inifile);
-        return NULL;
-    }
-
-    if ((point = read_ini_array(inifile, section, "PointList")) == NULL) {
-        g_array_free(num, TRUE);
-        g_free(filename);
-        close_ini_file(inifile);
-        return NULL;
-    }
-
-    close_ini_file(inifile);
-
-    mask = gdk_pixmap_new(window, width, height, 1);
-    gc = gdk_gc_new(mask);
-
-    pattern.pixel = 0;
-    gdk_gc_set_foreground(gc, &pattern);
-    gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height);
-    pattern.pixel = 1;
-    gdk_gc_set_foreground(gc, &pattern);
-
-    j = 0;
-    for (i = 0; i < num->len; i++) {
-        if ((int)(point->len - j) >= (g_array_index(num, gint, i) * 2)) {
-            created_mask = TRUE;
-            gpoints = g_new(GdkPoint, g_array_index(num, gint, i));
-            for (k = 0; k < g_array_index(num, gint, i); k++) {
-                gpoints[k].x =
-                    g_array_index(point, gint, j + k * 2) * (scale ? cfg.scale_factor : 1 );
-                gpoints[k].y =
-                    g_array_index(point, gint,
-                                  j + k * 2 + 1) * (scale ? cfg.scale_factor : 1);
-            }
-            j += k * 2;
-            gdk_draw_polygon(mask, gc, TRUE, gpoints,
-                             g_array_index(num, gint, i));
-            g_free(gpoints);
-        }
-    }
-    g_array_free(num, TRUE);
-    g_array_free(point, TRUE);
-    g_free(filename);
-
-    if (!created_mask)
-        gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height);
-
-    g_object_unref(gc);
-
-    return mask;
-}
-
-void
-skin_load_viscolor(Skin * skin, const gchar * path, const gchar * basename)
-{
-    VFSFile *file;
-    gint i, c;
-    gchar line[256], *filename;
-    GArray *a;
-
-    g_return_if_fail(skin != NULL);
-    g_return_if_fail(path != NULL);
-    g_return_if_fail(basename != NULL);
-
-    skin_set_default_vis_color(skin);
-
-    filename = find_file_recursively(path, basename);
-    if (!filename)
-        return;
-
-    if (!(file = vfs_fopen(filename, "r"))) {
-        g_free(filename);
-        return;
-    }
-
-    g_free(filename);
-
-    for (i = 0; i < 24; i++) {
-        if (vfs_fgets(line, 255, file)) {
-            a = string_to_garray(line);
-            if (a->len > 2) {
-                for (c = 0; c < 3; c++)
-                    skin->vis_color[i][c] = g_array_index(a, gint, c);
-            }
-            g_array_free(a, TRUE);
-        }
-        else
-            break;
-    }
-
-    vfs_fclose(file);
-}
-
-static void
-skin_numbers_generate_dash(Skin * skin)
-{
-    GdkPixbuf *pixbuf;
-    SkinPixmap *numbers;
-
-    g_return_if_fail(skin != NULL);
-
-    numbers = &skin->pixmaps[SKIN_NUMBERS];
-    if (!numbers->pixbuf || numbers->current_width < 99)
-        return;
-
-    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
-                            108, numbers->current_height);
-
-    skin_draw_pixbuf(NULL, skin, pixbuf, SKIN_NUMBERS, 0, 0, 0, 0, 99, numbers->current_height);
-    skin_draw_pixbuf(NULL, skin, pixbuf, SKIN_NUMBERS, 90, 0, 99, 0, 9, numbers->current_height);
-    skin_draw_pixbuf(NULL, skin, pixbuf, SKIN_NUMBERS, 20, 6, 101, 6, 5, 1);
-
-    g_object_unref(numbers->pixbuf);
-
-    numbers->pixbuf = pixbuf;
-    numbers->current_width = 108;
-    numbers->width = 108;
-}
-
-static gboolean
-skin_load_pixmaps(Skin * skin, const gchar * path)
-{
-    GdkPixbuf *text_pb;
-    guint i;
-    gchar *filename;
-    INIFile *inifile;
-    
-    if(!skin) return FALSE;
-    if(!path) return FALSE;
-
-    AUDDBG("Loading pixmaps in %s\n", path);
-
-    for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
-        if (!skin_load_pixmap_id(skin, i, path) && !cfg.allow_broken_skins)
-            return FALSE;
-
-    text_pb = skin->pixmaps[SKIN_TEXT].pixbuf;
-
-    if (text_pb)
-        skin_get_textcolors(text_pb, skin->textbg, skin->textfg);
-
-    if (skin->pixmaps[SKIN_NUMBERS].pixbuf &&
-        skin->pixmaps[SKIN_NUMBERS].width < 108 )
-        skin_numbers_generate_dash(skin);
-
-    filename = find_file_recursively(path, "pledit.txt");
-    inifile = open_ini_file(filename);
-
-    skin->colors[SKIN_PLEDIT_NORMAL] =
-        skin_load_color(inifile, "Text", "Normal", "#2499ff");
-    skin->colors[SKIN_PLEDIT_CURRENT] =
-        skin_load_color(inifile, "Text", "Current", "#ffeeff");
-    skin->colors[SKIN_PLEDIT_NORMALBG] =
-        skin_load_color(inifile, "Text", "NormalBG", "#0a120a");
-    skin->colors[SKIN_PLEDIT_SELECTEDBG] =
-        skin_load_color(inifile, "Text", "SelectedBG", "#0a124a");
-
-    if (inifile)
-        close_ini_file(inifile);
-
-    if (filename)
-        g_free(filename);
-
-    skin_mask_create(skin, path, SKIN_MASK_MAIN, mainwin->window);
-    skin_mask_create(skin, path, SKIN_MASK_MAIN_SHADE, mainwin->window);
-
-    skin_mask_create(skin, path, SKIN_MASK_EQ, equalizerwin->window);
-    skin_mask_create(skin, path, SKIN_MASK_EQ_SHADE, equalizerwin->window);
-
-    skin_load_viscolor(skin, path, "viscolor.txt");
-
-    return TRUE;
-}
-
-static void
-skin_set_gtk_theme(GtkSettings * settings, Skin * skin)
-{
-    if (original_gtk_theme == NULL)
-         g_object_get(settings, "gtk-theme-name", &original_gtk_theme, NULL);
-
-    /* the way GTK does things can be very broken. --nenolod */
-
-    gchar *tmp = g_strdup_printf("%s/.themes/aud-%s", g_get_home_dir(),
-                                 basename(skin->path));
-
-    gchar *troot = g_strdup_printf("%s/.themes", g_get_home_dir());
-    g_mkdir_with_parents(troot, 0755);
-    g_free(troot);
-
-    symlink(skin->path, tmp);
-    gtk_settings_set_string_property(settings, "gtk-theme-name",
-                                     basename(tmp), "audacious");
-    g_free(tmp);
-}
-
-/**
- * Checks if all pixmap files exist that skin needs.
- */
-static gboolean
-skin_check_pixmaps(const Skin * skin, const gchar * skin_path)
-{
-    guint i;
-    for (i = 0; i < SKIN_PIXMAP_COUNT; i++)
-    {
-        gchar *filename = skin_pixmap_locate_basenames(skin,
-                                                       skin_pixmap_id_lookup(i),
-                                                       skin_path);
-        if (!filename)
-            return FALSE;
-        g_free(filename);
-    }
-    return TRUE;
-}
-
-static gboolean
-skin_load_nolock(Skin * skin, const gchar * path, gboolean force)
-{
-    GtkSettings *settings;
-    gchar *gtkrcpath;
-    gchar *newpath, *skin_path;
-    int archive = 0;
-
-    AUDDBG("Attempt to load skin \"%s\"\n", path);
-
-    g_return_val_if_fail(skin != NULL, FALSE);
-    g_return_val_if_fail(path != NULL, FALSE);
-    REQUIRE_LOCK(skin->lock);
-
-    if (!g_file_test(path, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_DIR))
-        return FALSE;
-   
-    if(force) AUDDBG("reloading forced!\n");
-    if (!force && skin->path && !strcmp(skin->path, path)) {
-        AUDDBG("skin %s already loaded\n", path);
-        return FALSE;
-    }
-    
-    if (file_is_archive(path)) {
-        AUDDBG("Attempt to load archive\n");
-        if (!(skin_path = archive_decompress(path))) {
-            AUDDBG("Unable to extract skin archive (%s)\n", path);
-            return FALSE;
-        }
-        archive = 1;
-    } else {
-        skin_path = g_strdup(path);
-    }
-
-    // Check if skin path has all necessary files.
-    if (!cfg.allow_broken_skins && !skin_check_pixmaps(skin, skin_path)) {
-        if(archive) del_directory(skin_path);
-        g_free(skin_path);
-        AUDDBG("Skin path (%s) doesn't have all wanted pixmaps\n", skin_path);
-        return FALSE;
-    }
-
-    // skin_free() frees skin->path and variable path can actually be skin->path
-    // and we want to get the path before possibly freeing it.
-    newpath = g_strdup(path);
-    skin_free(skin);
-    skin->path = newpath;
-
-    memset(&(skin->properties), 0, sizeof(SkinProperties)); /* do it only if all tests above passed! --asphyx */
-    
-    skin_current_num++;
-
-    /* Parse the hints for this skin. */
-    skin_parse_hints(skin, skin_path);
-
-    if (!skin_load_pixmaps(skin, skin_path)) {
-        if(archive) del_directory(skin_path);
-        g_free(skin_path);
-        AUDDBG("Skin loading failed\n");
-        return FALSE;
-    }
-
-    /* restore gtk theme if changed by previous skin */
-    settings = gtk_settings_get_default();
-
-    if (original_gtk_theme != NULL) {
-        gtk_settings_set_string_property(settings, "gtk-theme-name",
-                                              original_gtk_theme, "audacious");
-        g_free(original_gtk_theme);
-        original_gtk_theme = NULL;
-    }
-
-#ifndef _WIN32
-    if (!cfg.disable_inline_gtk && !archive) {
-        gtkrcpath = find_path_recursively(skin->path, "gtkrc");
-        if (gtkrcpath != NULL)
-            skin_set_gtk_theme(settings, skin);
-        g_free(gtkrcpath);
-    }
-#endif
-
-    if(archive) del_directory(skin_path);
-    g_free(skin_path);
-
-    gtk_widget_shape_combine_mask(mainwin, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
-    gtk_widget_shape_combine_mask(equalizerwin, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
-
-    return TRUE;
-}
-
-void
-skin_install_skin(const gchar * path)
-{
-    gchar *command;
-
-    g_return_if_fail(path != NULL);
-
-    command = g_strdup_printf("cp %s %s",
-                              path, aud_paths[BMP_PATH_USER_SKIN_DIR]);
-    if (system(command)) {
-        AUDDBG("Unable to install skin (%s) into user directory (%s)\n",
-                  path, aud_paths[BMP_PATH_USER_SKIN_DIR]);
-    }
-    g_free(command);
-}
-
-static SkinPixmap *
-skin_get_pixmap(Skin * skin, SkinPixmapId map_id)
-{
-    g_return_val_if_fail(skin != NULL, NULL);
-    g_return_val_if_fail(map_id < SKIN_PIXMAP_COUNT, NULL);
-
-    return &skin->pixmaps[map_id];
-}
-
-gboolean
-skin_load(Skin * skin, const gchar * path)
-{
-    gboolean ret;
-
-    g_return_val_if_fail(skin != NULL, FALSE);
-
-    if (!path)
-        return FALSE;
-
-    skin_lock(skin);
-    ret = skin_load_nolock(skin, path, FALSE);
-    skin_unlock(skin);
-
-    if(!ret) {
-        AUDDBG("loading failed\n");
-        return FALSE; /* don't try to update anything if loading failed --asphyx */
-    }
-
-    SkinPixmap *pixmap = NULL;
-    pixmap = skin_get_pixmap(skin, SKIN_NUMBERS);
-    if (pixmap) {
-        ui_skinned_number_set_size(mainwin_minus_num, 9, pixmap->height);
-        ui_skinned_number_set_size(mainwin_10min_num, 9, pixmap->height);
-        ui_skinned_number_set_size(mainwin_min_num, 9, pixmap->height);
-        ui_skinned_number_set_size(mainwin_10sec_num, 9, pixmap->height);
-        ui_skinned_number_set_size(mainwin_sec_num, 9, pixmap->height);
-    }
-
-    pixmap = skin_get_pixmap(skin, SKIN_MAIN);
-    if (pixmap && skin->properties.mainwin_height > pixmap->height)
-        skin->properties.mainwin_height = pixmap->height;
-
-    pixmap = skin_get_pixmap(skin, SKIN_PLAYPAUSE);
-    if (pixmap)
-        ui_skinned_playstatus_set_size(mainwin_playstatus, 11, pixmap->height);
-
-    pixmap = skin_get_pixmap(skin, SKIN_EQMAIN);
-    if (pixmap->height >= 313)
-        gtk_widget_show(equalizerwin_graph);
-
-    return TRUE;
-}
-
-gboolean
-skin_reload_forced(void) 
-{
-   gboolean error;
-   AUDDBG("\n");
-
-   skin_lock(aud_active_skin);
-   error = skin_load_nolock(aud_active_skin, aud_active_skin->path, TRUE);
-   skin_unlock(aud_active_skin);
-
-   return error;
-}
-
-void
-skin_reload(Skin * skin)
-{
-    AUDDBG("\n");
-    g_return_if_fail(skin != NULL);
-    skin_load_nolock(skin, skin->path, TRUE);
-}
-
-GdkBitmap *
-skin_get_mask(Skin * skin, SkinMaskId mi)
-{
-    GdkBitmap **masks;
-
-    g_return_val_if_fail(skin != NULL, NULL);
-    g_return_val_if_fail(mi < SKIN_PIXMAP_COUNT, NULL);
-
-    masks = cfg.scaled ? skin->scaled_masks : skin->masks;
-    return masks[mi];
-}
-
-GdkColor *
-skin_get_color(Skin * skin, SkinColorId color_id)
-{
-    GdkColor *ret = NULL;
-
-    g_return_val_if_fail(skin != NULL, NULL);
-
-    switch (color_id) {
-    case SKIN_TEXTBG:
-        if (skin->pixmaps[SKIN_TEXT].pixbuf)
-            ret = skin->textbg;
-        else
-            ret = skin->def_textbg;
-        break;
-    case SKIN_TEXTFG:
-        if (skin->pixmaps[SKIN_TEXT].pixbuf)
-            ret = skin->textfg;
-        else
-            ret = skin->def_textfg;
-        break;
-    default:
-        if (color_id < SKIN_COLOR_COUNT)
-            ret = skin->colors[color_id];
-        break;
-    }
-    return ret;
-}
-
-void
-skin_get_viscolor(Skin * skin, guchar vis_color[24][3])
-{
-    gint i;
-
-    g_return_if_fail(skin != NULL);
-
-    for (i = 0; i < 24; i++) {
-        vis_color[i][0] = skin->vis_color[i][0];
-        vis_color[i][1] = skin->vis_color[i][1];
-        vis_color[i][2] = skin->vis_color[i][2];
-    }
-}
-
-gint
-skin_get_id(void)
-{
-    return skin_current_num;
-}
-
-void
-skin_draw_pixbuf(GtkWidget *widget, Skin * skin, GdkPixbuf * pix,
-                 SkinPixmapId pixmap_id,
-                 gint xsrc, gint ysrc, gint xdest, gint ydest,
-                 gint width, gint height)
-{
-    SkinPixmap *pixmap;
-
-    g_return_if_fail(skin != NULL);
-
-    pixmap = skin_get_pixmap(skin, pixmap_id);
-    g_return_if_fail(pixmap != NULL);
-    g_return_if_fail(pixmap->pixbuf != NULL);
-
-    /* perhaps we should use transparency or resize widget? */
-    if (xsrc+width > pixmap->width || ysrc+height > pixmap->height) {
-        if (widget) {
-            /* it's better to hide widget using SKIN_PLAYPAUSE/SKIN_POSBAR than display mess */
-            if ((pixmap_id == SKIN_PLAYPAUSE && pixmap->width != 42) || pixmap_id == SKIN_POSBAR) {
-                gtk_widget_hide(widget);
-                return;
-            }
-            gint x, y;
-            x = -1;
-            y = -1;
-
-            if (gtk_widget_get_parent(widget) == SKINNED_WINDOW(mainwin)->fixed) {
-                GList *iter;
-                for (iter = GTK_FIXED (SKINNED_WINDOW(mainwin)->fixed)->children; iter; iter = g_list_next (iter)) {
-                     GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
-                     if (child_data->widget == widget) {
-                         x = child_data->x;
-                         y = child_data->y;
-                         break;
-                     }
-                }
-
-                if (x != -1 && y != -1) {
-                    /* Some skins include SKIN_VOLUME and/or SKIN_BALANCE
-                       without knobs */
-                    if (pixmap_id == SKIN_VOLUME || pixmap_id == SKIN_BALANCE) {
-                        if (ysrc+height > 421 && xsrc+width <= pixmap->width)
-                            return;
-                    }
-                    /* let's copy what's under widget */
-                    gdk_pixbuf_copy_area(skin_get_pixmap(aud_active_skin, SKIN_MAIN)->pixbuf,
-                                         x, y, width, height, pix, xdest, ydest);
-
-                    /* XMMS skins seems to have SKIN_MONOSTEREO with size 58x20 instead of 58x24 */
-                    if (pixmap_id == SKIN_MONOSTEREO)
-                        height = pixmap->height/2;
-                }
-            } else if (gtk_widget_get_parent(widget) == SKINNED_WINDOW(equalizerwin)->fixed) {
-                   if (!(pixmap_id == SKIN_EQMAIN && ysrc == 314)) /* equalizer preamp on equalizer graph */
-                         gtk_widget_hide(widget);
-            } else if (gtk_widget_get_parent(widget) == SKINNED_WINDOW(playlistwin)->fixed) {
-                   /* I haven't seen any skin with substandard playlist */
-                   gtk_widget_hide(widget);
-            }
-        } else
-            return;
-    }
-
-    width = MIN(width, pixmap->width - xsrc);
-    height = MIN(height, pixmap->height - ysrc);
-    gdk_pixbuf_copy_area(pixmap->pixbuf, xsrc, ysrc, width, height,
-                         pix, xdest, ydest);
-}
-
-void
-skin_get_eq_spline_colors(Skin * skin, guint32 colors[19])
-{
-    gint i;
-    GdkPixbuf *pixbuf;
-    SkinPixmap *eqmainpm;
-    guchar* pixels,*p;
-    guint rowstride, n_channels;
-    g_return_if_fail(skin != NULL);
-
-    eqmainpm = &skin->pixmaps[SKIN_EQMAIN];
-    if (eqmainpm->pixbuf &&
-            eqmainpm->current_width >= 116 && eqmainpm->current_height >= 313)
-        pixbuf = eqmainpm->pixbuf;
-    else
-        return;
-
-    if (!GDK_IS_PIXBUF(pixbuf))
-        return;
-
-    pixels = gdk_pixbuf_get_pixels (pixbuf);
-    rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-    n_channels = gdk_pixbuf_get_n_channels (pixbuf);
-    for (i = 0; i < 19; i++)
-    {
-        p = pixels + rowstride * (i + 294) + 115 * n_channels;
-        colors[i] = (p[0] << 16) | (p[1] << 8) | p[2]; 
-        /* should we really treat the Alpha channel? */
-        /*if (n_channels == 4)
-            colors[i] = (colors[i] << 8) | p[3];*/
-    }
-}
-
-
-static void
-skin_draw_playlistwin_frame_top(Skin * skin, GdkPixbuf * pix,
-                                gint width, gint height, gboolean focus)
-{
-    /* The title bar skin consists of 2 sets of 4 images, 1 set
-     * for focused state and the other for unfocused. The 4 images
-     * are: 
-     *
-     * a. right corner (25,20)
-     * b. left corner  (25,20)
-     * c. tiler        (25,20)
-     * d. title        (100,20)
-     * 
-     * min allowed width = 100+25+25 = 150
-     */
-
-    gint i, y, c;
-
-    /* get y offset of the pixmap set to use */
-    if (focus)
-        y = 0;
-    else
-        y = 21;
-
-    /* left corner */
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 0, y, 0, 0, 25, 20);
-
-    /* titlebar title */
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 26, y,
-                     (width - 100) / 2, 0, 100, 20);
-
-    /* titlebar right corner  */
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 153, y,
-                     width - 25, 0, 25, 20);
-
-    /* tile draw the remaining frame */
-
-    /* compute tile count */
-    c = (width - (100 + 25 + 25)) / 25;
-
-    for (i = 0; i < c / 2; i++) {
-        /* left of title */
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
-                         25 + i * 25, 0, 25, 20);
-
-        /* right of title */
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
-                         (width + 100) / 2 + i * 25, 0, 25, 20);
-    }
-
-    if (c & 1) {
-        /* Odd tile count, so one remaining to draw. Here we split
-         * it into two and draw half on either side of the title */
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
-                         ((c / 2) * 25) + 25, 0, 12, 20);
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 127, y,
-                         (width / 2) + ((c / 2) * 25) + 50, 0, 13, 20);
-    }
-}
-
-static void
-skin_draw_playlistwin_frame_bottom(Skin * skin, GdkPixbuf * pix,
-                                   gint width, gint height, gboolean focus)
-{
-    /* The bottom frame skin consists of 1 set of 4 images. The 4
-     * images are:
-     *
-     * a. left corner with menu buttons (125,38)
-     * b. visualization window (75,38)
-     * c. right corner with play buttons (150,38)
-     * d. frame tile (25,38)
-     * 
-     * (min allowed width = 125+150+25=300
-     */
-
-    gint i, c;
-
-    /* bottom left corner (menu buttons) */
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 0, 72,
-                     0, height - 38, 125, 38);
-
-    c = (width - 275) / 25;
-
-    /* draw visualization window, if width allows */
-    if (c >= 3) {
-        c -= 3;
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 205, 0,
-                         width - (150 + 75), height - 38, 75, 38);
-    }
-
-    /* Bottom right corner (playbuttons etc) */
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT,
-                     126, 72, width - 150, height - 38, 150, 38);
-
-    /* Tile draw the remaining undrawn portions */
-    for (i = 0; i < c; i++)
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 179, 0,
-                         125 + i * 25, height - 38, 25, 38);
-}
-
-static void
-skin_draw_playlistwin_frame_sides(Skin * skin, GdkPixbuf * pix,
-                                  gint width, gint height, gboolean focus)
-{
-    /* The side frames consist of 2 tile images. 1 for the left, 1 for
-     * the right. 
-     * a. left  (12,29)
-     * b. right (19,29)
-     */
-
-    gint i;
-
-    /* frame sides */
-    for (i = 0; i < (height - (20 + 38)) / 29; i++) {
-        /* left */
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 0, 42,
-                         0, 20 + i * 29, 12, 29);
-
-        /* right */
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 32, 42,
-                         width - 19, 20 + i * 29, 19, 29);
-    }
-}
-
-
-void
-skin_draw_playlistwin_frame(Skin * skin, GdkPixbuf * pix,
-                            gint width, gint height, gboolean focus)
-{
-    skin_draw_playlistwin_frame_top(skin, pix, width, height, focus);
-    skin_draw_playlistwin_frame_bottom(skin, pix, width, height, focus);
-    skin_draw_playlistwin_frame_sides(skin, pix, width, height, focus);
-}
-
-
-void
-skin_draw_playlistwin_shaded(Skin * skin, GdkPixbuf * pix,
-                             gint width, gboolean focus)
-{
-    /* The shade mode titlebar skin consists of 4 images:
-     * a) left corner               offset (72,42) size (25,14)
-     * b) right corner, focused     offset (99,57) size (50,14)
-     * c) right corner, unfocused   offset (99,42) size (50,14)
-     * d) bar tile                  offset (72,57) size (25,14)
-     */
-
-    gint i;
-
-    /* left corner */
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 72, 42, 0, 0, 25, 14);
-
-    /* bar tile */
-    for (i = 0; i < (width - 75) / 25; i++)
-        skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 72, 57,
-                         (i * 25) + 25, 0, 25, 14);
-
-    /* right corner */
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_PLEDIT, 99, focus ? 42 : 57,
-                     width - 50, 0, 50, 14);
-}
-
-
-void
-skin_draw_mainwin_titlebar(Skin * skin, GdkPixbuf * pix,
-                           gboolean shaded, gboolean focus)
-{
-    /* The titlebar skin consists of 2 sets of 2 images, one for for
-     * shaded and the other for unshaded mode, giving a total of 4.
-     * The images are exactly 275x14 pixels, aligned and arranged
-     * vertically on each other in the pixmap in the following order:
-     * 
-     * a) unshaded, focused      offset (27, 0)
-     * b) unshaded, unfocused    offset (27, 15)
-     * c) shaded, focused        offset (27, 29)
-     * d) shaded, unfocused      offset (27, 42)
-     */
-
-    gint y_offset;
-
-    if (shaded) {
-        if (focus)
-            y_offset = 29;
-        else
-            y_offset = 42;
-    }
-    else {
-        if (focus)
-            y_offset = 0;
-        else
-            y_offset = 15;
-    }
-
-    skin_draw_pixbuf(NULL, skin, pix, SKIN_TITLEBAR, 27, y_offset,
-                     0, 0, aud_active_skin->properties.mainwin_width, MAINWIN_TITLEBAR_HEIGHT);
-}
-
-
-void
-skin_set_random_skin(void)
-{
-    SkinNode *node;
-    guint32 randval;
-
-    /* Get a random value to select the skin to use */
-    randval = g_random_int_range(0, g_list_length(skinlist));
-    node = g_list_nth(skinlist, randval)->data;
-    aud_active_skin_load(node->path);
-}
-
-
-void ui_skinned_widget_draw(GtkWidget *widget, GdkPixbuf *obj, gint width, gint height, gboolean scale) {
-    g_return_if_fail(widget != NULL);
-    g_return_if_fail(obj != NULL);
-
-    if (scale) {
-        gint s_width = width * cfg.scale_factor,
-             s_height = height * cfg.scale_factor;
-        GdkPixbuf *image = gdk_pixbuf_scale_simple(obj, s_width, s_height, GDK_INTERP_NEAREST);
-        gdk_draw_pixbuf(widget->window, NULL, image, 0, 0, 0, 0, s_width, s_height, GDK_RGB_DITHER_NONE, 0, 0);
-        g_object_unref(image);
-    } else {
-        gdk_draw_pixbuf(widget->window, NULL, obj, 0, 0, 0, 0, width, height, GDK_RGB_DITHER_NONE, 0, 0);
-    }
-}
--- a/src/audacious/ui_skin.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +0,0 @@
-/*  Audacious
- *  Copyright (C) 2005-2007  Audacious development team.
- *
- *  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKIN_H
-#define AUDACIOUS_UI_SKIN_H
-
-#include <glib.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-#include "audconfig.h"
-
-#define BMP_DEFAULT_SKIN_PATH \
-  DATA_DIR G_DIR_SEPARATOR_S "Skins" G_DIR_SEPARATOR_S "Default"
-
-
-typedef enum {
-    SKIN_MAIN = 0,
-    SKIN_CBUTTONS,
-    SKIN_TITLEBAR,
-    SKIN_SHUFREP,
-    SKIN_TEXT,
-    SKIN_VOLUME,
-    SKIN_BALANCE,
-    SKIN_MONOSTEREO,
-    SKIN_PLAYPAUSE,
-    SKIN_NUMBERS,
-    SKIN_POSBAR,
-    SKIN_PLEDIT,
-    SKIN_EQMAIN,
-    SKIN_EQ_EX,
-    SKIN_PIXMAP_COUNT
-} SkinPixmapId;
-
-typedef enum {
-    SKIN_MASK_MAIN = 0,
-    SKIN_MASK_MAIN_SHADE,
-    SKIN_MASK_EQ,
-    SKIN_MASK_EQ_SHADE,
-    SKIN_MASK_COUNT
-} SkinMaskId;
-
-typedef enum {
-    SKIN_PLEDIT_NORMAL = 0,
-    SKIN_PLEDIT_CURRENT,
-    SKIN_PLEDIT_NORMALBG,
-    SKIN_PLEDIT_SELECTEDBG,
-    SKIN_TEXTBG,
-    SKIN_TEXTFG,
-    SKIN_COLOR_COUNT
-} SkinColorId;
-
-typedef struct _SkinProperties {
-	/* this enables the othertext engine, not it's visibility -nenolod */
-	gboolean mainwin_othertext;
-
-	/* Vis properties */
-	gint mainwin_vis_x;
-	gint mainwin_vis_y;
-	gint mainwin_vis_width;
-	gboolean mainwin_vis_visible;
-
-	/* Text properties */
-	gint mainwin_text_x;
-	gint mainwin_text_y;
-	gint mainwin_text_width;
-	gboolean mainwin_text_visible;
-
-	/* Infobar properties */
-	gint mainwin_infobar_x;
-	gint mainwin_infobar_y;
-	gboolean mainwin_othertext_visible;
-
-	gint mainwin_number_0_x;
-	gint mainwin_number_0_y;
-
-	gint mainwin_number_1_x;
-	gint mainwin_number_1_y;
-
-	gint mainwin_number_2_x;
-	gint mainwin_number_2_y;
-
-	gint mainwin_number_3_x;
-	gint mainwin_number_3_y;
-
-	gint mainwin_number_4_x;
-	gint mainwin_number_4_y;
-
-	gint mainwin_playstatus_x;
-	gint mainwin_playstatus_y;
-
-	gint mainwin_volume_x;
-	gint mainwin_volume_y;	
-
-	gint mainwin_balance_x;
-	gint mainwin_balance_y;	
-
-	gint mainwin_position_x;
-	gint mainwin_position_y;
-
-	gint mainwin_previous_x;
-	gint mainwin_previous_y;
-
-	gint mainwin_play_x;
-	gint mainwin_play_y;
-
-	gint mainwin_pause_x;
-	gint mainwin_pause_y;
-
-	gint mainwin_stop_x;
-	gint mainwin_stop_y;
-
-	gint mainwin_next_x;
-	gint mainwin_next_y;
-
-	gint mainwin_eject_x;
-	gint mainwin_eject_y;
-
-	gint mainwin_eqbutton_x;
-	gint mainwin_eqbutton_y;
-
-	gint mainwin_plbutton_x;
-	gint mainwin_plbutton_y;
-
-	gint mainwin_shuffle_x;
-	gint mainwin_shuffle_y;
-
-	gint mainwin_repeat_x;
-	gint mainwin_repeat_y;
-
-	gint mainwin_about_x;
-	gint mainwin_about_y;
-
-	gint mainwin_minimize_x;
-	gint mainwin_minimize_y;
-
-	gint mainwin_shade_x;
-	gint mainwin_shade_y;
-
-	gint mainwin_close_x;
-	gint mainwin_close_y;
-
-	gint mainwin_width;
-	gint mainwin_height;
-
-	gboolean mainwin_menurow_visible;
-	gboolean mainwin_othertext_is_status;
-
-	gint textbox_bitmap_font_width;
-	gint textbox_bitmap_font_height;
-} SkinProperties;
-
-#define SKIN_PIXMAP(x)  ((SkinPixmap *)(x))
-typedef struct _SkinPixmap {
-    GdkPixbuf *pixbuf;
-
-    /* The real size of the pixmap */
-    gint width, height;
-
-    /* The size of the pixmap from the current skin,
-       which might be smaller */
-    gint current_width, current_height;
-} SkinPixmap;
-
-
-#define SKIN(x)  ((Skin *)(x))
-typedef struct _Skin {
-    GMutex *lock;
-    gchar *path;
-    gchar *def_path;
-    SkinPixmap pixmaps[SKIN_PIXMAP_COUNT];
-    GdkColor textbg[6], def_textbg[6];
-    GdkColor textfg[6], def_textfg[6];
-    GdkColor *colors[SKIN_COLOR_COUNT];
-    guchar vis_color[24][3];
-    GdkBitmap *masks[SKIN_MASK_COUNT];
-    GdkBitmap *scaled_masks[SKIN_MASK_COUNT];
-    SkinProperties properties;
-} Skin;
-
-extern Skin *aud_active_skin;
-
-gboolean init_skins(const gchar * path);
-void cleanup_skins(void);
-
-gboolean aud_active_skin_load(const gchar * path);
-gboolean aud_active_skin_reload(void);
-
-Skin *skin_new(void);
-gboolean skin_load(Skin * skin, const gchar * path);
-gboolean skin_reload_forced(void);
-void skin_reload(Skin * skin);
-void skin_free(Skin * skin);
-
-GdkBitmap *skin_get_mask(Skin * skin, SkinMaskId mi);
-GdkColor *skin_get_color(Skin * skin, SkinColorId color_id);
-
-void skin_get_viscolor(Skin * skin, guchar vis_color[24][3]);
-gint skin_get_id(void);
-void skin_draw_pixbuf(GtkWidget *widget, Skin * skin, GdkPixbuf * pix,
-                 SkinPixmapId pixmap_id,
-                 gint xsrc, gint ysrc, gint xdest, gint ydest,
-                 gint width, gint height);
-
-void skin_get_eq_spline_colors(Skin * skin, guint32 colors[19]);
-void skin_install_skin(const gchar * path);
-
-void skin_draw_playlistwin_shaded(Skin * skin, GdkPixbuf * pix,
-                                  gint width, gboolean focus);
-void skin_draw_playlistwin_frame(Skin * skin, GdkPixbuf * pix,
-                                 gint width, gint height, gboolean focus);
-
-void skin_draw_mainwin_titlebar(Skin * skin, GdkPixbuf * pix,
-                                gboolean shaded, gboolean focus);
-
-
-void skin_parse_hints(Skin * skin, gchar *path_p);
-
-
-void skin_set_random_skin(void);
-
-
-void ui_skinned_widget_draw(GtkWidget *widget, GdkPixbuf *obj, gint width, gint height, gboolean scale);
-
-#endif /* AUDACIOUS_UI_SKIN_H */
--- a/src/audacious/ui_skinned_button.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,535 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skinned_button.h"
-#include <math.h>
-
-#define UI_SKINNED_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_button_get_type(), UiSkinnedButtonPrivate))
-typedef struct _UiSkinnedButtonPrivate UiSkinnedButtonPrivate;
-
-enum {
-    PRESSED,
-    RELEASED,
-    CLICKED,
-    DOUBLED,
-    REDRAW,
-    LAST_SIGNAL
-};
-
-struct _UiSkinnedButtonPrivate {
-    //Skinned part
-    GdkGC            *gc;
-    gint             w;
-    gint             h;
-    SkinPixmapId     skin_index1;
-    SkinPixmapId     skin_index2;
-    gboolean         scaled;
-    gint             move_x, move_y;
-
-    gint             nx, ny, px, py;
-    //Toogle button needs also those
-    gint             pnx, pny, ppx, ppy;
-};
-
-
-static GtkWidgetClass *parent_class = NULL;
-static void ui_skinned_button_class_init(UiSkinnedButtonClass *klass);
-static void ui_skinned_button_init(UiSkinnedButton *button);
-static void ui_skinned_button_destroy(GtkObject *object);
-static void ui_skinned_button_realize(GtkWidget *widget);
-static void ui_skinned_button_unrealize(GtkWidget *widget);
-static void ui_skinned_button_map(GtkWidget *widget);
-static void ui_skinned_button_unmap(GtkWidget *widget);
-static void ui_skinned_button_size_request(GtkWidget *widget, GtkRequisition *requisition);
-static gint ui_skinned_button_expose(GtkWidget *widget,GdkEventExpose *event);
-
-static void ui_skinned_button_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
-static void ui_skinned_button_update_state(UiSkinnedButton *button);
-
-static guint button_signals[LAST_SIGNAL] = { 0 };
-static gint ui_skinned_button_button_press(GtkWidget *widget, GdkEventButton *event);
-static gint ui_skinned_button_button_release(GtkWidget *widget, GdkEventButton *event);
-static void button_pressed(UiSkinnedButton *button);
-static void button_released(UiSkinnedButton *button);
-static void ui_skinned_button_pressed(UiSkinnedButton *button);
-static void ui_skinned_button_released(UiSkinnedButton *button);
-static void ui_skinned_button_clicked(UiSkinnedButton *button);
-static void ui_skinned_button_set_pressed (UiSkinnedButton *button, gboolean pressed);
-
-static void ui_skinned_button_toggle_scaled(UiSkinnedButton *button);
-
-static gint ui_skinned_button_enter_notify(GtkWidget *widget, GdkEventCrossing *event);
-static gint ui_skinned_button_leave_notify(GtkWidget *widget, GdkEventCrossing *event);
-static void ui_skinned_button_redraw(UiSkinnedButton *button);
-
-GType ui_skinned_button_get_type() {
-    static GType button_type = 0;
-    if (!button_type) {
-        static const GTypeInfo button_info = {
-            sizeof (UiSkinnedButtonClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_button_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedButton),
-            0,
-            (GInstanceInitFunc) ui_skinned_button_init,
-        };
-        button_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedButton_", &button_info, 0);
-    }
-
-    return button_type;
-}
-
-static void ui_skinned_button_class_init (UiSkinnedButtonClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_button_destroy;
-
-    widget_class->realize = ui_skinned_button_realize;
-    widget_class->unrealize = ui_skinned_button_unrealize;
-    widget_class->map = ui_skinned_button_map;
-    widget_class->unmap = ui_skinned_button_unmap;
-    widget_class->expose_event = ui_skinned_button_expose;
-    widget_class->size_request = ui_skinned_button_size_request;
-    widget_class->size_allocate = ui_skinned_button_size_allocate;
-    widget_class->button_press_event = ui_skinned_button_button_press;
-    widget_class->button_release_event = ui_skinned_button_button_release;
-    widget_class->enter_notify_event = ui_skinned_button_enter_notify;
-    widget_class->leave_notify_event = ui_skinned_button_leave_notify;
-
-    klass->pressed = button_pressed;
-    klass->released = button_released;
-    klass->clicked = NULL;
-    klass->scaled = ui_skinned_button_toggle_scaled;
-    klass->redraw = ui_skinned_button_redraw;
-
-    button_signals[PRESSED] = 
-        g_signal_new ("pressed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST,
-                      G_STRUCT_OFFSET (UiSkinnedButtonClass, pressed), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    button_signals[RELEASED] = 
-        g_signal_new ("released", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST,
-                      G_STRUCT_OFFSET (UiSkinnedButtonClass, released), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    button_signals[CLICKED] = 
-        g_signal_new ("clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedButtonClass, clicked), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    button_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedButtonClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    button_signals[REDRAW] = 
-        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedButtonClass, redraw), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    g_type_class_add_private (gobject_class, sizeof (UiSkinnedButtonPrivate));
-}
-
-static void ui_skinned_button_init (UiSkinnedButton *button) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    button->inside = FALSE;
-    button->type = TYPE_NOT_SET;
-    priv->move_x = 0;
-    priv->move_y = 0;
-    button->event_window = NULL;
-}
-
-static void ui_skinned_button_destroy (GtkObject *object) {
-    UiSkinnedButton *button;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_BUTTON (object));
-
-    button = UI_SKINNED_BUTTON(object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_button_realize (GtkWidget *widget) {
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_BUTTON(widget));
-    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
-
-    if (button->type == TYPE_SMALL || button->type == TYPE_NOT_SET) {
-        widget->window = gtk_widget_get_parent_window (widget);
-        g_object_ref (widget->window);
-        attributes.wclass = GDK_INPUT_ONLY;
-        attributes_mask = GDK_WA_X | GDK_WA_Y;
-        button->event_window = gdk_window_new (widget->window, &attributes, attributes_mask);
-        GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
-        gdk_window_set_user_data(button->event_window, widget);
-    } else {
-        attributes.visual = gtk_widget_get_visual(widget);
-        attributes.colormap = gtk_widget_get_colormap(widget);
-        attributes.wclass = GDK_INPUT_OUTPUT;
-        attributes.event_mask |= GDK_EXPOSURE_MASK;
-        attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-        widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-        GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW);
-        gdk_window_set_user_data(widget->window, widget);
-    }
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-}
-
-static void ui_skinned_button_unrealize (GtkWidget *widget) {
-    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
-
-    if ( button->event_window != NULL )
-    {
-      gdk_window_set_user_data( button->event_window , NULL );
-      gdk_window_destroy( button->event_window );
-      button->event_window = NULL;
-    }
-
-    if (GTK_WIDGET_CLASS (parent_class)->unrealize)
-        (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
-}
-
-static void ui_skinned_button_map (GtkWidget *widget)
-{
-    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
-
-    if (button->event_window != NULL)
-      gdk_window_show (button->event_window);
-
-    if (GTK_WIDGET_CLASS (parent_class)->map)
-      (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
-}
-
-static void ui_skinned_button_unmap (GtkWidget *widget)
-{
-    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
-
-    if (button->event_window != NULL)
-      gdk_window_hide (button->event_window);
-
-    if (GTK_WIDGET_CLASS (parent_class)->unmap)
-      (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
-}
-
-static void ui_skinned_button_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(widget);
-    requisition->width = priv->w*(priv->scaled ? cfg.scale_factor : 1);
-    requisition->height = priv->h*(priv->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_button_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    widget->allocation = *allocation;
-    widget->allocation.x = ceil(widget->allocation.x*(priv->scaled ? cfg.scale_factor : 1));
-    widget->allocation.y = ceil(widget->allocation.y*(priv->scaled ? cfg.scale_factor : 1));
-
-    if (GTK_WIDGET_REALIZED (widget))
-    {
-        if ( button->event_window != NULL )
-            gdk_window_move_resize(button->event_window, ceil(allocation->x*(priv->scaled ? cfg.scale_factor : 1)), ceil(allocation->y*(priv->scaled ? cfg.scale_factor : 1)), allocation->width, allocation->height);
-        else
-            gdk_window_move_resize(widget->window, ceil(allocation->x*(priv->scaled ? cfg.scale_factor : 1)), ceil(allocation->y*(priv->scaled ? cfg.scale_factor : 1)), allocation->width, allocation->height);
-    }
-
-    if (button->x + priv->move_x == ceil(widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1)))
-        priv->move_x = 0;
-    if (button->y + priv->move_y == ceil(widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1)))
-        priv->move_y = 0;
-
-    button->x = ceil(widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1));
-    button->y = ceil(widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1));
-}
-
-static gboolean ui_skinned_button_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_BUTTON (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedButton *button = UI_SKINNED_BUTTON (widget);
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    g_return_val_if_fail (priv->w > 0 && priv->h > 0, FALSE);
-
-    //TYPE_SMALL doesn't have its own face
-    if (button->type == TYPE_SMALL || button->type == TYPE_NOT_SET)
-        return FALSE;
-
-    /* paranoia */
-    if (button->event_window != NULL)
-        return FALSE;
-
-    GdkPixbuf *obj;
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->w, priv->h);
-
-    switch (button->type) {
-        case TYPE_PUSH:
-            skin_draw_pixbuf(widget, aud_active_skin, obj,
-                             button->pressed ? priv->skin_index2 : priv->skin_index1,
-                             button->pressed ? priv->px : priv->nx,
-                             button->pressed ? priv->py : priv->ny,
-                             0, 0, priv->w, priv->h);
-            break;
-        case TYPE_TOGGLE:
-            if (button->inside)
-                skin_draw_pixbuf(widget, aud_active_skin, obj,
-                                 button->pressed ? priv->skin_index2 : priv->skin_index1,
-                                 button->pressed ? priv->ppx : priv->pnx,
-                                 button->pressed ? priv->ppy : priv->pny,
-                                 0, 0, priv->w, priv->h);
-            else
-                skin_draw_pixbuf(widget, aud_active_skin, obj,
-                                 button->pressed ? priv->skin_index2 : priv->skin_index1,
-                                 button->pressed ? priv->px : priv->nx,
-                                 button->pressed ? priv->py : priv->ny,
-                                 0, 0, priv->w, priv->h);
-            break;
-        default:
-            break;
-    }
-
-    ui_skinned_widget_draw(widget, obj, priv->w, priv->h, priv->scaled);
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-GtkWidget* ui_skinned_button_new () {
-    UiSkinnedButton *button = g_object_new (ui_skinned_button_get_type (), NULL);
-
-    return GTK_WIDGET(button);
-}
-
-void ui_skinned_push_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, SkinPixmapId si) {
-
-    UiSkinnedButton *sbutton = UI_SKINNED_BUTTON(button);
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(sbutton);
-    priv->w = w;
-    priv->h = h;
-    sbutton->x = x;
-    sbutton->y = y;
-    priv->nx = nx;
-    priv->ny = ny;
-    priv->px = px;
-    priv->py = py;
-    sbutton->type = TYPE_PUSH;
-    priv->skin_index1 = si;
-    priv->skin_index2 = si;
-    priv->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(button), sbutton->x, sbutton->y);
-}
-
-void ui_skinned_toggle_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, gint pnx, gint pny, gint ppx, gint ppy, SkinPixmapId si) {
-
-    UiSkinnedButton *sbutton = UI_SKINNED_BUTTON(button);
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(sbutton);
-    priv->w = w;
-    priv->h = h;
-    sbutton->x = x;
-    sbutton->y = y;
-    priv->nx = nx;
-    priv->ny = ny;
-    priv->px = px;
-    priv->py = py;
-    priv->pnx = pnx;
-    priv->pny = pny;
-    priv->ppx = ppx;
-    priv->ppy = ppy;
-    sbutton->type = TYPE_TOGGLE;
-    priv->skin_index1 = si;
-    priv->skin_index2 = si;
-    priv->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(button), sbutton->x, sbutton->y);
-}
-
-void ui_skinned_small_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h) {
-
-    UiSkinnedButton *sbutton = UI_SKINNED_BUTTON(button);
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(sbutton);
-    priv->w = w;
-    priv->h = h;
-    sbutton->x = x;
-    sbutton->y = y;
-    sbutton->type = TYPE_SMALL;
-    priv->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(button), sbutton->x, sbutton->y);
-}
-
-static void button_pressed(UiSkinnedButton *button) {
-    button->button_down = TRUE;
-    ui_skinned_button_update_state(button);
-}
-
-static void button_released(UiSkinnedButton *button) {
-    button->button_down = FALSE;
-    if(button->hover) ui_skinned_button_clicked(button);
-    ui_skinned_button_update_state(button);
-}
-
-static void ui_skinned_button_update_state(UiSkinnedButton *button) {
-    ui_skinned_button_set_pressed(button, button->button_down); 
-}
-
-static void ui_skinned_button_set_pressed (UiSkinnedButton *button, gboolean pressed) {
-    if (pressed != button->pressed) {
-        button->pressed = pressed;
-        gtk_widget_queue_draw(GTK_WIDGET(button));
-    }
-}
-
-static gboolean ui_skinned_button_button_press(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedButton *button;
-
-    if (event->type == GDK_BUTTON_PRESS) {
-        button = UI_SKINNED_BUTTON(widget);
-
-        if (event->button == 1)
-            ui_skinned_button_pressed (button);
-        else if (event->button == 3) {
-            event->x = event->x + button->x;
-            event->y = event->y + button->y;
-            return FALSE;
-        }
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_button_button_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedButton *button;
-    if (event->button == 1) {
-            button = UI_SKINNED_BUTTON(widget);
-            ui_skinned_button_released(button);
-    }
-    return TRUE;
-}
-
-static void ui_skinned_button_pressed(UiSkinnedButton *button) {
-    g_return_if_fail(UI_SKINNED_IS_BUTTON(button));
-    g_signal_emit(button, button_signals[PRESSED], 0);
-}
-
-static void ui_skinned_button_released(UiSkinnedButton *button) {
-    g_return_if_fail(UI_SKINNED_IS_BUTTON(button));
-    g_signal_emit(button, button_signals[RELEASED], 0);
-}
-
-static void ui_skinned_button_clicked(UiSkinnedButton *button) {
-    g_return_if_fail(UI_SKINNED_IS_BUTTON(button));
-    button->inside = !button->inside;
-    g_signal_emit(button, button_signals[CLICKED], 0);
-}
-
-static gboolean ui_skinned_button_enter_notify(GtkWidget *widget, GdkEventCrossing *event) {
-    UiSkinnedButton *button;
-
-    button = UI_SKINNED_BUTTON(widget);
-    button->hover = TRUE;
-    if(button->button_down) ui_skinned_button_set_pressed(button, TRUE);
-
-    return FALSE;
-}
-
-static gboolean ui_skinned_button_leave_notify(GtkWidget *widget, GdkEventCrossing *event) {
-    UiSkinnedButton *button;
-
-    button = UI_SKINNED_BUTTON (widget);
-    button->hover = FALSE;
-    if(button->button_down) ui_skinned_button_set_pressed(button, FALSE);
-
-    return FALSE;
-}
-
-static void ui_skinned_button_toggle_scaled(UiSkinnedButton *button) {
-    GtkWidget *widget = GTK_WIDGET (button);
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    priv->scaled = !priv->scaled;
-
-    gtk_widget_set_size_request(widget, priv->w*(priv->scaled ? cfg.scale_factor : 1), priv->h*(priv->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(widget);
-}
-
-static void ui_skinned_button_redraw(UiSkinnedButton *button) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    if (priv->move_x || priv->move_y)
-        gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(GTK_WIDGET(button))), GTK_WIDGET(button),
-                       button->x+priv->move_x, button->y+priv->move_y);
-
-    gtk_widget_queue_draw(GTK_WIDGET(button));
-}
-
-
-void ui_skinned_set_push_button_data(GtkWidget *button, gint nx, gint ny, gint px, gint py) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE(button);
-    if (nx > -1) priv->nx = nx;
-    if (ny > -1) priv->ny = ny;
-    if (px > -1) priv->px = px;
-    if (py > -1) priv->py = py;
-    gtk_widget_queue_draw(button);
-}
-
-void ui_skinned_button_set_skin_index(GtkWidget *button, SkinPixmapId si) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    priv->skin_index1 = priv->skin_index2 = si;
-}
-
-void ui_skinned_button_set_skin_index1(GtkWidget *button, SkinPixmapId si) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    priv->skin_index1 = si;
-}
-
-void ui_skinned_button_set_skin_index2(GtkWidget *button, SkinPixmapId si) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    priv->skin_index2 = si;
-}
-
-void ui_skinned_button_move_relative(GtkWidget *button, gint x, gint y) {
-    UiSkinnedButtonPrivate *priv = UI_SKINNED_BUTTON_GET_PRIVATE (button);
-    priv->move_x += x;
-    priv->move_y += y;
-}
--- a/src/audacious/ui_skinned_button.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_BUTTON_H
-#define AUDACIOUS_UI_SKINNED_BUTTON_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#define UI_SKINNED_BUTTON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), ui_skinned_button_get_type(), UiSkinnedButton))
-#define UI_SKINNED_BUTTON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  ui_skinned_button_get_type(), UiSkinnedButtonClass))
-#define UI_SKINNED_IS_BUTTON(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ui_skinned_button_get_type()))
-
-typedef struct _UiSkinnedButton		UiSkinnedButton;
-typedef struct _UiSkinnedButtonClass	UiSkinnedButtonClass;
-
-enum {
-    TYPE_NOT_SET,
-    TYPE_PUSH,
-    TYPE_TOGGLE,
-    TYPE_SMALL
-};
-
-struct _UiSkinnedButton {
-    GtkWidget widget;
-
-    GdkWindow *event_window;
-    gboolean button_down;
-    gboolean pressed;
-    gboolean hover;
-    gboolean inside;
-    gint type;
-    gint x, y;
-};
-
-struct _UiSkinnedButtonClass {
-    GtkWidgetClass          parent_class;
-    void (* pressed)       (UiSkinnedButton *button);
-    void (* released)      (UiSkinnedButton *button);
-    void (* clicked)       (UiSkinnedButton *button);
-    void (* right_clicked) (UiSkinnedButton *button);
-    void (* scaled)        (UiSkinnedButton *button);
-    void (* redraw)        (UiSkinnedButton *button);
-};
-
-GType ui_skinned_button_get_type(void) G_GNUC_CONST;
-GtkWidget* ui_skinned_button_new();
-void ui_skinned_push_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, SkinPixmapId si);
-void ui_skinned_set_push_button_data(GtkWidget *button, gint nx, gint ny, gint px, gint py);
-void ui_skinned_toggle_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h, gint nx, gint ny, gint px, gint py, gint pnx, gint pny, gint ppx, gint ppy, SkinPixmapId si);
-void ui_skinned_small_button_setup(GtkWidget *button, GtkWidget *fixed, gint x, gint y, gint w, gint h);
-void ui_skinned_button_set_skin_index(GtkWidget *button, SkinPixmapId si);
-void ui_skinned_button_set_skin_index1(GtkWidget *button, SkinPixmapId si);
-void ui_skinned_button_set_skin_index2(GtkWidget *button, SkinPixmapId si);
-void ui_skinned_button_move_relative(GtkWidget *button, gint x, gint y);
-
-#endif /* AUDACIOUS_UI_SKINNED_BUTTON_H */
--- a/src/audacious/ui_skinned_equalizer_graph.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- */
-
-#include "ui_skin.h"
-#include "ui_skinned_equalizer_graph.h"
-#include "main.h"
-#include "equalizer_flow.h"
-
-#define UI_TYPE_SKINNED_EQUALIZER_GRAPH           (ui_skinned_equalizer_graph_get_type())
-
-enum {
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-static void ui_skinned_equalizer_graph_class_init         (UiSkinnedEqualizerGraphClass *klass);
-static void ui_skinned_equalizer_graph_init               (UiSkinnedEqualizerGraph *equalizer_graph);
-static void ui_skinned_equalizer_graph_destroy            (GtkObject *object);
-static void ui_skinned_equalizer_graph_realize            (GtkWidget *widget);
-static void ui_skinned_equalizer_graph_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_equalizer_graph_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_equalizer_graph_expose         (GtkWidget *widget, GdkEventExpose *event);
-static void ui_skinned_equalizer_graph_toggle_scaled  (UiSkinnedEqualizerGraph *equalizer_graph);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint equalizer_graph_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_equalizer_graph_get_type() {
-    static GType equalizer_graph_type = 0;
-    if (!equalizer_graph_type) {
-        static const GTypeInfo equalizer_graph_info = {
-            sizeof (UiSkinnedEqualizerGraphClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_equalizer_graph_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedEqualizerGraph),
-            0,
-            (GInstanceInitFunc) ui_skinned_equalizer_graph_init,
-        };
-        equalizer_graph_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedEqualizerGraph_", &equalizer_graph_info, 0);
-    }
-
-    return equalizer_graph_type;
-}
-
-static void ui_skinned_equalizer_graph_class_init(UiSkinnedEqualizerGraphClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_equalizer_graph_destroy;
-
-    widget_class->realize = ui_skinned_equalizer_graph_realize;
-    widget_class->expose_event = ui_skinned_equalizer_graph_expose;
-    widget_class->size_request = ui_skinned_equalizer_graph_size_request;
-    widget_class->size_allocate = ui_skinned_equalizer_graph_size_allocate;
-
-    klass->scaled = ui_skinned_equalizer_graph_toggle_scaled;
-
-    equalizer_graph_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedEqualizerGraphClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-}
-
-static void ui_skinned_equalizer_graph_init(UiSkinnedEqualizerGraph *equalizer_graph) {
-    equalizer_graph->width = 113;
-    equalizer_graph->height = 19;
-}
-
-GtkWidget* ui_skinned_equalizer_graph_new(GtkWidget *fixed, gint x, gint y) {
-    UiSkinnedEqualizerGraph *equalizer_graph = g_object_new (ui_skinned_equalizer_graph_get_type (), NULL);
-
-    equalizer_graph->x = x;
-    equalizer_graph->y = y;
-    equalizer_graph->skin_index = SKIN_EQMAIN;
-    equalizer_graph->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(equalizer_graph), equalizer_graph->x, equalizer_graph->y);
-
-    return GTK_WIDGET(equalizer_graph);
-}
-
-static void ui_skinned_equalizer_graph_destroy(GtkObject *object) {
-    UiSkinnedEqualizerGraph *equalizer_graph;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_GRAPH (object));
-
-    equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_equalizer_graph_realize(GtkWidget *widget) {
-    UiSkinnedEqualizerGraph *equalizer_graph;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_GRAPH(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_equalizer_graph_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedEqualizerGraph *equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH(widget);
-
-    requisition->width = equalizer_graph->width*(equalizer_graph->scaled ? cfg.scale_factor : 1);
-    requisition->height = equalizer_graph->height*(equalizer_graph->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_equalizer_graph_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedEqualizerGraph *equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH (widget);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (equalizer_graph->scaled ? cfg.scale_factor : 1);
-    widget->allocation.y *= (equalizer_graph->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    equalizer_graph->x = widget->allocation.x/(equalizer_graph->scaled ? cfg.scale_factor : 1);
-    equalizer_graph->y = widget->allocation.y/(equalizer_graph->scaled ? cfg.scale_factor : 1);
-}
-
-void
-init_spline(gfloat * x, gfloat * y, gint n, gfloat * y2)
-{
-    gint i, k;
-    gfloat p, qn, sig, un, *u;
-
-    u = (gfloat *) g_malloc(n * sizeof(gfloat));
-
-    y2[0] = u[0] = 0.0;
-
-    for (i = 1; i < n - 1; i++) {
-        sig = ((gfloat) x[i] - x[i - 1]) / ((gfloat) x[i + 1] - x[i - 1]);
-        p = sig * y2[i - 1] + 2.0;
-        y2[i] = (sig - 1.0) / p;
-        u[i] =
-            (((gfloat) y[i + 1] - y[i]) / (x[i + 1] - x[i])) -
-            (((gfloat) y[i] - y[i - 1]) / (x[i] - x[i - 1]));
-        u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
-    }
-    qn = un = 0.0;
-
-    y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0);
-    for (k = n - 2; k >= 0; k--)
-        y2[k] = y2[k] * y2[k + 1] + u[k];
-    g_free(u);
-}
-
-gfloat
-eval_spline(gfloat xa[], gfloat ya[], gfloat y2a[], gint n, gfloat x)
-{
-    gint klo, khi, k;
-    gfloat h, b, a;
-
-    klo = 0;
-    khi = n - 1;
-    while (khi - klo > 1) {
-        k = (khi + klo) >> 1;
-        if (xa[k] > x)
-            khi = k;
-        else
-            klo = k;
-    }
-    h = xa[khi] - xa[klo];
-    a = (xa[khi] - x) / h;
-    b = (x - xa[klo]) / h;
-    return (a * ya[klo] + b * ya[khi] +
-            ((a * a * a - a) * y2a[klo] +
-             (b * b * b - b) * y2a[khi]) * (h * h) / 6.0);
-}
-
-static gboolean ui_skinned_equalizer_graph_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_GRAPH (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedEqualizerGraph *equalizer_graph = UI_SKINNED_EQUALIZER_GRAPH (widget);
-    g_return_val_if_fail (equalizer_graph->width > 0 && equalizer_graph->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, equalizer_graph->width, equalizer_graph->height);
-
-    guint32 cols[19], rowstride;
-    gint i, y, ymin, ymax, py = 0;
-    gfloat x[] = { 0, 11, 23, 35, 47, 59, 71, 83, 97, 109 }, yf[10];
-    guchar* pixels, *p;
-    gint n_channels;
-    /*
-     * This avoids the init_spline() function to be inlined.
-     * Inlining the function caused troubles when compiling with
-     * `-O' (at least on FreeBSD).
-     */
-    void (*__init_spline) (gfloat *, gfloat *, gint, gfloat *) = init_spline;
-
-    skin_draw_pixbuf(widget, aud_active_skin, obj, equalizer_graph->skin_index, 0, 294, 0, 0,
-                     equalizer_graph->width, equalizer_graph->height);
-    skin_draw_pixbuf(widget, aud_active_skin, obj, equalizer_graph->skin_index, 0, 314,
-                     0, 9 + ((cfg.equalizer_preamp * 9) / 20),
-                     equalizer_graph->width, 1);
-
-    skin_get_eq_spline_colors(aud_active_skin, cols);
-
-    __init_spline(x, cfg.equalizer_bands, AUD_EQUALIZER_NBANDS, yf);
-    for (i = 0; i < 109; i++) {
-        y = 9 -
-            (gint) ((eval_spline(x, cfg.equalizer_bands, yf, AUD_EQUALIZER_NBANDS, i) *
-                     9.0) / EQUALIZER_MAX_GAIN);
-        if (y < 0)
-            y = 0;
-        if (y > 18)
-            y = 18;
-        if (!i)
-            py = y;
-        if (y < py) {
-            ymin = y;
-            ymax = py;
-        }
-        else {
-            ymin = py;
-            ymax = y;
-        }
-        py = y;
-
-        pixels = gdk_pixbuf_get_pixels(obj);
-        rowstride = gdk_pixbuf_get_rowstride(obj);
-        n_channels = gdk_pixbuf_get_n_channels(obj); 
-
-        for (y = ymin; y <= ymax; y++) 
-        {
-            p = pixels + (y * rowstride) + (( i + 2) * n_channels); 
-            p[0] = (cols[y] & 0xff0000) >> 16;
-            p[1] = (cols[y] & 0x00ff00) >> 8;
-            p[2] = (cols[y] & 0x0000ff);
-            /* do we really need to treat the alpha channel? */
-            /*if (n_channels == 4)
-                  p[3] = cols[y] >> 24;*/
-        }
-    }
-
-    ui_skinned_widget_draw(widget, obj, equalizer_graph->width, equalizer_graph->height, equalizer_graph->scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static void ui_skinned_equalizer_graph_toggle_scaled(UiSkinnedEqualizerGraph *equalizer_graph) {
-    GtkWidget *widget = GTK_WIDGET (equalizer_graph);
-
-    equalizer_graph->scaled = !equalizer_graph->scaled;
-    gtk_widget_set_size_request(widget, equalizer_graph->width*(equalizer_graph->scaled ? cfg.scale_factor : 1),
-                                        equalizer_graph->height*(equalizer_graph->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(GTK_WIDGET(equalizer_graph));
-}
--- a/src/audacious/ui_skinned_equalizer_graph.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_EQUALIZER_GRAPH_H
-#define AUDACIOUS_UI_SKINNED_EQUALIZER_GRAPH_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_EQUALIZER_GRAPH(obj)          GTK_CHECK_CAST (obj, ui_skinned_equalizer_graph_get_type (), UiSkinnedEqualizerGraph)
-#define UI_SKINNED_EQUALIZER_GRAPH_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_equalizer_graph_get_type (), UiSkinnedEqualizerGraphClass)
-#define UI_SKINNED_IS_EQUALIZER_GRAPH(obj)       GTK_CHECK_TYPE (obj, ui_skinned_equalizer_graph_get_type ())
-
-typedef struct _UiSkinnedEqualizerGraph        UiSkinnedEqualizerGraph;
-typedef struct _UiSkinnedEqualizerGraphClass   UiSkinnedEqualizerGraphClass;
-
-struct _UiSkinnedEqualizerGraph {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    SkinPixmapId     skin_index;
-    gboolean         scaled;
-};
-
-struct _UiSkinnedEqualizerGraphClass {
-    GtkWidgetClass          parent_class;
-    void (* scaled)        (UiSkinnedEqualizerGraph *eq_graph);
-};
-
-GtkWidget* ui_skinned_equalizer_graph_new(GtkWidget *fixed, gint x, gint y);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_EQUALIZER_GRAPH_H */
--- a/src/audacious/ui_skinned_equalizer_slider.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,392 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- */
-
-#include "ui_skin.h"
-#include "ui_skinned_equalizer_slider.h"
-#include "ui_equalizer.h"
-#include "ui_main.h"
-#include "equalizer_flow.h"
-#include <glib/gi18n.h>
-
-#define UI_TYPE_SKINNED_EQUALIZER_SLIDER           (ui_skinned_equalizer_slider_get_type())
-#define UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UI_TYPE_SKINNED_EQUALIZER_SLIDER, UiSkinnedEqualizerSliderPrivate))
-typedef struct _UiSkinnedEqualizerSliderPrivate UiSkinnedEqualizerSliderPrivate;
-
-enum {
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-struct _UiSkinnedEqualizerSliderPrivate {
-    SkinPixmapId     skin_index;
-    gboolean         scaled;
-    gint             position;
-    gint             width, height;
-    gboolean         pressed;
-    gint             drag_y;
-    gfloat           value; /* store gain as is to prevent truncation --asphyx */
-};
-
-static void ui_skinned_equalizer_slider_class_init         (UiSkinnedEqualizerSliderClass *klass);
-static void ui_skinned_equalizer_slider_init               (UiSkinnedEqualizerSlider *equalizer_slider);
-static void ui_skinned_equalizer_slider_destroy            (GtkObject *object);
-static void ui_skinned_equalizer_slider_realize            (GtkWidget *widget);
-static void ui_skinned_equalizer_slider_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_equalizer_slider_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_equalizer_slider_expose         (GtkWidget *widget, GdkEventExpose *event);
-static gboolean ui_skinned_equalizer_slider_button_press   (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_equalizer_slider_button_release (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_equalizer_slider_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
-static gboolean ui_skinned_equalizer_slider_scroll         (GtkWidget *widget, GdkEventScroll *event);
-static void ui_skinned_equalizer_slider_toggle_scaled      (UiSkinnedEqualizerSlider *equalizer_slider);
-void ui_skinned_equalizer_slider_set_mainwin_text          (UiSkinnedEqualizerSlider * es);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint equalizer_slider_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_equalizer_slider_get_type() {
-    static GType equalizer_slider_type = 0;
-    if (!equalizer_slider_type) {
-        static const GTypeInfo equalizer_slider_info = {
-            sizeof (UiSkinnedEqualizerSliderClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_equalizer_slider_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedEqualizerSlider),
-            0,
-            (GInstanceInitFunc) ui_skinned_equalizer_slider_init,
-        };
-        equalizer_slider_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedEqualizerSlider_", &equalizer_slider_info, 0);
-    }
-
-    return equalizer_slider_type;
-}
-
-static void ui_skinned_equalizer_slider_class_init(UiSkinnedEqualizerSliderClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_equalizer_slider_destroy;
-
-    widget_class->realize = ui_skinned_equalizer_slider_realize;
-    widget_class->expose_event = ui_skinned_equalizer_slider_expose;
-    widget_class->size_request = ui_skinned_equalizer_slider_size_request;
-    widget_class->size_allocate = ui_skinned_equalizer_slider_size_allocate;
-    widget_class->button_press_event = ui_skinned_equalizer_slider_button_press;
-    widget_class->button_release_event = ui_skinned_equalizer_slider_button_release;
-    widget_class->motion_notify_event = ui_skinned_equalizer_slider_motion_notify;
-    widget_class->scroll_event = ui_skinned_equalizer_slider_scroll;
-
-    klass->scaled = ui_skinned_equalizer_slider_toggle_scaled;
-
-    equalizer_slider_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedEqualizerSliderClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    g_type_class_add_private (gobject_class, sizeof (UiSkinnedEqualizerSliderPrivate));
-}
-
-static void ui_skinned_equalizer_slider_init(UiSkinnedEqualizerSlider *equalizer_slider) {
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(equalizer_slider);
-    priv->pressed = FALSE;
-}
-
-GtkWidget* ui_skinned_equalizer_slider_new(GtkWidget *fixed, gint x, gint y) {
-    UiSkinnedEqualizerSlider *es = g_object_new (ui_skinned_equalizer_slider_get_type (), NULL);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(es);
-
-    es->x = x;
-    es->y = y;
-    priv->width = 14;
-    priv->height = 63;
-    priv->skin_index = SKIN_EQMAIN;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(es), es->x, es->y);
-
-    return GTK_WIDGET(es);
-}
-
-static void ui_skinned_equalizer_slider_destroy(GtkObject *object) {
-    UiSkinnedEqualizerSlider *equalizer_slider;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (object));
-
-    equalizer_slider = UI_SKINNED_EQUALIZER_SLIDER (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_equalizer_slider_realize(GtkWidget *widget) {
-    UiSkinnedEqualizerSlider *equalizer_slider;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    equalizer_slider = UI_SKINNED_EQUALIZER_SLIDER(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
-                             GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_equalizer_slider_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
-
-    requisition->width = priv->width*(priv->scaled ? cfg.scale_factor : 1);
-    requisition->height = priv->height*(priv->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_equalizer_slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedEqualizerSlider *equalizer_slider = UI_SKINNED_EQUALIZER_SLIDER (widget);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(equalizer_slider);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (priv->scaled ? cfg.scale_factor : 1);
-    widget->allocation.y *= (priv->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    equalizer_slider->x = widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1);
-    equalizer_slider->y = widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1);
-}
-
-static gboolean ui_skinned_equalizer_slider_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedEqualizerSlider *es = UI_SKINNED_EQUALIZER_SLIDER (widget);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(es);
-    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->width, priv->height);
-
-    gint frame;
-    frame = 27 - ((priv->position * 27) / 50);
-    if (frame < 14)
-        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, (frame * 15) + 13, 164, 0, 0, priv->width, priv->height);
-    else
-        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, ((frame - 14) * 15) + 13, 229, 0, 0, priv->width, priv->height);
-
-    if (priv->pressed)
-        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, 0, 176, 1, priv->position, 11, 11);
-    else
-        skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, 0, 164, 1, priv->position, 11, 11);
-
-    ui_skinned_widget_draw(widget, obj, priv->width, priv->height, priv->scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static gboolean ui_skinned_equalizer_slider_button_press(GtkWidget *widget, GdkEventButton *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedEqualizerSlider *es = UI_SKINNED_EQUALIZER_SLIDER (widget);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(es);
-
-    gint y;
-
-    if (event->type == GDK_BUTTON_PRESS) {
-        if (event->button == 1) {
-            priv->pressed = TRUE;
-            y = event->y/(priv->scaled ? cfg.scale_factor : 1);
-
-            if (y >= priv->position && y < priv->position + 11)
-                priv->drag_y = y - priv->position;
-            else {
-                priv->position = y - 5;
-                priv->drag_y = 5;
-                if (priv->position < 0)
-                    priv->position = 0;
-                if (priv->position > 50)
-                    priv->position = 50;
-                if (priv->position >= 24 && priv->position <= 26)
-                    priv->position = 25;
-                
-                priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 );
-                equalizerwin_eq_changed();
-            }
-
-            ui_skinned_equalizer_slider_set_mainwin_text(es);
-            gtk_widget_queue_draw(widget);
-        }
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_equalizer_slider_button_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
-
-    if (event->button == 1) {
-        priv->pressed = FALSE;
-        mainwin_release_info_text();
-        gtk_widget_queue_draw(widget);
-    }
-    return TRUE;
-}
-
-static gboolean ui_skinned_equalizer_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-    UiSkinnedEqualizerSlider *es = UI_SKINNED_EQUALIZER_SLIDER(widget);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
-
-    if (priv->pressed) {
-        gint y;
-
-        y = event->y/(priv->scaled ? cfg.scale_factor : 1);
-        priv->position = y - priv->drag_y;
-
-        if (priv->position < 0)
-            priv->position = 0;
-        if (priv->position > 50)
-            priv->position = 50;
-        if (priv->position >= 24 && priv->position <= 26)
-            priv->position = 25;
-        
-        priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 );
-        ui_skinned_equalizer_slider_set_mainwin_text(es);
-        equalizerwin_eq_changed();
-        gtk_widget_queue_draw(widget);
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_equalizer_slider_scroll(GtkWidget *widget, GdkEventScroll *event) {
-    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
-
-    if (event->direction == GDK_SCROLL_UP) {
-        priv->position -= 2;
-
-        if (priv->position < 0)
-            priv->position = 0;
-    }
-    else {
-        priv->position += 2;
-
-        if (priv->position > 50)
-            priv->position = 50;
-    }
-
-    priv->value = ((gfloat) (25 - priv->position) * EQUALIZER_MAX_GAIN / 25.0 );
-    equalizerwin_eq_changed();
-    gtk_widget_queue_draw(widget);
-    return TRUE;
-}
-
-static void ui_skinned_equalizer_slider_toggle_scaled(UiSkinnedEqualizerSlider *equalizer_slider) {
-    GtkWidget *widget = GTK_WIDGET (equalizer_slider);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(equalizer_slider);
-
-    priv->scaled = !priv->scaled;
-
-    gtk_widget_set_size_request(widget, priv->width*(priv->scaled ? cfg.scale_factor : 1),
-    priv->height*(priv->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(GTK_WIDGET(equalizer_slider));
-}
-
-void ui_skinned_equalizer_slider_set_position(GtkWidget *widget, gfloat pos) {
-    g_return_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget));
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
-
-    if (priv->pressed)
-        return;
-
-    priv->value = (pos > EQUALIZER_MAX_GAIN) ? EQUALIZER_MAX_GAIN : ((pos < -EQUALIZER_MAX_GAIN) ? -EQUALIZER_MAX_GAIN : pos);
-    priv->position = 25 - (gint) ((pos * 25.0) / EQUALIZER_MAX_GAIN);
-
-    if (priv->position < 0)
-        priv->position = 0;
-
-    if (priv->position > 50)
-        priv->position = 50;
-
-    if (priv->position >= 24 && priv->position <= 26)
-        priv->position = 25;
-
-    gtk_widget_queue_draw(widget);
-}
-
-gfloat ui_skinned_equalizer_slider_get_position(GtkWidget *widget) {
-    g_return_val_if_fail (UI_SKINNED_IS_EQUALIZER_SLIDER (widget), -1);
-    UiSkinnedEqualizerSliderPrivate *priv = UI_SKINNED_EQUALIZER_SLIDER_GET_PRIVATE(widget);
-    return priv->value;
-}
-
-void ui_skinned_equalizer_slider_set_mainwin_text(UiSkinnedEqualizerSlider * es) {
-    gint band = 0;
-    const gchar *bandname[11] = { N_("PREAMP"), N_("60HZ"), N_("170HZ"),
-        N_("310HZ"), N_("600HZ"), N_("1KHZ"),
-        N_("3KHZ"), N_("6KHZ"), N_("12KHZ"),
-        N_("14KHZ"), N_("16KHZ")
-    };
-    gchar *tmp;
-
-    if (es->x > 21)
-        band = ((es->x - 78) / 18) + 1;
-
-    tmp =
-        g_strdup_printf("EQ: %s: %+.1f DB", _(bandname[band]),
-                        ui_skinned_equalizer_slider_get_position(GTK_WIDGET(es)));
-    mainwin_lock_info_text(tmp);
-    g_free(tmp);
-}
--- a/src/audacious/ui_skinned_equalizer_slider.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_EQUALIZER_SLIDER_H
-#define AUDACIOUS_UI_SKINNED_EQUALIZER_SLIDER_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_EQUALIZER_SLIDER(obj)          GTK_CHECK_CAST (obj, ui_skinned_equalizer_slider_get_type (), UiSkinnedEqualizerSlider)
-#define UI_SKINNED_EQUALIZER_SLIDER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_equalizer_slider_get_type (),  UiSkinnedEqualizerSliderClass)
-#define UI_SKINNED_IS_EQUALIZER_SLIDER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_equalizer_slider_get_type ())
-
-typedef struct _UiSkinnedEqualizerSlider        UiSkinnedEqualizerSlider;
-typedef struct _UiSkinnedEqualizerSliderClass   UiSkinnedEqualizerSliderClass;
-
-struct _UiSkinnedEqualizerSlider {
-    GtkWidget   widget;
-    gint        x, y;
-};
-
-struct _UiSkinnedEqualizerSliderClass {
-    GtkWidgetClass    parent_class;
-    void (* scaled)  (UiSkinnedEqualizerSlider *equalizer_slider);
-};
-
-GtkWidget* ui_skinned_equalizer_slider_new(GtkWidget *fixed, gint x, gint y);
-GtkType ui_skinned_equalizer_slider_get_type(void);
-void ui_skinned_equalizer_slider_set_position(GtkWidget *widget, gfloat pos);
-gfloat ui_skinned_equalizer_slider_get_position(GtkWidget *widget);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_EQUALIZER_SLIDER_H */
--- a/src/audacious/ui_skinned_horizontal_slider.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,386 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skinned_horizontal_slider.h"
-#include "main.h"
-#include <math.h>
-
-#define UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_horizontal_slider_get_type(), UiSkinnedHorizontalSliderPrivate))
-typedef struct _UiSkinnedHorizontalSliderPrivate UiSkinnedHorizontalSliderPrivate;
-
-enum {
-    MOTION,
-    RELEASE,
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-struct _UiSkinnedHorizontalSliderPrivate {
-    SkinPixmapId     skin_index;
-    gboolean         scaled;
-    gint             frame, frame_offset, frame_height, min, max;
-    gint             knob_width, knob_height;
-    gint             position;
-    gint             width, height;
-    gint             (*frame_cb) (gint);
-};
-
-static void ui_skinned_horizontal_slider_class_init         (UiSkinnedHorizontalSliderClass *klass);
-static void ui_skinned_horizontal_slider_init               (UiSkinnedHorizontalSlider *horizontal_slider);
-static void ui_skinned_horizontal_slider_destroy            (GtkObject *object);
-static void ui_skinned_horizontal_slider_realize            (GtkWidget *widget);
-static void ui_skinned_horizontal_slider_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_horizontal_slider_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_horizontal_slider_expose         (GtkWidget *widget, GdkEventExpose *event);
-static gboolean ui_skinned_horizontal_slider_button_press   (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_horizontal_slider_button_release (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_horizontal_slider_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
-static void ui_skinned_horizontal_slider_toggle_scaled  (UiSkinnedHorizontalSlider *horizontal_slider);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint horizontal_slider_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_horizontal_slider_get_type() {
-    static GType horizontal_slider_type = 0;
-    if (!horizontal_slider_type) {
-        static const GTypeInfo horizontal_slider_info = {
-            sizeof (UiSkinnedHorizontalSliderClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_horizontal_slider_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedHorizontalSlider),
-            0,
-            (GInstanceInitFunc) ui_skinned_horizontal_slider_init,
-        };
-        horizontal_slider_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedHorizontalSlider_", &horizontal_slider_info, 0);
-    }
-
-    return horizontal_slider_type;
-}
-
-static void ui_skinned_horizontal_slider_class_init(UiSkinnedHorizontalSliderClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_horizontal_slider_destroy;
-
-    widget_class->realize = ui_skinned_horizontal_slider_realize;
-    widget_class->expose_event = ui_skinned_horizontal_slider_expose;
-    widget_class->size_request = ui_skinned_horizontal_slider_size_request;
-    widget_class->size_allocate = ui_skinned_horizontal_slider_size_allocate;
-    widget_class->button_press_event = ui_skinned_horizontal_slider_button_press;
-    widget_class->button_release_event = ui_skinned_horizontal_slider_button_release;
-    widget_class->motion_notify_event = ui_skinned_horizontal_slider_motion_notify;
-
-    klass->motion = NULL;
-    klass->release = NULL;
-    klass->scaled = ui_skinned_horizontal_slider_toggle_scaled;
-
-    horizontal_slider_signals[MOTION] = 
-        g_signal_new ("motion", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedHorizontalSliderClass, motion), NULL, NULL,
-                      gtk_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
-
-    horizontal_slider_signals[RELEASE] = 
-        g_signal_new ("release", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedHorizontalSliderClass, release), NULL, NULL,
-                      gtk_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
-
-    horizontal_slider_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedHorizontalSliderClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    g_type_class_add_private (gobject_class, sizeof (UiSkinnedHorizontalSliderPrivate));
-}
-
-static void ui_skinned_horizontal_slider_init(UiSkinnedHorizontalSlider *horizontal_slider) {
-    horizontal_slider->pressed = FALSE;
-}
-
-GtkWidget* ui_skinned_horizontal_slider_new(GtkWidget *fixed, gint x, gint y, gint w, gint h, gint knx, gint kny,
-                                            gint kpx, gint kpy, gint kw, gint kh, gint fh,
-                                            gint fo, gint min, gint max, gint(*fcb) (gint), SkinPixmapId si) {
-
-    UiSkinnedHorizontalSlider *hs = g_object_new (ui_skinned_horizontal_slider_get_type (), NULL);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(hs);
-
-    hs->x = x;
-    hs->y = y;
-    priv->width = w;
-    priv->height = h;
-    hs->knob_nx = knx;
-    hs->knob_ny = kny;
-    hs->knob_px = kpx;
-    hs->knob_py = kpy;
-    priv->knob_width = kw;
-    priv->knob_height = kh;
-    priv->frame_height = fh;
-    priv->frame_offset = fo;
-    priv->min = min;
-    priv->position = min;
-    priv->max = max;
-    priv->frame_cb = fcb;
-    if (priv->frame_cb)
-        priv->frame = priv->frame_cb(0);
-    priv->skin_index = si;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y);
-
-    return GTK_WIDGET(hs);
-}
-
-static void ui_skinned_horizontal_slider_destroy(GtkObject *object) {
-    UiSkinnedHorizontalSlider *horizontal_slider;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (object));
-
-    horizontal_slider = UI_SKINNED_HORIZONTAL_SLIDER (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_horizontal_slider_realize(GtkWidget *widget) {
-    UiSkinnedHorizontalSlider *horizontal_slider;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    horizontal_slider = UI_SKINNED_HORIZONTAL_SLIDER(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
-                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_horizontal_slider_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
-
-    requisition->width = priv->width*(priv->scaled ? cfg.scale_factor : 1);
-    requisition->height = priv->height*(priv->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_horizontal_slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedHorizontalSlider *horizontal_slider = UI_SKINNED_HORIZONTAL_SLIDER (widget);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(horizontal_slider);
-
-    widget->allocation = *allocation;
-    widget->allocation.x = ceil(widget->allocation.x*(priv->scaled ? cfg.scale_factor : 1));
-    widget->allocation.y = ceil(widget->allocation.y*(priv->scaled ? cfg.scale_factor : 1));
-
-    if (priv->knob_height == priv->height)
-        priv->knob_height = ceil(allocation->height/(priv->scaled ? cfg.scale_factor : 1));
-    priv->width = ceil(allocation->width/(priv->scaled ? cfg.scale_factor : 1));
-    priv->height = ceil(allocation->height/(priv->scaled ? cfg.scale_factor : 1));
-
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    horizontal_slider->x = ceil(widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1));
-    horizontal_slider->y = ceil(widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1));
-}
-
-static gboolean ui_skinned_horizontal_slider_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER (widget);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(hs);
-    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-
-    if (priv->position > priv->max) priv->position = priv->max;
-    else if (priv->position < priv->min) priv->position = priv->min;
-
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->width, priv->height);
-
-    skin_draw_pixbuf(widget, aud_active_skin, obj,
-                     priv->skin_index, priv->frame_offset,
-                     priv->frame * priv->frame_height,
-                     0, 0, priv->width, priv->height);
-    if (hs->pressed)
-        skin_draw_pixbuf(widget, aud_active_skin, obj,
-                         priv->skin_index, hs->knob_px,
-                         hs->knob_py, priv->position,
-                         ((priv->height - priv->knob_height) / 2),
-                         priv->knob_width, priv->knob_height);
-    else
-        skin_draw_pixbuf(widget, aud_active_skin, obj,
-                         priv->skin_index, hs->knob_nx,
-                         hs->knob_ny, priv->position,
-                         ((priv->height - priv->knob_height) / 2),
-                         priv->knob_width, priv->knob_height);
-
-    ui_skinned_widget_draw(widget, obj, priv->width, priv->height, priv->scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static gboolean ui_skinned_horizontal_slider_button_press(GtkWidget *widget, GdkEventButton *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER (widget);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(hs);
-
-    if (event->type == GDK_BUTTON_PRESS) {
-        if (event->button == 1) {
-            gint x;
-
-            x = event->x - (priv->knob_width / (priv->scaled ? 1 : cfg.scale_factor));
-            hs->pressed = TRUE;
-
-            priv->position = x/(priv->scaled ? cfg.scale_factor : 1);
-            if (priv->position < priv->min)
-                priv->position = priv->min;
-            if (priv->position > priv->max)
-                priv->position = priv->max;
-            if (priv->frame_cb)
-                priv->frame = priv->frame_cb(priv->position);
-
-            g_signal_emit_by_name(widget, "motion", priv->position);
-            gtk_widget_queue_draw(widget);
-        } else if (event->button == 3) {
-            if (hs->pressed) {
-                hs->pressed = FALSE;
-                g_signal_emit_by_name(widget, "release", priv->position);
-                gtk_widget_queue_draw(widget);
-            }
-            event->x = event->x + hs->x;
-            event->y = event->y + hs->y;
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-
-static gboolean ui_skinned_horizontal_slider_button_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER(widget);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
-
-    if (hs->pressed) {
-        hs->pressed = FALSE;
-        g_signal_emit_by_name(widget, "release", priv->position);
-        gtk_widget_queue_draw(widget);
-    }
-    return TRUE;
-}
-
-static gboolean ui_skinned_horizontal_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER(widget);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
-
-    if (hs->pressed) {
-        gint x;
-
-        x = event->x - (priv->knob_width / (priv->scaled ? 1 : cfg.scale_factor));
-        priv->position = x/(priv->scaled ? cfg.scale_factor : 1);
-
-        if (priv->position < priv->min)
-            priv->position = priv->min;
-
-        if (priv->position > priv->max)
-            priv->position = priv->max;
-
-        if (priv->frame_cb)
-            priv->frame = priv->frame_cb(priv->position);
-
-        g_signal_emit_by_name(widget, "motion", priv->position);
-        gtk_widget_queue_draw(widget);
-    }
-
-    return TRUE;
-}
-
-static void ui_skinned_horizontal_slider_toggle_scaled(UiSkinnedHorizontalSlider *horizontal_slider) {
-    GtkWidget *widget = GTK_WIDGET (horizontal_slider);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(horizontal_slider);
-
-    priv->scaled = !priv->scaled;
-
-    gtk_widget_set_size_request(widget,
-        priv->width*(priv->scaled ? cfg.scale_factor : 1),
-        priv->height*(priv->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(GTK_WIDGET(horizontal_slider));
-}
-
-void ui_skinned_horizontal_slider_set_position(GtkWidget *widget, gint pos) {
-    g_return_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget));
-    UiSkinnedHorizontalSlider *hs = UI_SKINNED_HORIZONTAL_SLIDER(widget);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
-
-    if (pos == priv->position || hs->pressed)
-        return;
-
-    priv->position = pos;
-
-    if (priv->frame_cb)
-        priv->frame = priv->frame_cb(priv->position);
-
-    gtk_widget_queue_draw(widget);
-}
-
-gint ui_skinned_horizontal_slider_get_position(GtkWidget *widget) {
-    g_return_val_if_fail (UI_SKINNED_IS_HORIZONTAL_SLIDER (widget), -1);
-    UiSkinnedHorizontalSliderPrivate *priv = UI_SKINNED_HORIZONTAL_SLIDER_GET_PRIVATE(widget);
-    return priv->position;
-}
--- a/src/audacious/ui_skinned_horizontal_slider.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_HORIZONTAL_SLIDER_H
-#define AUDACIOUS_UI_SKINNED_HORIZONTAL_SLIDER_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_HORIZONTAL_SLIDER(obj)          GTK_CHECK_CAST (obj, ui_skinned_horizontal_slider_get_type (), UiSkinnedHorizontalSlider)
-#define UI_SKINNED_HORIZONTAL_SLIDER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_horizontal_slider_get_type (), UiSkinnedHorizontalSliderClass)
-#define UI_SKINNED_IS_HORIZONTAL_SLIDER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_horizontal_slider_get_type ())
-
-typedef struct _UiSkinnedHorizontalSlider        UiSkinnedHorizontalSlider;
-typedef struct _UiSkinnedHorizontalSliderClass   UiSkinnedHorizontalSliderClass;
-
-struct _UiSkinnedHorizontalSlider {
-    GtkWidget   widget;
-    gboolean    pressed;
-    gint        x, y;
-    gint        knob_nx, knob_ny, knob_px, knob_py;
-};
-
-struct _UiSkinnedHorizontalSliderClass {
-    GtkWidgetClass    parent_class;
-    void (* motion)   (UiSkinnedHorizontalSlider *horizontal_slider);
-    void (* release)  (UiSkinnedHorizontalSlider *horizontal_slider);
-    void (* scaled)  (UiSkinnedHorizontalSlider *horizontal_slider);
-    void (* redraw)   (UiSkinnedHorizontalSlider *horizontal_slider);
-};
-GtkWidget* ui_skinned_horizontal_slider_new(GtkWidget *fixed, gint x, gint y, gint w, gint h, gint knx, gint kny,
-                                            gint kpx, gint kpy, gint kw, gint kh, gint fh,
-                                            gint fo, gint min, gint max, gint(*fcb) (gint), SkinPixmapId si);
-GtkType ui_skinned_horizontal_slider_get_type(void);
-void ui_skinned_horizontal_slider_set_position(GtkWidget *widget, gint pos);
-gint ui_skinned_horizontal_slider_get_position(GtkWidget *widget);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_HORIZONTAL_SLIDER_H */
--- a/src/audacious/ui_skinned_menurow.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,331 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skinned_menurow.h"
-#include "main.h"
-
-enum {
-    DOUBLED,
-    CHANGE,
-    RELEASE,
-    LAST_SIGNAL
-};
-
-static void ui_skinned_menurow_class_init         (UiSkinnedMenurowClass *klass);
-static void ui_skinned_menurow_init               (UiSkinnedMenurow *menurow);
-static void ui_skinned_menurow_destroy            (GtkObject *object);
-static void ui_skinned_menurow_realize            (GtkWidget *widget);
-static void ui_skinned_menurow_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_menurow_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_menurow_expose         (GtkWidget *widget, GdkEventExpose *event);
-static MenuRowItem menurow_find_selected          (UiSkinnedMenurow * mr, gint x, gint y);
-static gboolean ui_skinned_menurow_button_press   (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_menurow_button_release (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_menurow_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
-static void ui_skinned_menurow_toggle_scaled  (UiSkinnedMenurow *menurow);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint menurow_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_menurow_get_type() {
-    static GType menurow_type = 0;
-    if (!menurow_type) {
-        static const GTypeInfo menurow_info = {
-            sizeof (UiSkinnedMenurowClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_menurow_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedMenurow),
-            0,
-            (GInstanceInitFunc) ui_skinned_menurow_init,
-        };
-        menurow_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedMenurow_", &menurow_info, 0);
-    }
-
-    return menurow_type;
-}
-
-static void ui_skinned_menurow_class_init(UiSkinnedMenurowClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_menurow_destroy;
-
-    widget_class->realize = ui_skinned_menurow_realize;
-    widget_class->expose_event = ui_skinned_menurow_expose;
-    widget_class->size_request = ui_skinned_menurow_size_request;
-    widget_class->size_allocate = ui_skinned_menurow_size_allocate;
-    widget_class->button_press_event = ui_skinned_menurow_button_press;
-    widget_class->button_release_event = ui_skinned_menurow_button_release;
-    widget_class->motion_notify_event = ui_skinned_menurow_motion_notify;
-
-    klass->scaled = ui_skinned_menurow_toggle_scaled;
-    klass->change = NULL;
-    klass->release = NULL;
-
-    menurow_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedMenurowClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-
-    menurow_signals[CHANGE] = 
-        g_signal_new ("change", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedMenurowClass, change), NULL, NULL,
-                      gtk_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
-
-    menurow_signals[RELEASE] = 
-        g_signal_new ("release", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedMenurowClass, release), NULL, NULL,
-                      g_cclosure_marshal_VOID__UINT_POINTER, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
-
-}
-
-static void ui_skinned_menurow_init(UiSkinnedMenurow *menurow) {
-    menurow->scale_selected = cfg.scaled;
-    menurow->always_selected = cfg.always_on_top;
-}
-
-GtkWidget* ui_skinned_menurow_new(GtkWidget *fixed, gint x, gint y, gint nx, gint ny, gint sx, gint sy, SkinPixmapId si) {
-    UiSkinnedMenurow *menurow = g_object_new (ui_skinned_menurow_get_type (), NULL);
-
-    menurow->x = x;
-    menurow->y = y;
-    menurow->width = 8;
-    menurow->height = 43;
-    menurow->nx = nx;
-    menurow->ny = ny;
-    menurow->sx = sx;
-    menurow->sy = sy;
-    menurow->selected = MENUROW_NONE;
-
-    menurow->skin_index = si;
-
-    menurow->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(menurow), menurow->x, menurow->y);
-
-    return GTK_WIDGET(menurow);
-}
-
-static void ui_skinned_menurow_destroy(GtkObject *object) {
-    UiSkinnedMenurow *menurow;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_MENUROW (object));
-
-    menurow = UI_SKINNED_MENUROW (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_menurow_realize(GtkWidget *widget) {
-    UiSkinnedMenurow *menurow;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_MENUROW(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    menurow = UI_SKINNED_MENUROW(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
-                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_menurow_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW(widget);
-
-    requisition->width = menurow->width*(menurow->scaled ? cfg.scale_factor : 1);
-    requisition->height = menurow->height*(menurow->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_menurow_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW (widget);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (menurow->scaled ? cfg.scale_factor : 1);
-    widget->allocation.y *= (menurow->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    menurow->x = widget->allocation.x/(menurow->scaled ? cfg.scale_factor : 1);
-    menurow->y = widget->allocation.y/(menurow->scaled ? cfg.scale_factor : 1);
-}
-
-static gboolean ui_skinned_menurow_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_MENUROW (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW (widget);
-    g_return_val_if_fail (menurow->width > 0 && menurow->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, menurow->width, menurow->height);
-
-    if (menurow->selected == MENUROW_NONE) {
-        if (cfg.always_show_cb || menurow->pushed)
-            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
-                             menurow->nx, menurow->ny, 0, 0, 8, 43);
-        else
-            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
-                             menurow->nx + 8, menurow->ny, 0, 0, 8, 43);
-    }
-    else {
-        skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
-                         menurow->sx + ((menurow->selected - 1) * 8),
-                         menurow->sy, 0, 0, 8, 43);
-    }
-    if (cfg.always_show_cb || menurow->pushed) {
-        if (menurow->always_selected)
-            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
-                             menurow->sx + 8, menurow->sy + 10, 0, 10, 8, 8);
-        if (menurow->scale_selected)
-            skin_draw_pixbuf(widget, aud_active_skin, obj, menurow->skin_index,
-                             menurow->sx + 24, menurow->sy + 26, 0, 26, 8, 8);
-    }
-
-    ui_skinned_widget_draw(widget, obj, menurow->width, menurow->height, menurow->scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static MenuRowItem menurow_find_selected(UiSkinnedMenurow * mr, gint x, gint y) {
-    MenuRowItem ret = MENUROW_NONE;
-
-    x = x/(mr->scaled ? cfg.scale_factor : 1);
-    y = y/(mr->scaled ? cfg.scale_factor : 1);
-    if (x > 0 && x < 8) {
-        if (y >= 0 && y <= 10)
-            ret = MENUROW_OPTIONS;
-        if (y >= 10 && y <= 17)
-            ret = MENUROW_ALWAYS;
-        if (y >= 18 && y <= 25)
-            ret = MENUROW_FILEINFOBOX;
-        if (y >= 26 && y <= 33)
-            ret = MENUROW_SCALE;
-        if (y >= 34 && y <= 42)
-            ret = MENUROW_VISUALIZATION;
-    }
-    return ret;
-}
-
-static gboolean ui_skinned_menurow_button_press(GtkWidget *widget, GdkEventButton *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_MENUROW (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW (widget);
-
-    if (event->type == GDK_BUTTON_PRESS) {
-        if (event->button == 1) {
-
-        menurow->pushed = TRUE;
-        menurow->selected = menurow_find_selected(menurow, event->x, event->y);
-
-        gtk_widget_queue_draw(widget);
-        g_signal_emit_by_name(widget, "change", menurow->selected);
-        }
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_menurow_button_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW(widget);
-    if (menurow->pushed) {
-        menurow->pushed = FALSE;
-
-        if (menurow->selected == MENUROW_ALWAYS)
-            menurow->always_selected = !menurow->always_selected;
-
-        if (menurow->selected == MENUROW_SCALE)
-            menurow->scale_selected = !menurow->scale_selected;
-
-        if ((int)(menurow->selected) != -1)
-            g_signal_emit_by_name(widget, "release", menurow->selected, event);
-
-        menurow->selected = MENUROW_NONE;
-        gtk_widget_queue_draw(widget);
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_menurow_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_MENUROW (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-    UiSkinnedMenurow *menurow = UI_SKINNED_MENUROW(widget);
-
-    if (menurow->pushed) {
-        menurow->selected = menurow_find_selected(menurow, event->x, event->y);
-
-        gtk_widget_queue_draw(widget);
-        g_signal_emit_by_name(widget, "change", menurow->selected);
-    }
-
-    return TRUE;
-}
-
-static void ui_skinned_menurow_toggle_scaled(UiSkinnedMenurow *menurow) {
-    GtkWidget *widget = GTK_WIDGET (menurow);
-
-    menurow->scaled = !menurow->scaled;
-    gtk_widget_set_size_request(widget, menurow->width* (menurow->scaled ? cfg.scale_factor : 1),
-    menurow->height * (menurow->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(GTK_WIDGET(menurow));
-}
--- a/src/audacious/ui_skinned_menurow.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_MENUROW_H
-#define AUDACIOUS_UI_SKINNED_MENUROW_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_MENUROW(obj)          GTK_CHECK_CAST (obj, ui_skinned_menurow_get_type (), UiSkinnedMenurow)
-#define UI_SKINNED_MENUROW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_menurow_get_type (), UiSkinnedMenurowClass)
-#define UI_SKINNED_IS_MENUROW(obj)       GTK_CHECK_TYPE (obj, ui_skinned_menurow_get_type ())
-
-typedef struct _UiSkinnedMenurow        UiSkinnedMenurow;
-typedef struct _UiSkinnedMenurowClass   UiSkinnedMenurowClass;
-
-typedef enum {
-    MENUROW_NONE, MENUROW_OPTIONS, MENUROW_ALWAYS, MENUROW_FILEINFOBOX,
-    MENUROW_SCALE, MENUROW_VISUALIZATION
-} MenuRowItem;
-
-struct _UiSkinnedMenurow {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    gboolean         scaled;
-    gint             nx, ny;
-    gint             sx, sy;
-    MenuRowItem      selected;
-    gboolean         always_selected;
-    gboolean         scale_selected;
-    gboolean         pushed;
-    SkinPixmapId     skin_index;
-};
-
-struct _UiSkinnedMenurowClass {
-    GtkWidgetClass          parent_class;
-    void (* scaled)        (UiSkinnedMenurow *menurow);
-    void (* change)         (UiSkinnedMenurow *menurow);
-    void (* release)        (UiSkinnedMenurow *menurow);
-};
-
-GtkWidget* ui_skinned_menurow_new (GtkWidget *fixed, gint x, gint y, gint nx, gint ny, gint sx, gint sy, SkinPixmapId si);
-GtkType ui_skinned_menurow_get_type(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_MENUROW_H */
--- a/src/audacious/ui_skinned_monostereo.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skin.h"
-#include "ui_skinned_monostereo.h"
-#include "main.h"
-
-enum {
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-static void ui_skinned_monostereo_class_init         (UiSkinnedMonoStereoClass *klass);
-static void ui_skinned_monostereo_init               (UiSkinnedMonoStereo *monostereo);
-static void ui_skinned_monostereo_destroy            (GtkObject *object);
-static void ui_skinned_monostereo_realize            (GtkWidget *widget);
-static void ui_skinned_monostereo_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_monostereo_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_monostereo_expose         (GtkWidget *widget, GdkEventExpose *event);
-static void ui_skinned_monostereo_toggle_scaled      (UiSkinnedMonoStereo *monostereo);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint monostereo_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_monostereo_get_type() {
-    static GType monostereo_type = 0;
-    if (!monostereo_type) {
-        static const GTypeInfo monostereo_info = {
-            sizeof (UiSkinnedMonoStereoClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_monostereo_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedMonoStereo),
-            0,
-            (GInstanceInitFunc) ui_skinned_monostereo_init,
-        };
-        monostereo_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedMonoStereo_", &monostereo_info, 0);
-    }
-
-    return monostereo_type;
-}
-
-static void ui_skinned_monostereo_class_init(UiSkinnedMonoStereoClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_monostereo_destroy;
-
-    widget_class->realize = ui_skinned_monostereo_realize;
-    widget_class->expose_event = ui_skinned_monostereo_expose;
-    widget_class->size_request = ui_skinned_monostereo_size_request;
-    widget_class->size_allocate = ui_skinned_monostereo_size_allocate;
-
-    klass->scaled = ui_skinned_monostereo_toggle_scaled;
-
-    monostereo_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedMonoStereoClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-}
-
-static void ui_skinned_monostereo_init(UiSkinnedMonoStereo *monostereo) {
-    monostereo->width = 56;
-    monostereo->height = 12;
-}
-
-GtkWidget* ui_skinned_monostereo_new(GtkWidget *fixed, gint x, gint y, SkinPixmapId si) {
-    UiSkinnedMonoStereo *monostereo = g_object_new (ui_skinned_monostereo_get_type (), NULL);
-
-    monostereo->x = x;
-    monostereo->y = y;
-    monostereo->skin_index = si;
-    monostereo->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(monostereo), monostereo->x, monostereo->y);
-
-    return GTK_WIDGET(monostereo);
-}
-
-static void ui_skinned_monostereo_destroy(GtkObject *object) {
-    UiSkinnedMonoStereo *monostereo;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_MONOSTEREO (object));
-
-    monostereo = UI_SKINNED_MONOSTEREO (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_monostereo_realize(GtkWidget *widget) {
-    UiSkinnedMonoStereo *monostereo;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_MONOSTEREO(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    monostereo = UI_SKINNED_MONOSTEREO(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_monostereo_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO(widget);
-
-    requisition->width = monostereo->width*(monostereo->scaled ? cfg.scale_factor : 1);
-    requisition->height = monostereo->height*(monostereo->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_monostereo_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO (widget);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (monostereo->scaled ? cfg.scale_factor : 1);
-    widget->allocation.y *= (monostereo->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    monostereo->x = widget->allocation.x/(monostereo->scaled ? cfg.scale_factor : 1);
-    monostereo->y = widget->allocation.y/(monostereo->scaled ? cfg.scale_factor : 1);
-}
-
-static gboolean ui_skinned_monostereo_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_MONOSTEREO (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO (widget);
-    g_return_val_if_fail (monostereo->width > 0 && monostereo->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, monostereo->width, monostereo->height);
-
-    switch (monostereo->num_channels) {
-    case 1:
-        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 29, 0, 0, 0, 27, 12);
-        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 0, 12, 27, 0, 29, 12);
-        break;
-    case 2:
-        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 29, 12, 0, 0, 27, 12);
-        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 0, 0, 27, 0, 29, 12);
-        break;
-    default:
-    case 0:
-        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 29, 12, 0, 0, 27, 12);
-        skin_draw_pixbuf(widget, aud_active_skin, obj, monostereo->skin_index, 0, 12, 27, 0, 29, 12);
-        break;
-    }
-
-    ui_skinned_widget_draw(widget, obj, monostereo->width, monostereo->height, monostereo->scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static void ui_skinned_monostereo_toggle_scaled(UiSkinnedMonoStereo *monostereo) {
-    GtkWidget *widget = GTK_WIDGET (monostereo);
-
-    monostereo->scaled = !monostereo->scaled;
-    gtk_widget_set_size_request(widget, monostereo->width*(monostereo->scaled ? cfg.scale_factor : 1), monostereo->height*(monostereo->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(GTK_WIDGET(monostereo));
-}
-
-void ui_skinned_monostereo_set_num_channels(GtkWidget *widget, gint nch) {
-    g_return_if_fail (UI_SKINNED_IS_MONOSTEREO (widget));
-    UiSkinnedMonoStereo *monostereo = UI_SKINNED_MONOSTEREO (widget);
-
-    monostereo->num_channels = nch;
-    gtk_widget_queue_draw(widget);
-}
--- a/src/audacious/ui_skinned_monostereo.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_MONOSTEREO_H
-#define AUDACIOUS_UI_SKINNED_MONOSTEREO_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_MONOSTEREO(obj)          GTK_CHECK_CAST (obj, ui_skinned_monostereo_get_type (), UiSkinnedMonoStereo)
-#define UI_SKINNED_MONOSTEREO_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_monostereo_get_type (), UiSkinnedMonoStereoClass)
-#define UI_SKINNED_IS_MONOSTEREO(obj)       GTK_CHECK_TYPE (obj, ui_skinned_monostereo_get_type ())
-
-typedef struct _UiSkinnedMonoStereo        UiSkinnedMonoStereo;
-typedef struct _UiSkinnedMonoStereoClass   UiSkinnedMonoStereoClass;
-
-struct _UiSkinnedMonoStereo {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    gint             num_channels;
-    SkinPixmapId     skin_index;
-    gboolean         scaled;
-};
-
-struct _UiSkinnedMonoStereoClass {
-    GtkWidgetClass          parent_class;
-    void (* scaled)        (UiSkinnedMonoStereo *menurow);
-};
-
-GtkWidget* ui_skinned_monostereo_new (GtkWidget *fixed, gint x, gint y, SkinPixmapId si);
-GtkType ui_skinned_monostereo_get_type(void);
-void ui_skinned_monostereo_set_num_channels(GtkWidget *widget, gint nch);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_MONOSTEREO_H */
--- a/src/audacious/ui_skinned_number.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skinned_number.h"
-#include "main.h"
-#include "strings.h"
-#include <string.h>
-#include <ctype.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkmarshal.h>
-
-#define UI_TYPE_SKINNED_NUMBER           (ui_skinned_number_get_type())
-
-enum {
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-static void ui_skinned_number_class_init         (UiSkinnedNumberClass *klass);
-static void ui_skinned_number_init               (UiSkinnedNumber *number);
-static void ui_skinned_number_destroy            (GtkObject *object);
-static void ui_skinned_number_realize            (GtkWidget *widget);
-static void ui_skinned_number_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_number_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_number_expose         (GtkWidget *widget, GdkEventExpose *event);
-static void ui_skinned_number_toggle_scaled  (UiSkinnedNumber *number);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint number_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_number_get_type() {
-    static GType number_type = 0;
-    if (!number_type) {
-        static const GTypeInfo number_info = {
-            sizeof (UiSkinnedNumberClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_number_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedNumber),
-            0,
-            (GInstanceInitFunc) ui_skinned_number_init,
-        };
-        number_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedNumber_", &number_info, 0);
-    }
-
-    return number_type;
-}
-
-static void ui_skinned_number_class_init(UiSkinnedNumberClass *klass) {
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_number_destroy;
-
-    widget_class->realize = ui_skinned_number_realize;
-    widget_class->expose_event = ui_skinned_number_expose;
-    widget_class->size_request = ui_skinned_number_size_request;
-    widget_class->size_allocate = ui_skinned_number_size_allocate;
-
-    klass->scaled = ui_skinned_number_toggle_scaled;
-
-    number_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedNumberClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-}
-
-static void ui_skinned_number_init(UiSkinnedNumber *number) {
-    number->width = 9;
-    number->height = 13;
-}
-
-GtkWidget* ui_skinned_number_new(GtkWidget *fixed, gint x, gint y, SkinPixmapId si) {
-    UiSkinnedNumber *number = g_object_new (ui_skinned_number_get_type (), NULL);
-
-    number->x = x;
-    number->y = y;
-    number->num = 0;
-    number->skin_index = si;
-
-    number->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(number), number->x, number->y);
-
-    return GTK_WIDGET(number);
-}
-
-static void ui_skinned_number_destroy(GtkObject *object) {
-    UiSkinnedNumber *number;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_NUMBER (object));
-
-    number = UI_SKINNED_NUMBER (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_number_realize(GtkWidget *widget) {
-    UiSkinnedNumber *number;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_NUMBER(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    number = UI_SKINNED_NUMBER(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_number_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedNumber *number = UI_SKINNED_NUMBER(widget);
-
-    requisition->width = number->width * ( number->scaled ? cfg.scale_factor : 1 );
-    requisition->height = number->height*( number->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_number_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (number->scaled ? cfg.scale_factor: 1 );
-    widget->allocation.y *= (number->scaled ? cfg.scale_factor: 1 );
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    number->x = widget->allocation.x/(number->scaled ? cfg.scale_factor : 1);
-    number->y = widget->allocation.y/(number->scaled ? cfg.scale_factor : 1);
-}
-
-static gboolean ui_skinned_number_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_NUMBER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
-    g_return_val_if_fail (number->width > 0 && number->height > 0, FALSE);
-
-    GdkPixbuf *obj;
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, number->width, number->height);
-
-    if (number->num > 11 || number->num < 0)
-        number->num = 10;
-
-    skin_draw_pixbuf(widget, aud_active_skin, obj,
-                     number->skin_index, number->num * 9, 0,
-                     0, 0, number->width, number->height);
-
-    ui_skinned_widget_draw(widget, obj, number->width, number->height, number->scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static void ui_skinned_number_toggle_scaled(UiSkinnedNumber *number) {
-    GtkWidget *widget = GTK_WIDGET (number);
-    number->scaled = !number->scaled;
-
-    gtk_widget_set_size_request(widget, number->width * ( number->scaled ? cfg.scale_factor : 1),
-        number->height * ( number->scaled ? cfg.scale_factor : 1) );
-
-    gtk_widget_queue_draw(GTK_WIDGET(number));
-}
-
-void ui_skinned_number_set_number(GtkWidget *widget, gint num) {
-    g_return_if_fail(UI_SKINNED_IS_NUMBER(widget));
-    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
-
-    if (number->num == num)
-         return;
-
-    number->num = num;
-    gtk_widget_queue_draw(GTK_WIDGET(number));
-}
-
-void ui_skinned_number_set_size(GtkWidget *widget, gint width, gint height) {
-    g_return_if_fail(UI_SKINNED_IS_NUMBER(widget));
-    UiSkinnedNumber *number = UI_SKINNED_NUMBER (widget);
-
-    number->width = width;
-    number->height = height;
-
-    gtk_widget_set_size_request(widget, width*(number->scaled ? cfg.scale_factor : 1 ),
-    height*(number->scaled ? cfg.scale_factor : 1 ));
-}
--- a/src/audacious/ui_skinned_number.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_NUMBER_H
-#define AUDACIOUS_UI_SKINNED_NUMBER_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_NUMBER(obj)          GTK_CHECK_CAST (obj, ui_skinned_number_get_type (), UiSkinnedNumber)
-#define UI_SKINNED_NUMBER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_number_get_type (), UiSkinnedNumberClass)
-#define UI_SKINNED_IS_NUMBER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_number_get_type ())
-
-typedef struct _UiSkinnedNumber        UiSkinnedNumber;
-typedef struct _UiSkinnedNumberClass   UiSkinnedNumberClass;
-
-struct _UiSkinnedNumber {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    gint             num;
-    gboolean         scaled;
-    SkinPixmapId     skin_index;
-};
-
-struct _UiSkinnedNumberClass {
-    GtkWidgetClass          parent_class;
-    void (* scaled)        (UiSkinnedNumber *textbox);
-};
-
-GtkWidget* ui_skinned_number_new (GtkWidget *fixed, gint x, gint y, SkinPixmapId si);
-GtkType ui_skinned_number_get_type(void);
-void ui_skinned_number_set_number(GtkWidget *widget, gint num);
-void ui_skinned_number_set_size(GtkWidget *widget, gint width, gint height);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_NUMBER_H */
--- a/src/audacious/ui_skinned_playlist.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1105 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- * Copyright (c) 2008 William Pitcock
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- *
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-/*
- *  A note about Pango and some funky spacey fonts: Weirdly baselined
- *  fonts, or fonts with weird ascents or descents _will_ display a
- *  little bit weird in the playlist widget, but the display engine
- *  won't make it look too bad, just a little deranged.  I honestly
- *  don't think it's worth fixing (around...), it doesn't have to be
- *  perfectly fitting, just the general look has to be ok, which it
- *  IMHO is.
- *
- *  A second note: The numbers aren't perfectly aligned, but in the
- *  end it looks better when using a single Pango layout for each
- *  number.
- */
-
-#include "ui_skinned_playlist.h"
-
-#include "debug.h"
-#include "input.h"
-#include "main.h"
-#include "playback.h"
-#include "playlist.h"
-#include "strings.h"
-#include "ui_fileinfopopup.h"
-#include "ui_manager.h"
-#include "ui_playlist.h"
-#include "ui_skin.h"
-#include "util.h"
-
-static PangoFontDescription *playlist_list_font = NULL;
-static gint ascent, descent, width_delta_digit_one;
-static gboolean has_slant;
-static guint padding;
-
-/* FIXME: the following globals should not be needed. */
-static gint width_approx_letters;
-static gint width_colon, width_colon_third;
-static gint width_approx_digits, width_approx_digits_half;
-
-#define UI_SKINNED_PLAYLIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_playlist_get_type(), UiSkinnedPlaylistPrivate))
-typedef struct _UiSkinnedPlaylistPrivate UiSkinnedPlaylistPrivate;
-
-enum {
-    REDRAW,
-    LAST_SIGNAL
-};
-
-struct _UiSkinnedPlaylistPrivate {
-    SkinPixmapId     skin_index;
-    gint             width, height;
-    gint             resize_width, resize_height;
-    gint             drag_pos;
-    gboolean         dragging, auto_drag_down, auto_drag_up;
-    gint             auto_drag_up_tag, auto_drag_down_tag;
-};
-
-static void ui_skinned_playlist_class_init         (UiSkinnedPlaylistClass *klass);
-static void ui_skinned_playlist_init               (UiSkinnedPlaylist *playlist);
-static void ui_skinned_playlist_destroy            (GtkObject *object);
-static void ui_skinned_playlist_realize            (GtkWidget *widget);
-static void ui_skinned_playlist_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_playlist_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_playlist_expose         (GtkWidget *widget, GdkEventExpose *event);
-static gboolean ui_skinned_playlist_button_press   (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_playlist_button_release (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_playlist_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
-static gboolean ui_skinned_playlist_leave_notify   (GtkWidget *widget, GdkEventCrossing *event);
-static void ui_skinned_playlist_redraw             (UiSkinnedPlaylist *playlist);
-static gboolean ui_skinned_playlist_popup_show     (gpointer data);
-static void ui_skinned_playlist_popup_hide         (GtkWidget *widget);
-static void ui_skinned_playlist_popup_timer_start  (GtkWidget *widget);
-static void ui_skinned_playlist_popup_timer_stop   (GtkWidget *widget);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint playlist_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_playlist_get_type() {
-    static GType playlist_type = 0;
-    if (!playlist_type) {
-        static const GTypeInfo playlist_info = {
-            sizeof (UiSkinnedPlaylistClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_playlist_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedPlaylist),
-            0,
-            (GInstanceInitFunc) ui_skinned_playlist_init,
-        };
-        playlist_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaylist_", &playlist_info, 0);
-    }
-
-    return playlist_type;
-}
-
-static void ui_skinned_playlist_class_init(UiSkinnedPlaylistClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_playlist_destroy;
-
-    widget_class->realize = ui_skinned_playlist_realize;
-    widget_class->expose_event = ui_skinned_playlist_expose;
-    widget_class->size_request = ui_skinned_playlist_size_request;
-    widget_class->size_allocate = ui_skinned_playlist_size_allocate;
-    widget_class->button_press_event = ui_skinned_playlist_button_press;
-    widget_class->button_release_event = ui_skinned_playlist_button_release;
-    widget_class->motion_notify_event = ui_skinned_playlist_motion_notify;
-    widget_class->leave_notify_event = ui_skinned_playlist_leave_notify;
-
-    klass->redraw = ui_skinned_playlist_redraw;
-
-    playlist_signals[REDRAW] = 
-        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedPlaylistClass, redraw), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    g_type_class_add_private (gobject_class, sizeof (UiSkinnedPlaylistPrivate));
-}
-
-static void ui_skinned_playlist_init(UiSkinnedPlaylist *playlist) {
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist);
-    playlist->pressed = FALSE;
-    priv->resize_width = 0;
-    priv->resize_height = 0;
-    playlist->prev_selected = -1;
-    playlist->prev_min = -1;
-    playlist->prev_max = -1;
-
-    g_object_set_data(G_OBJECT(playlist), "timer_id", GINT_TO_POINTER(0));
-    g_object_set_data(G_OBJECT(playlist), "timer_active", GINT_TO_POINTER(0));
-
-    GtkWidget *popup = fileinfopopup_create();
-    g_object_set_data(G_OBJECT(playlist), "popup", popup);
-    g_object_set_data(G_OBJECT(playlist), "popup_active", GINT_TO_POINTER(0));
-    g_object_set_data(G_OBJECT(playlist), "popup_position", GINT_TO_POINTER(-1));
-}
-
-GtkWidget* ui_skinned_playlist_new(GtkWidget *fixed, gint x, gint y, gint w, gint h) {
-
-    UiSkinnedPlaylist *hs = g_object_new (ui_skinned_playlist_get_type (), NULL);
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(hs);
-
-    hs->x = x;
-    hs->y = y;
-    priv->width = w;
-    priv->height = h;
-    priv->skin_index = SKIN_PLEDIT;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y);
-    gtk_widget_set_double_buffered(GTK_WIDGET(hs), TRUE);
-
-    return GTK_WIDGET(hs);
-}
-
-static void ui_skinned_playlist_destroy(GtkObject *object) {
-    UiSkinnedPlaylist *playlist;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_PLAYLIST (object));
-
-    playlist = UI_SKINNED_PLAYLIST (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_playlist_realize(GtkWidget *widget) {
-    UiSkinnedPlaylist *playlist;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_PLAYLIST(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    playlist = UI_SKINNED_PLAYLIST(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
-                             GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_playlist_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
-
-    requisition->width = priv->width;
-    requisition->height = priv->height;
-}
-
-static void ui_skinned_playlist_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedPlaylist *playlist = UI_SKINNED_PLAYLIST (widget);
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist);
-
-    widget->allocation = *allocation;
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    playlist->x = widget->allocation.x;
-    playlist->y = widget->allocation.y;
-
-    if (priv->height != widget->allocation.height || priv->width != widget->allocation.width) {
-        priv->width = priv->width + priv->resize_width;
-        priv->height = priv->height + priv->resize_height;
-        priv->resize_width = 0;
-        priv->resize_height = 0;
-        gtk_widget_queue_draw(widget);
-    }
-}
-
-static gboolean ui_skinned_playlist_auto_drag_down_func(gpointer data) {
-    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(data);
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(data);
-
-    if (priv->auto_drag_down) {
-        ui_skinned_playlist_move_down(pl);
-        pl->first++;
-        playlistwin_update_list(playlist_get_active());
-        return TRUE;
-    }
-    return FALSE;
-}
-
-static gboolean ui_skinned_playlist_auto_drag_up_func(gpointer data) {
-    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(data);
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(data);
-
-    if (priv->auto_drag_up) {
-        ui_skinned_playlist_move_up(pl);
-        pl->first--;
-        playlistwin_update_list(playlist_get_active());
-        return TRUE;
-
-    }
-    return FALSE;
-}
-
-void ui_skinned_playlist_move_up(UiSkinnedPlaylist * pl) {
-    GList *list;
-    Playlist *playlist = playlist_get_active();
-
-    if (!playlist)
-        return;
-
-    PLAYLIST_LOCK(playlist);
-    if ((list = playlist->entries) == NULL) {
-        PLAYLIST_UNLOCK(playlist);
-        return;
-    }
-    if (PLAYLIST_ENTRY(list->data)->selected) {
-        /* We are at the top */
-        PLAYLIST_UNLOCK(playlist);
-        return;
-    }
-    while (list) {
-        if (PLAYLIST_ENTRY(list->data)->selected)
-            glist_moveup(list);
-        list = g_list_next(list);
-    }
-    PLAYLIST_INCR_SERIAL(playlist);
-    PLAYLIST_UNLOCK(playlist);
-    if (pl->prev_selected != -1)
-        pl->prev_selected--;
-    if (pl->prev_min != -1)
-        pl->prev_min--;
-    if (pl->prev_max != -1)
-        pl->prev_max--;
-}
-
-void ui_skinned_playlist_move_down(UiSkinnedPlaylist * pl) {
-    GList *list;
-    Playlist *playlist = playlist_get_active();
-
-    if (!playlist)
-        return;
-
-    PLAYLIST_LOCK(playlist);
-
-    if (!(list = g_list_last(playlist->entries))) {
-        PLAYLIST_UNLOCK(playlist);
-        return;
-    }
-
-    if (PLAYLIST_ENTRY(list->data)->selected) {
-        /* We are at the bottom */
-        PLAYLIST_UNLOCK(playlist);
-        return;
-    }
-
-    while (list) {
-        if (PLAYLIST_ENTRY(list->data)->selected)
-            glist_movedown(list);
-        list = g_list_previous(list);
-    }
-
-    PLAYLIST_INCR_SERIAL(playlist);
-    PLAYLIST_UNLOCK(playlist);
-
-    if (pl->prev_selected != -1)
-        pl->prev_selected++;
-    if (pl->prev_min != -1)
-        pl->prev_min++;
-    if (pl->prev_max != -1)
-        pl->prev_max++;
-}
-
-static void
-playlist_list_draw_string(cairo_t *cr, UiSkinnedPlaylist *pl,
-                          PangoFontDescription * font,
-                          gint line,
-                          gint width,
-                          const gchar * text,
-                          guint ppos)
-{
-    guint plist_length_int;
-    Playlist *playlist = playlist_get_active();
-    PangoLayout *layout;
-
-    REQUIRE_LOCK(playlist->mutex);
-
-    cairo_new_path(cr);
-
-    if (cfg.show_numbers_in_pl) {
-        gchar *pos_string = g_strdup_printf(cfg.show_separator_in_pl == TRUE ? "%d" : "%d.", ppos);
-        plist_length_int =
-            gint_count_digits(playlist_get_length(playlist)) + !cfg.show_separator_in_pl + 1; /* cf.show_separator_in_pl will be 0 if false */
-
-        padding = plist_length_int;
-        padding = ((padding + 1) * width_approx_digits);
-
-        layout = gtk_widget_create_pango_layout(playlistwin, pos_string);
-        pango_layout_set_font_description(layout, playlist_list_font);
-        pango_layout_set_width(layout, plist_length_int * 100);
-
-        pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
-
-        cairo_move_to(cr, (width_approx_digits *
-                         (-1 + plist_length_int - strlen(pos_string))) +
-                        (width_approx_digits / 4), (line - 1) * pl->fheight +
-                        ascent + abs(descent));
-        pango_cairo_show_layout(cr, layout);
-
-        g_free(pos_string);
-        g_object_unref(layout);
-
-        if (!cfg.show_separator_in_pl)
-            padding -= (width_approx_digits * 1.5);
-    } else {
-        padding = 3;
-    }
-
-    width -= padding;
-
-    layout = gtk_widget_create_pango_layout(playlistwin, text);
-
-    pango_layout_set_font_description(layout, playlist_list_font);
-    pango_layout_set_width(layout, width * PANGO_SCALE);
-    pango_layout_set_single_paragraph_mode(layout, TRUE);
-    pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
-
-    cairo_move_to(cr, padding + (width_approx_letters / 4),
-                    (line - 1) * pl->fheight +
-                    ascent + abs(descent));
-    pango_cairo_show_layout(cr, layout);
-
-    g_object_unref(layout);
-}
-
-static gboolean ui_skinned_playlist_expose(GtkWidget *widget, GdkEventExpose *event) {
-    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget);
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(pl);
-    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
-
-    Playlist *playlist = playlist_get_active();
-    PlaylistEntry *entry;
-    GList *list;
-    PangoLayout *layout;
-    gchar *title;
-    gint width, height;
-    gint i, max_first;
-    guint padding, padding_dwidth, padding_plength;
-    guint max_time_len = 0;
-    gfloat queue_tailpadding = 0;
-    gint tpadding; 
-    gsize tpadding_dwidth = 0;
-    gint x, y;
-    guint tail_width;
-    guint tail_len;
-    gboolean in_selection = FALSE;
-
-    gchar tail[100];
-    gchar queuepos[255];
-    gchar length[40];
-
-    gchar **frags;
-    gchar *frag0;
-
-    gint plw_w, plw_h;
-
-    cairo_t *cr;
-    gint yc;
-    gint pos;
-    gdouble rounding_offset;
-
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_PLAYLIST (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    cr = gdk_cairo_create(widget->window);
-
-    width = priv->width;
-    height = priv->height;
-
-    plw_w = playlistwin_get_width();
-    plw_h = playlistwin_get_height();
-
-    gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMALBG));
-
-    cairo_rectangle(cr, 0, 0, width, height);
-    cairo_paint(cr);
-
-    if (!playlist_list_font) {
-        g_critical("Couldn't open playlist font");
-        return FALSE;
-    }
-
-    pl->fheight = (ascent + abs(descent));
-    pl->num_visible = height / pl->fheight;
-
-    rounding_offset = pl->fheight / 3;
-
-    max_first = playlist_get_length(playlist) - pl->num_visible;
-    max_first = MAX(max_first, 0);
-
-    pl->first = CLAMP(pl->first, 0, max_first);
-
-    PLAYLIST_LOCK(playlist);
-    list = playlist->entries;
-    list = g_list_nth(list, pl->first);
-
-    /* It sucks having to run the iteration twice but this is the only
-       way you can reliably get the maximum width so we can get our
-       playlist nice and aligned... -- plasmaroo */
-
-    for (i = pl->first;
-         list && i < pl->first + pl->num_visible;
-         list = g_list_next(list), i++) {
-        entry = list->data;
-
-        if (entry->length != -1)
-        {
-            g_snprintf(length, sizeof(length), "%d:%-2.2d",
-                       entry->length / 60000, (entry->length / 1000) % 60);
-            tpadding_dwidth = MAX(tpadding_dwidth, strlen(length));
-        }
-    }
-
-    /* Reset */
-    list = playlist->entries;
-    list = g_list_nth(list, pl->first);
-
-    for (i = pl->first;
-         list && i < pl->first + pl->num_visible;
-         list = g_list_next(list), i++) {
-        entry = list->data;
-
-        if (entry->selected && !in_selection) {
-            yc = ((i - pl->first) * pl->fheight);
-
-            cairo_new_path(cr);
-
-            cairo_move_to(cr, 0, yc + (rounding_offset * 2));
-            cairo_curve_to(cr, 0, yc + rounding_offset, 0, yc + 0.5, 0 + rounding_offset, yc + 0.5);
-
-            cairo_line_to(cr, 0 + width - (rounding_offset * 2), yc + 0.5);
-            cairo_curve_to(cr, 0 + width - rounding_offset, yc + 0.5,
-                        0 + width, yc + 0.5, 0 + width, yc + rounding_offset);
-
-            in_selection = TRUE;
-        }
-
-        if ((!entry->selected ||
-            (i == pl->first + pl->num_visible - 1) || !g_list_next(list))
-            && in_selection) {
-
-            if (!entry->selected)
-                yc = (((i - 1) - pl->first) * pl->fheight);
-            else /* last visible item */
-                yc = ((i - pl->first) * pl->fheight);
-
-            cairo_line_to(cr, 0 + width, yc + pl->fheight - (rounding_offset * 2));
-            cairo_curve_to (cr, 0 + width, yc + pl->fheight - rounding_offset,
-                        0 + width, yc + pl->fheight - 0.5,
-                        0 + width-rounding_offset, yc + pl->fheight - 0.5);
-
-            cairo_line_to (cr, 0 + (rounding_offset * 2), yc + pl->fheight - 0.5);
-            cairo_curve_to (cr, 0 + rounding_offset, yc + pl->fheight - 0.5,
-                        0, yc + pl->fheight - 0.5,
-                        0, yc + pl->fheight - rounding_offset);
-
-            cairo_close_path (cr);
-
-            gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_SELECTEDBG));
-
-            cairo_fill(cr);
-
-            in_selection = FALSE;
-        }
-    }
-
-    list = playlist->entries;
-    list = g_list_nth(list, pl->first);
-
-    /* now draw the text */
-    for (i = pl->first;
-         list && i < pl->first + pl->num_visible;
-         list = g_list_next(list), i++) {
-        entry = list->data;
-
-        /* FIXME: entry->title should NEVER be NULL, and there should
-           NEVER be a need to do a UTF-8 conversion. Playlist title
-           strings should be kept properly. */
-
-        if (!entry->title) {
-            gchar *realfn = g_filename_from_uri(entry->filename, NULL, NULL);
-            gchar *basename = g_path_get_basename(realfn ? realfn : entry->filename);
-            title = filename_to_utf8(basename);
-            g_free(basename); g_free(realfn);
-        }
-        else
-            title = str_assert_utf8(entry->title);
-
-        title = convert_title_text(title);
-
-        pos = playlist_get_queue_position(playlist, entry);
-
-        tail[0] = 0;
-        queuepos[0] = 0;
-        length[0] = 0;
-
-        if (pos != -1)
-            g_snprintf(queuepos, sizeof(queuepos), "%d", pos + 1);
-
-        if (entry->length != -1)
-        {
-            g_snprintf(length, sizeof(length), "%d:%-2.2d",
-                       entry->length / 60000, (entry->length / 1000) % 60);
-        }
-
-        strncat(tail, length, sizeof(tail) - 1);
-        tail_len = strlen(tail);
-
-        max_time_len = MAX(max_time_len, tail_len);
-
-        if (pos != -1 && tpadding_dwidth <= 0)
-            tail_width = width - (width_approx_digits * (strlen(queuepos) + 2.25));
-        else if (pos != -1)
-            tail_width = width - (width_approx_digits * (tpadding_dwidth + strlen(queuepos) + 4));
-        else if (tpadding_dwidth > 0)
-            tail_width = width - (width_approx_digits * (tpadding_dwidth + 2.5));
-        else
-            tail_width = width;
-
-        if (i == playlist_get_position_nolock(playlist))
-            gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT));
-        else
-            gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMAL));
-
-        playlist_list_draw_string(cr, pl, playlist_list_font,
-                                  i - pl->first, tail_width, title,
-                                  i + 1);
-
-        x = width - width_approx_digits * 2;
-        y = ((i - pl->first) - 1) * pl->fheight + ascent;
-
-        frags = NULL;
-        frag0 = NULL;
-
-        if ((strlen(tail) > 0) && (tail != NULL)) {
-            frags = g_strsplit(tail, ":", 0);
-            frag0 = g_strconcat(frags[0], ":", NULL);
-
-            layout = gtk_widget_create_pango_layout(playlistwin, frags[1]);
-            pango_layout_set_font_description(layout, playlist_list_font);
-            pango_layout_set_width(layout, tail_len * 100);
-            pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
-
-            cairo_new_path(cr);
-            cairo_move_to(cr, x - (0.5 * width_approx_digits), y + abs(descent));
-            pango_cairo_show_layout(cr, layout);
-            g_object_unref(layout);
-
-            layout = gtk_widget_create_pango_layout(playlistwin, frag0);
-            pango_layout_set_font_description(layout, playlist_list_font);
-            pango_layout_set_width(layout, tail_len * 100);
-            pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
-
-            cairo_move_to(cr, x - (0.75 * width_approx_digits), y + abs(descent));
-            pango_cairo_show_layout(cr, layout);
-            g_object_unref(layout);
-
-            g_free(frag0);
-            g_strfreev(frags);
-        }
-
-        if (pos != -1) {
-            if (tpadding_dwidth > 0)
-                queue_tailpadding = tpadding_dwidth + 1;
-            else
-                queue_tailpadding = -0.75;
-
-            cairo_rectangle(cr,
-                            x -
-                            (((queue_tailpadding +
-                               strlen(queuepos)) *
-                              width_approx_digits) +
-                             (width_approx_digits / 4)),
-                            y + abs(descent),
-                            (strlen(queuepos)) *
-                            width_approx_digits +
-                            (width_approx_digits / 2),
-                            pl->fheight - 2);
-
-            layout =
-                gtk_widget_create_pango_layout(playlistwin, queuepos);
-            pango_layout_set_font_description(layout, playlist_list_font);
-            pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
-
-            cairo_move_to(cr,
-                            x -
-                            ((queue_tailpadding +
-                              strlen(queuepos)) * width_approx_digits) +
-                            (width_approx_digits / 4),
-                            y + abs(descent));
-            pango_cairo_show_layout(cr, layout);
-
-            g_object_unref(layout);
-        }
-
-        cairo_stroke(cr);
-
-        g_free(title);
-    }
-
-
-    /*
-     * Drop target hovering over the playlist, so draw some hint where the
-     * drop will occur.
-     *
-     * This is (currently? unfixably?) broken when dragging files from Qt/KDE apps,
-     * probably due to DnD signaling problems (actually i have no clue).
-     *
-     */
-
-    if (pl->drag_motion) {
-        guint pos, plength, lpadding;
-
-        if (cfg.show_numbers_in_pl) {
-            lpadding = gint_count_digits(playlist_get_length(playlist)) + 1;
-            lpadding = ((lpadding + 1) * width_approx_digits);
-        }
-        else {
-            lpadding = 3;
-        };
-
-        /* We already hold the mutex and have the playlist locked, so call
-           the non-locking function. */
-        plength = playlist_get_length(playlist);
-
-        x = pl->drag_motion_x;
-        y = pl->drag_motion_y;
-
-        if ((x > pl->x) && !(x > priv->width)) {
-
-            if ((y > pl->y)
-                && !(y > (priv->height + pl->y))) {
-
-                pos = (y / pl->fheight) +
-                    pl->first;
-
-                if (pos > (plength)) {
-                    pos = plength;
-                }
-
-                gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT));
-
-                cairo_new_path(cr);
-
-                cairo_move_to(cr, 0, ((pos - pl->first) * pl->fheight));
-                cairo_rel_line_to(cr, priv->width - 1, 0);
-
-                cairo_set_line_width(cr, 1);
-                cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
-                cairo_stroke(cr);
-            }
-
-        }
-
-        /* When dropping on the borders of the playlist, outside the text area,
-         * files get appended at the end of the list. Show that too.
-         */
-
-        if ((y < pl->y) || (y > priv->height + pl->y)) {
-            if ((y >= 0) || (y <= (priv->height + pl->y))) {
-                pos = plength;
-
-                gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_CURRENT));
-
-                cairo_new_path(cr);
-
-                cairo_move_to(cr, 0, ((pos - pl->first) * pl->fheight));
-                cairo_rel_line_to(cr, priv->width - 1, 0);
-
-                cairo_set_line_width(cr, 1);
-                cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
-                cairo_stroke(cr);
-            }
-        }
-    }
-
-    gdk_cairo_set_source_color(cr, skin_get_color(aud_active_skin, SKIN_PLEDIT_NORMAL));
-    cairo_set_line_width(cr, 1);
-    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
-
-    if (cfg.show_numbers_in_pl)
-    {
-        padding_plength = playlist_get_length(playlist);
-
-        if (padding_plength == 0) {
-            padding_dwidth = 0;
-        }
-        else {
-            padding_dwidth = gint_count_digits(playlist_get_length(playlist));
-        }
-
-        padding =
-            (padding_dwidth *
-             width_approx_digits) + width_approx_digits;
-
-
-        /* For italic or oblique fonts we add another half of the
-         * approximate width */
-        if (has_slant)
-            padding += width_approx_digits_half;
-
-        if (cfg.show_separator_in_pl) {
-            cairo_new_path(cr);
-
-            cairo_move_to(cr, padding, 0);
-            cairo_rel_line_to(cr, 0, priv->height - 1);
-
-            cairo_stroke(cr);
-        }
-    }
-
-    if (tpadding_dwidth != 0)
-    {
-        tpadding = (tpadding_dwidth * width_approx_digits) + (width_approx_digits * 1.5);
-
-        if (has_slant)
-            tpadding += width_approx_digits_half;
-
-        if (cfg.show_separator_in_pl) {
-            cairo_new_path(cr);
-
-            cairo_move_to(cr, priv->width - tpadding, 0);
-            cairo_rel_line_to(cr, 0, priv->height - 1);
-
-            cairo_stroke(cr);
-        }
-    }
-
-    PLAYLIST_UNLOCK(playlist);
-
-    cairo_destroy(cr);
-
-    return FALSE;
-}
-
-gint ui_skinned_playlist_get_position(GtkWidget *widget, gint x, gint y) {
-    gint iy, length;
-    gint ret;
-    Playlist *playlist = playlist_get_active();
-    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget);
-
-    if (!pl->fheight)
-        return -1;
-
-    if ((length = playlist_get_length(playlist)) == 0)
-        return -1;
-    iy = y;
-
-    ret = (iy / pl->fheight) + pl->first;
-
-    if (ret > length - 1)
-        ret = -1;
-
-    return ret;
-}
-
-static gboolean ui_skinned_playlist_button_press(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget);
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
-
-    gint nr;
-    Playlist *playlist = playlist_get_active();
-
-    nr = ui_skinned_playlist_get_position(widget, event->x, event->y);
-    if (nr == -1)
-        return FALSE;
-
-    if (event->button == 3) {
-        ui_manager_popup_menu_show(GTK_MENU(playlistwin_popup_menu),
-                                   event->x_root, event->y_root + 5,
-                                   event->button, event->time);
-        GList* selection = playlist_get_selected(playlist);
-        if (g_list_find(selection, GINT_TO_POINTER(nr)) == NULL) {
-            playlist_select_all(playlist, FALSE);
-            playlist_select_range(playlist, nr, nr, TRUE);
-        }
-    } else if (event->button == 1) {
-        if (!(event->state & GDK_CONTROL_MASK))
-            playlist_select_all(playlist, FALSE);
-
-        if ((event->state & GDK_MOD1_MASK))
-            playlist_queue_position(playlist, nr);
-
-        if (event->state & GDK_SHIFT_MASK && pl->prev_selected != -1) {
-            playlist_select_range(playlist, pl->prev_selected, nr, TRUE);
-            pl->prev_min = pl->prev_selected;
-            pl->prev_max = nr;
-            priv->drag_pos = nr - pl->first;
-        }
-        else {
-            if (playlist_select_invert(playlist, nr)) {
-                if (event->state & GDK_CONTROL_MASK) {
-                    if (pl->prev_min == -1) {
-                        pl->prev_min = pl->prev_selected;
-                        pl->prev_max = pl->prev_selected;
-                    }
-                    if (nr < pl->prev_min)
-                        pl->prev_min = nr;
-                    else if (nr > pl->prev_max)
-                        pl->prev_max = nr;
-                }
-                else
-                    pl->prev_min = -1;
-                pl->prev_selected = nr;
-                priv->drag_pos = nr - pl->first;
-            }
-        }
-        if (event->type == GDK_2BUTTON_PRESS) {
-            /*
-             * Ungrab the pointer to prevent us from
-             * hanging on to it during the sometimes slow
-             * playback_initiate().
-             */
-            gdk_pointer_ungrab(GDK_CURRENT_TIME);
-            playlist_set_position(playlist, nr);
-            if (!playback_get_playing())
-                playback_initiate();
-        }
-
-        priv->dragging = TRUE;
-    }
-    playlistwin_update_list(playlist);
-    ui_skinned_playlist_popup_hide(widget);
-    ui_skinned_playlist_popup_timer_stop(widget);
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_playlist_button_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
-
-    priv->dragging = FALSE;
-    priv->auto_drag_down = FALSE;
-    priv->auto_drag_up = FALSE;
-    gtk_widget_queue_draw(widget);
-
-    ui_skinned_playlist_popup_hide(widget);
-    ui_skinned_playlist_popup_timer_stop(widget);
-    return TRUE;
-}
-
-static gboolean ui_skinned_playlist_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
-    UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST(widget);
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
-
-    gint nr, y, off, i;
-    if (priv->dragging) {
-        y = event->y;
-        nr = (y / pl->fheight);
-        if (nr < 0) {
-            nr = 0;
-            if (!priv->auto_drag_up) {
-                priv->auto_drag_up = TRUE;
-                priv->auto_drag_up_tag =
-                    g_timeout_add(100, ui_skinned_playlist_auto_drag_up_func, pl);
-            }
-        }
-        else if (priv->auto_drag_up)
-            priv->auto_drag_up = FALSE;
-
-        if (nr >= pl->num_visible) {
-            nr = pl->num_visible - 1;
-            if (!priv->auto_drag_down) {
-                priv->auto_drag_down = TRUE;
-                priv->auto_drag_down_tag =
-                    g_timeout_add(100, ui_skinned_playlist_auto_drag_down_func, pl);
-            }
-        }
-        else if (priv->auto_drag_down)
-            priv->auto_drag_down = FALSE;
-
-        off = nr - priv->drag_pos;
-        if (off) {
-            for (i = 0; i < abs(off); i++) {
-                if (off < 0)
-                    ui_skinned_playlist_move_up(pl);
-                else
-                    ui_skinned_playlist_move_down(pl);
-
-            }
-            playlistwin_update_list(playlist_get_active());
-        }
-        priv->drag_pos = nr;
-    } else if (cfg.show_filepopup_for_tuple) {
-        gint pos = ui_skinned_playlist_get_position(widget, event->x, event->y);
-        gint cur_pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_position"));
-        if (pos != cur_pos) {
-            g_object_set_data(G_OBJECT(widget), "popup_position", GINT_TO_POINTER(pos));
-            ui_skinned_playlist_popup_hide(widget);
-            ui_skinned_playlist_popup_timer_stop(widget);
-            if (pos != -1)
-                ui_skinned_playlist_popup_timer_start(widget);
-        }
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_playlist_leave_notify(GtkWidget *widget, GdkEventCrossing *event) {
-    ui_skinned_playlist_popup_hide(widget);
-    ui_skinned_playlist_popup_timer_stop(widget);
-
-    return FALSE;
-}
-
-static void ui_skinned_playlist_redraw(UiSkinnedPlaylist *playlist) {
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(playlist);
-
-    if (priv->resize_height || priv->resize_width)
-        gtk_widget_set_size_request(GTK_WIDGET(playlist), priv->width+priv->resize_width, priv->height+priv->resize_height);
-
-    gtk_widget_queue_draw(GTK_WIDGET(playlist));
-}
-
-void ui_skinned_playlist_set_font(const gchar * font) {
-    /* Welcome to bad hack central 2k3 */
-    gchar *font_lower;
-    gint width_temp;
-    gint width_temp_0;
-
-    playlist_list_font = pango_font_description_from_string(font);
-
-    text_get_extents(font,
-                     "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ",
-                     &width_approx_letters, NULL, &ascent, &descent);
-
-    width_approx_letters = (width_approx_letters / 53);
-
-    /* Experimental: We don't weigh the 1 into total because it's width is almost always
-     * very different from the rest
-     */
-    text_get_extents(font, "023456789", &width_approx_digits, NULL, NULL,
-                     NULL);
-    width_approx_digits = (width_approx_digits / 9);
-
-    /* Precache some often used calculations */
-    width_approx_digits_half = width_approx_digits / 2;
-
-    /* FIXME: We assume that any other number is broader than the "1" */
-    text_get_extents(font, "1", &width_temp, NULL, NULL, NULL);
-    text_get_extents(font, "2", &width_temp_0, NULL, NULL, NULL);
-
-    if (abs(width_temp_0 - width_temp) < 2) {
-        width_delta_digit_one = 0;
-    }
-    else {
-        width_delta_digit_one = ((width_temp_0 - width_temp) / 2) + 2;
-    }
-
-    text_get_extents(font, ":", &width_colon, NULL, NULL, NULL);
-    width_colon_third = width_colon / 4;
-
-    font_lower = g_utf8_strdown(font, strlen(font));
-    /* This doesn't take any i18n into account, but i think there is none with TTF fonts
-     * FIXME: This can probably be retrieved trough Pango too
-     */
-    has_slant = g_strstr_len(font_lower, strlen(font_lower), "oblique")
-        || g_strstr_len(font_lower, strlen(font_lower), "italic");
-
-    g_free(font_lower);
-}
-
-void ui_skinned_playlist_resize_relative(GtkWidget *widget, gint w, gint h) {
-    UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
-    priv->resize_width += w;
-    priv->resize_height += h;
-}
-
-static gboolean ui_skinned_playlist_popup_show(gpointer data) {
-    GtkWidget *widget = data;
-    gint pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_position"));
-
-    if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_active")) == 1 && pos != -1) {
-        Tuple *tuple;
-        Playlist *pl_active = playlist_get_active();
-        GtkWidget *popup = g_object_get_data(G_OBJECT(widget), "popup");
-
-        tuple = playlist_get_tuple(pl_active, pos);
-        if ((tuple == NULL) || (tuple_get_int(tuple, FIELD_LENGTH, NULL) < 1)) {
-           gchar *title = playlist_get_songtitle(pl_active, pos);
-           fileinfopopup_show_from_title(popup, title);
-           g_free(title);
-        } else {
-           fileinfopopup_show_from_tuple(popup , tuple);
-        }
-        g_object_set_data(G_OBJECT(widget), "popup_active" , GINT_TO_POINTER(1));
-    }
-
-    ui_skinned_playlist_popup_timer_stop(widget);
-    return FALSE;
-}
-
-static void ui_skinned_playlist_popup_hide(GtkWidget *widget) {
-    if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "popup_active")) == 1) {
-        GtkWidget *popup = g_object_get_data(G_OBJECT(widget), "popup");
-        g_object_set_data(G_OBJECT(widget), "popup_active", GINT_TO_POINTER(0));
-        fileinfopopup_hide(popup, NULL);
-    }
-}
-
-static void ui_skinned_playlist_popup_timer_start(GtkWidget *widget) {
-    gint timer_id = g_timeout_add(cfg.filepopup_delay*100, ui_skinned_playlist_popup_show, widget);
-    g_object_set_data(G_OBJECT(widget), "timer_id", GINT_TO_POINTER(timer_id));
-    g_object_set_data(G_OBJECT(widget), "timer_active", GINT_TO_POINTER(1));
-}
-
-static void ui_skinned_playlist_popup_timer_stop(GtkWidget *widget) {
-    if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_active")) == 1)
-        g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "timer_id")));
-
-    g_object_set_data(G_OBJECT(widget), "timer_id", GINT_TO_POINTER(0));
-    g_object_set_data(G_OBJECT(widget), "timer_active", GINT_TO_POINTER(0));
-}
--- a/src/audacious/ui_skinned_playlist.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_PLAYLIST_H
-#define AUDACIOUS_UI_SKINNED_PLAYLIST_H
-
-#include <gtk/gtk.h>
-
-#include <cairo.h>
-#include <pango/pangocairo.h>
-
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_PLAYLIST(obj)          GTK_CHECK_CAST (obj, ui_skinned_playlist_get_type (), UiSkinnedPlaylist)
-#define UI_SKINNED_PLAYLIST_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_playlist_get_type (), UiSkinnedPlaylistClass)
-#define UI_SKINNED_IS_PLAYLIST(obj)       GTK_CHECK_TYPE (obj, ui_skinned_playlist_get_type ())
-
-typedef struct _UiSkinnedPlaylist        UiSkinnedPlaylist;
-typedef struct _UiSkinnedPlaylistClass   UiSkinnedPlaylistClass;
-
-struct _UiSkinnedPlaylist {
-    GtkWidget   widget;
-    gboolean    pressed;
-    gint        x, y;
-    gint        first;
-    gint        num_visible;
-    gint        prev_selected, prev_min, prev_max;
-    gboolean    drag_motion;
-    gint        drag_motion_x, drag_motion_y;
-    gint        fheight;
-};
-
-struct _UiSkinnedPlaylistClass {
-    GtkWidgetClass    parent_class;
-    void (* redraw)   (UiSkinnedPlaylist *playlist);
-};
-
-GtkWidget* ui_skinned_playlist_new(GtkWidget *fixed, gint x, gint y, gint w, gint h);
-GtkType ui_skinned_playlist_get_type(void);
-void ui_skinned_playlist_resize_relative(GtkWidget *widget, gint w, gint h);
-void ui_skinned_playlist_set_font(const gchar * font);
-void ui_skinned_playlist_move_up(UiSkinnedPlaylist *pl);
-void ui_skinned_playlist_move_down(UiSkinnedPlaylist *pl);
-gint ui_skinned_playlist_get_position(GtkWidget *widget, gint x, gint y);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_PLAYLIST_H */
--- a/src/audacious/ui_skinned_playlist_slider.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skin.h"
-#include "ui_skinned_playlist_slider.h"
-#include "main.h"
-#include "ui_playlist.h"
-
-#define UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_playlist_slider_get_type(), UiSkinnedPlaylistSliderPrivate))
-typedef struct _UiSkinnedPlaylistSliderPrivate UiSkinnedPlaylistSliderPrivate;
-
-enum {
-    REDRAW,
-    LAST_SIGNAL
-};
-
-struct _UiSkinnedPlaylistSliderPrivate {
-    SkinPixmapId     skin_index;
-    gint             width, height;
-
-    gint             resize_height;
-    gint             move_x;
-    gint             prev_y;
-    gint             drag_y;
-};
-
-static void ui_skinned_playlist_slider_class_init         (UiSkinnedPlaylistSliderClass *klass);
-static void ui_skinned_playlist_slider_init               (UiSkinnedPlaylistSlider *playlist_slider);
-static void ui_skinned_playlist_slider_destroy            (GtkObject *object);
-static void ui_skinned_playlist_slider_realize            (GtkWidget *widget);
-static void ui_skinned_playlist_slider_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_playlist_slider_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_playlist_slider_expose         (GtkWidget *widget, GdkEventExpose *event);
-static void ui_skinned_playlist_slider_set_position       (GtkWidget *widget, gint y);
-static gboolean ui_skinned_playlist_slider_button_press   (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_playlist_slider_button_release (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_playlist_slider_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
-static void ui_skinned_playlist_slider_redraw             (UiSkinnedPlaylistSlider *playlist_slider);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint playlist_slider_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_playlist_slider_get_type() {
-    static GType playlist_slider_type = 0;
-    if (!playlist_slider_type) {
-        static const GTypeInfo playlist_slider_info = {
-            sizeof (UiSkinnedPlaylistSliderClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_playlist_slider_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedPlaylistSlider),
-            0,
-            (GInstanceInitFunc) ui_skinned_playlist_slider_init,
-        };
-        playlist_slider_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaylistSlider_", &playlist_slider_info, 0);
-    }
-
-    return playlist_slider_type;
-}
-
-static void ui_skinned_playlist_slider_class_init(UiSkinnedPlaylistSliderClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_playlist_slider_destroy;
-
-    widget_class->realize = ui_skinned_playlist_slider_realize;
-    widget_class->expose_event = ui_skinned_playlist_slider_expose;
-    widget_class->size_request = ui_skinned_playlist_slider_size_request;
-    widget_class->size_allocate = ui_skinned_playlist_slider_size_allocate;
-    widget_class->button_press_event = ui_skinned_playlist_slider_button_press;
-    widget_class->button_release_event = ui_skinned_playlist_slider_button_release;
-    widget_class->motion_notify_event = ui_skinned_playlist_slider_motion_notify;
-
-    klass->redraw = ui_skinned_playlist_slider_redraw;
-
-    playlist_slider_signals[REDRAW] = 
-        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedPlaylistSliderClass, redraw), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    g_type_class_add_private (gobject_class, sizeof (UiSkinnedPlaylistSliderPrivate));
-}
-
-static void ui_skinned_playlist_slider_init(UiSkinnedPlaylistSlider *playlist_slider) {
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider);
-    playlist_slider->pressed = FALSE;
-    priv->resize_height = 0;
-    priv->move_x = 0;
-    priv->drag_y = 0;
-    priv->prev_y = 0;
-}
-
-GtkWidget* ui_skinned_playlist_slider_new(GtkWidget *fixed, gint x, gint y, gint h) {
-
-    UiSkinnedPlaylistSlider *hs = g_object_new (ui_skinned_playlist_slider_get_type (), NULL);
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(hs);
-
-    hs->x = x;
-    hs->y = y;
-    priv->width = 8;
-    priv->height = h;
-    priv->skin_index = SKIN_PLEDIT;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(hs), hs->x, hs->y);
-
-    return GTK_WIDGET(hs);
-}
-
-static void ui_skinned_playlist_slider_destroy(GtkObject *object) {
-    UiSkinnedPlaylistSlider *playlist_slider;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER (object));
-
-    playlist_slider = UI_SKINNED_PLAYLIST_SLIDER (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_playlist_slider_realize(GtkWidget *widget) {
-    UiSkinnedPlaylistSlider *playlist_slider;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    playlist_slider = UI_SKINNED_PLAYLIST_SLIDER(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
-                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_playlist_slider_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
-
-    requisition->width = priv->width;
-    requisition->height = priv->height;
-}
-
-static void ui_skinned_playlist_slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedPlaylistSlider *playlist_slider = UI_SKINNED_PLAYLIST_SLIDER (widget);
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider);
-
-    widget->allocation = *allocation;
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    if (playlist_slider->x + priv->move_x == widget->allocation.x)
-        priv->move_x = 0;
-    playlist_slider->x = widget->allocation.x;
-    playlist_slider->y = widget->allocation.y;
-
-    if (priv->height != widget->allocation.height) {
-        priv->height = priv->height + priv->resize_height;
-        priv->resize_height = 0;
-        gtk_widget_queue_draw(widget);
-    }
-}
-
-static gboolean ui_skinned_playlist_slider_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_PLAYLIST_SLIDER (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER (widget);
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(ps);
-    g_return_val_if_fail (priv->width > 0 && priv->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, priv->width, priv->height);
-
-    gint num_visible;
-    num_visible = playlistwin_list_get_visible_count();
-
-
-    Playlist *playlist = playlist_get_active();
-
-    gint y;
-    if (playlist_get_length(playlist) > num_visible)
-        y = (playlistwin_list_get_first() * (priv->height - 19)) /
-            (playlist_get_length(playlist) - num_visible);
-    else
-        y = 0;
-
-    if (y < 0) y=0;
-    if (y > priv->height - 19) y = priv->height - 19;
-
-    priv->prev_y = y;
-
-    /* FIXME: uses aud_active_skin->pixmaps directly and may need calibration */
-    /* drawing background */
-    gint c;
-    for (c = 0; c < priv->height / 29; c++) {
-         gdk_pixbuf_copy_area(aud_active_skin->pixmaps[SKIN_PLEDIT].pixbuf,
-                              36, 42, priv->width, 29, obj, 0, c*29);
-    }
-
-    /* drawing knob */
-    skin_draw_pixbuf(widget, aud_active_skin, obj, priv->skin_index, ps->pressed ? 61 : 52, 53, 0, y, priv->width, 18);
-
-    ui_skinned_widget_draw(widget, obj, priv->width, priv->height, FALSE);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static void ui_skinned_playlist_slider_set_position(GtkWidget *widget, gint y) {
-    gint pos;
-    Playlist *playlist = playlist_get_active();
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
-
-    y = CLAMP(y, 0, priv->height - 19);
-
-    pos = (y * (playlist_get_length(playlist) - playlistwin_list_get_visible_count())) / (priv->height - 19);
-    playlistwin_set_toprow(pos);
-
-    gtk_widget_queue_draw(widget);
-}
-
-static gboolean ui_skinned_playlist_slider_button_press(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER (widget);
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
-
-    if (event->button != 1 && event->button != 2)
-        return TRUE;
-
-    gint y = event->y;
-    if (event->type == GDK_BUTTON_PRESS) {
-        ps->pressed = TRUE;
-        if ((y >= priv->prev_y && y < priv->prev_y + 18)) {
-            priv->drag_y = y - priv->prev_y;
-        } else if (event->button == 2) {
-            ui_skinned_playlist_slider_set_position(widget, y);
-            priv->drag_y = 0;
-        } else {
-            gint n = playlistwin_list_get_visible_count() / 2;
-            if (y < priv->prev_y)
-                n *= -1;
-            playlistwin_scroll(n);
-        }
-        gtk_widget_queue_draw(widget);
-    }
-    return TRUE;
-}
-
-static gboolean ui_skinned_playlist_slider_button_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER(widget);
-
-    if (event->button == 1 || event->button == 2) {
-        ps->pressed = FALSE;
-        gtk_widget_queue_draw(widget);
-    }
-    return TRUE;
-}
-
-static gboolean ui_skinned_playlist_slider_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
-    UiSkinnedPlaylistSlider *ps = UI_SKINNED_PLAYLIST_SLIDER(widget);
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
-
-    if (ps->pressed) {
-        gint y = event->y - priv->drag_y;
-        ui_skinned_playlist_slider_set_position(widget, y);
-    }
-    return TRUE;
-}
-
-static void ui_skinned_playlist_slider_redraw(UiSkinnedPlaylistSlider *playlist_slider) {
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(playlist_slider);
-
-    if (priv->resize_height)
-        gtk_widget_set_size_request(GTK_WIDGET(playlist_slider), priv->width, priv->height+priv->resize_height);
-    if (priv->move_x)
-        gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(GTK_WIDGET(playlist_slider))), GTK_WIDGET(playlist_slider),
-                       playlist_slider->x+priv->move_x, playlist_slider->y);
-
-    gtk_widget_queue_draw(GTK_WIDGET(playlist_slider));
-}
-
-void ui_skinned_playlist_slider_move_relative(GtkWidget *widget, gint x) {
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
-    priv->move_x += x;
-}
-
-void ui_skinned_playlist_slider_resize_relative(GtkWidget *widget, gint h) {
-    UiSkinnedPlaylistSliderPrivate *priv = UI_SKINNED_PLAYLIST_SLIDER_GET_PRIVATE(widget);
-    priv->resize_height += h;
-}
--- a/src/audacious/ui_skinned_playlist_slider.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H
-#define AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H
-
-#include <gtk/gtk.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_PLAYLIST_SLIDER(obj)          GTK_CHECK_CAST (obj, ui_skinned_playlist_slider_get_type (), UiSkinnedPlaylistSlider)
-#define UI_SKINNED_PLAYLIST_SLIDER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_playlist_slider_get_type (), UiSkinnedPlaylistSliderClass)
-#define UI_SKINNED_IS_PLAYLIST_SLIDER(obj)       GTK_CHECK_TYPE (obj, ui_skinned_playlist_slider_get_type ())
-
-typedef struct _UiSkinnedPlaylistSlider        UiSkinnedPlaylistSlider;
-typedef struct _UiSkinnedPlaylistSliderClass   UiSkinnedPlaylistSliderClass;
-
-struct _UiSkinnedPlaylistSlider {
-    GtkWidget   widget;
-    gboolean    pressed;
-    gint        x, y;
-};
-
-struct _UiSkinnedPlaylistSliderClass {
-    GtkWidgetClass    parent_class;
-    void (* redraw)   (UiSkinnedPlaylistSlider *playlist_slider);
-};
-
-GtkWidget* ui_skinned_playlist_slider_new(GtkWidget *fixed, gint x, gint y, gint h);
-GtkType ui_skinned_playlist_slider_get_type(void);
-void ui_skinned_playlist_slider_move_relative(GtkWidget *widget, gint x);
-void ui_skinned_playlist_slider_resize_relative(GtkWidget *widget, gint h);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_PLAYLIST_SLIDER_H */
--- a/src/audacious/ui_skinned_playstatus.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skin.h"
-#include "ui_skinned_playstatus.h"
-#include "main.h"
-
-#define UI_TYPE_SKINNED_PLAYSTATUS           (ui_skinned_playstatus_get_type())
-
-enum {
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-static void ui_skinned_playstatus_class_init         (UiSkinnedPlaystatusClass *klass);
-static void ui_skinned_playstatus_init               (UiSkinnedPlaystatus *playstatus);
-static void ui_skinned_playstatus_destroy            (GtkObject *object);
-static void ui_skinned_playstatus_realize            (GtkWidget *widget);
-static void ui_skinned_playstatus_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_playstatus_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_playstatus_expose         (GtkWidget *widget, GdkEventExpose *event);
-static void ui_skinned_playstatus_toggle_scaled      (UiSkinnedPlaystatus *playstatus);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint playstatus_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_playstatus_get_type() {
-    static GType playstatus_type = 0;
-    if (!playstatus_type) {
-        static const GTypeInfo playstatus_info = {
-            sizeof (UiSkinnedPlaystatusClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_playstatus_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedPlaystatus),
-            0,
-            (GInstanceInitFunc) ui_skinned_playstatus_init,
-        };
-        playstatus_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedPlaystatus_", &playstatus_info, 0);
-    }
-
-    return playstatus_type;
-}
-
-static void ui_skinned_playstatus_class_init(UiSkinnedPlaystatusClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_playstatus_destroy;
-
-    widget_class->realize = ui_skinned_playstatus_realize;
-    widget_class->expose_event = ui_skinned_playstatus_expose;
-    widget_class->size_request = ui_skinned_playstatus_size_request;
-    widget_class->size_allocate = ui_skinned_playstatus_size_allocate;
-
-    klass->scaled = ui_skinned_playstatus_toggle_scaled;
-
-    playstatus_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedPlaystatusClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-}
-
-static void ui_skinned_playstatus_init(UiSkinnedPlaystatus *playstatus) {
-    playstatus->width = 11;
-    playstatus->height = 9;
-}
-
-GtkWidget* ui_skinned_playstatus_new(GtkWidget *fixed, gint x, gint y) {
-    UiSkinnedPlaystatus *playstatus = g_object_new (ui_skinned_playstatus_get_type (), NULL);
-
-    playstatus->x = x;
-    playstatus->y = y;
-
-    playstatus->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(playstatus), playstatus->x, playstatus->y);
-
-    return GTK_WIDGET(playstatus);
-}
-
-static void ui_skinned_playstatus_destroy(GtkObject *object) {
-    UiSkinnedPlaystatus *playstatus;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (object));
-
-    playstatus = UI_SKINNED_PLAYSTATUS (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_playstatus_realize(GtkWidget *widget) {
-    UiSkinnedPlaystatus *playstatus;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    playstatus = UI_SKINNED_PLAYSTATUS(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_playstatus_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS(widget);
-
-    requisition->width = playstatus->width*(playstatus->scaled ? cfg.scale_factor : 1);
-    requisition->height = playstatus->height*(playstatus->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_skinned_playstatus_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (playstatus->scaled ? cfg.scale_factor : 1);
-    widget->allocation.y *= (playstatus->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    playstatus->x = widget->allocation.x/(playstatus->scaled ? cfg.scale_factor : 1);
-    playstatus->y = widget->allocation.y/(playstatus->scaled ? cfg.scale_factor : 1);
-}
-
-static gboolean ui_skinned_playstatus_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
-    g_return_val_if_fail (playstatus->width > 0 && playstatus->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, playstatus->width, playstatus->height);
-
-    if (playstatus->status == STATUS_STOP && playstatus->buffering == TRUE)
-        playstatus->buffering = FALSE;
-    if (playstatus->status == STATUS_PLAY && playstatus->buffering == TRUE)
-        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 39, 0, 0, 0, 3, playstatus->height);
-    else if (playstatus->status == STATUS_PLAY)
-        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 36, 0, 0, 0, 3, playstatus->height);
-    else
-        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 27, 0, 0, 0, 2, playstatus->height);
-    switch (playstatus->status) {
-    case STATUS_STOP:
-        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 18, 0, 2, 0, 9, playstatus->height);
-        break;
-    case STATUS_PAUSE:
-        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 9, 0, 2, 0, 9, playstatus->height);
-        break;
-    case STATUS_PLAY:
-        skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_PLAYPAUSE, 1, 0, 3, 0, 8, playstatus->height);
-        break;
-    }
-
-    ui_skinned_widget_draw(widget, obj, playstatus->width, playstatus->height, playstatus->scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static void ui_skinned_playstatus_toggle_scaled(UiSkinnedPlaystatus *playstatus) {
-    GtkWidget *widget = GTK_WIDGET (playstatus);
-
-    playstatus->scaled = !playstatus->scaled;
-    gtk_widget_set_size_request(widget, playstatus->width*(playstatus->scaled ? cfg.scale_factor : 1), playstatus->height*(playstatus->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(GTK_WIDGET(playstatus));
-}
-
-void ui_skinned_playstatus_set_status(GtkWidget *widget, PStatus status) {
-    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget));
-    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
-
-    playstatus->status = status;
-    gtk_widget_queue_draw(widget);
-}
-
-void ui_skinned_playstatus_set_buffering(GtkWidget *widget, gboolean status) {
-    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget));
-    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
-
-    playstatus->buffering = status;
-    gtk_widget_queue_draw(widget);
-}
-
-void ui_skinned_playstatus_set_size(GtkWidget *widget, gint width, gint height) {
-    g_return_if_fail (UI_SKINNED_IS_PLAYSTATUS (widget));
-    UiSkinnedPlaystatus *playstatus = UI_SKINNED_PLAYSTATUS (widget);
-
-    playstatus->width = width;
-    playstatus->height = height;
-
-    gtk_widget_set_size_request(widget, width*(playstatus->scaled ? cfg.scale_factor : 1), height*(playstatus->scaled ? cfg.scale_factor : 1));
-}
--- a/src/audacious/ui_skinned_playstatus.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_PLAYSTATUS_H
-#define AUDACIOUS_UI_SKINNED_PLAYSTATUS_H
-
-#include <gtk/gtk.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_PLAYSTATUS(obj)          GTK_CHECK_CAST (obj, ui_skinned_playstatus_get_type (), UiSkinnedPlaystatus)
-#define UI_SKINNED_PLAYSTATUS_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_playstatus_get_type (), UiSkinnedPlaystatusClass)
-#define UI_SKINNED_IS_PLAYSTATUS(obj)       GTK_CHECK_TYPE (obj, ui_skinned_playstatus_get_type ())
-
-typedef struct _UiSkinnedPlaystatus        UiSkinnedPlaystatus;
-typedef struct _UiSkinnedPlaystatusClass   UiSkinnedPlaystatusClass;
-
-typedef enum {
-    STATUS_STOP, STATUS_PAUSE, STATUS_PLAY
-} PStatus;
-
-struct _UiSkinnedPlaystatus {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    gboolean         scaled;
-    PStatus          status;
-    gboolean         buffering;
-};
-
-struct _UiSkinnedPlaystatusClass {
-    GtkWidgetClass          parent_class;
-    void (* scaled)        (UiSkinnedPlaystatus *menurow);
-};
-
-GtkWidget* ui_skinned_playstatus_new (GtkWidget *fixed, gint x, gint y);
-GtkType ui_skinned_playstatus_get_type(void);
-void ui_skinned_playstatus_set_status(GtkWidget *widget, PStatus status);
-void ui_skinned_playstatus_set_buffering(GtkWidget *widget, gboolean status);
-void ui_skinned_playstatus_set_size(GtkWidget *widget, gint width, gint height);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_PLAYSTATUS_H */
--- a/src/audacious/ui_skinned_textbox.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,871 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skinned_textbox.h"
-
-#include <string.h>
-
-#include "main.h"
-#include "util.h"
-#include "strings.h"
-
-#define UI_SKINNED_TEXTBOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ui_skinned_textbox_get_type(), UiSkinnedTextboxPrivate))
-typedef struct _UiSkinnedTextboxPrivate UiSkinnedTextboxPrivate;
-
-#define TEXTBOX_SCROLL_SMOOTH_TIMEOUT  30
-#define TEXTBOX_SCROLL_WAIT            80
-
-enum {
-    CLICKED,
-    DOUBLE_CLICKED,
-    RIGHT_CLICKED,
-    DOUBLED,
-    REDRAW,
-    LAST_SIGNAL
-};
-
-struct _UiSkinnedTextboxPrivate {
-    SkinPixmapId     skin_index;
-    gboolean         scaled;
-    gboolean         scroll_back;
-    gint             nominal_y, nominal_height;
-    gint             scroll_timeout;
-    gint             font_ascent, font_descent;
-    PangoFontDescription *font;
-    gchar            *fontname;
-    gchar            *pixbuf_text;
-    gint             skin_id;
-    gint             drag_x, drag_off, offset;
-    gboolean         is_scrollable, is_dragging;
-    gint             pixbuf_width;
-    GdkPixbuf        *pixbuf;
-    gboolean         scroll_allowed, scroll_enabled;
-    gint             scroll_dummy;
-    gint             move_x, move_y;
-};
-
-static void ui_skinned_textbox_class_init         (UiSkinnedTextboxClass *klass);
-static void ui_skinned_textbox_init               (UiSkinnedTextbox *textbox);
-static void ui_skinned_textbox_destroy            (GtkObject *object);
-static void ui_skinned_textbox_realize            (GtkWidget *widget);
-static void ui_skinned_textbox_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_skinned_textbox_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_skinned_textbox_expose         (GtkWidget *widget, GdkEventExpose *event);
-static gboolean ui_skinned_textbox_button_press   (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_textbox_button_release (GtkWidget *widget, GdkEventButton *event);
-static gboolean ui_skinned_textbox_motion_notify  (GtkWidget *widget, GdkEventMotion *event);
-static void ui_skinned_textbox_toggle_scaled      (UiSkinnedTextbox *textbox);
-static void ui_skinned_textbox_redraw             (UiSkinnedTextbox *textbox);
-static gboolean ui_skinned_textbox_should_scroll  (UiSkinnedTextbox *textbox);
-static void textbox_generate_xfont_pixmap         (UiSkinnedTextbox *textbox, const gchar *pixmaptext);
-static gboolean textbox_scroll                    (gpointer data);
-static void textbox_generate_pixmap               (UiSkinnedTextbox *textbox);
-static void textbox_handle_special_char           (gchar *c, gint * x, gint * y);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint textbox_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_skinned_textbox_get_type() {
-    static GType textbox_type = 0;
-    if (!textbox_type) {
-        static const GTypeInfo textbox_info = {
-            sizeof (UiSkinnedTextboxClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_skinned_textbox_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSkinnedTextbox),
-            0,
-            (GInstanceInitFunc) ui_skinned_textbox_init,
-        };
-        textbox_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSkinnedTextbox_", &textbox_info, 0);
-    }
-
-    return textbox_type;
-}
-
-static void ui_skinned_textbox_class_init(UiSkinnedTextboxClass *klass) {
-    GObjectClass *gobject_class;
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    gobject_class = G_OBJECT_CLASS(klass);
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_skinned_textbox_destroy;
-
-    widget_class->realize = ui_skinned_textbox_realize;
-    widget_class->expose_event = ui_skinned_textbox_expose;
-    widget_class->size_request = ui_skinned_textbox_size_request;
-    widget_class->size_allocate = ui_skinned_textbox_size_allocate;
-    widget_class->button_press_event = ui_skinned_textbox_button_press;
-    widget_class->button_release_event = ui_skinned_textbox_button_release;
-    widget_class->motion_notify_event = ui_skinned_textbox_motion_notify;
-
-    klass->clicked = NULL;
-    klass->double_clicked = NULL;
-    klass->right_clicked = NULL;
-    klass->scaled = ui_skinned_textbox_toggle_scaled;
-    klass->redraw = ui_skinned_textbox_redraw;
-
-    textbox_signals[CLICKED] = 
-        g_signal_new ("clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, clicked), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    textbox_signals[DOUBLE_CLICKED] = 
-        g_signal_new ("double-clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, double_clicked), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    textbox_signals[RIGHT_CLICKED] = 
-        g_signal_new ("right-clicked", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, right_clicked), NULL, NULL,
-                      gtk_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
-
-    textbox_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    textbox_signals[REDRAW] = 
-        g_signal_new ("redraw", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSkinnedTextboxClass, redraw), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
-    g_type_class_add_private (gobject_class, sizeof (UiSkinnedTextboxPrivate));
-}
-
-static void ui_skinned_textbox_init(UiSkinnedTextbox *textbox) {
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-    priv->move_x = 0;
-    priv->move_y = 0;
-}
-
-GtkWidget* ui_skinned_textbox_new(GtkWidget *fixed, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si) {
-    UiSkinnedTextbox *textbox = g_object_new (ui_skinned_textbox_get_type (), NULL);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    textbox->height = aud_active_skin->properties.textbox_bitmap_font_height;
-    textbox->x = x;
-    textbox->y = y;
-    textbox->text = g_strdup("");
-    textbox->width = w;
-    priv->scroll_allowed = allow_scroll;
-    priv->scroll_enabled = TRUE;
-    priv->skin_index = si;
-    priv->nominal_y = y;
-    priv->nominal_height = textbox->height;
-    priv->scroll_timeout = 0;
-    priv->scroll_dummy = 0;
-
-    priv->scaled = FALSE;
-
-    gtk_fixed_put(GTK_FIXED(fixed), GTK_WIDGET(textbox), textbox->x, textbox->y);
-
-    return GTK_WIDGET(textbox);
-}
-
-static void ui_skinned_textbox_destroy(GtkObject *object) {
-    UiSkinnedTextbox *textbox;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_SKINNED_IS_TEXTBOX (object));
-
-    textbox = UI_SKINNED_TEXTBOX (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_skinned_textbox_realize(GtkWidget *widget) {
-    UiSkinnedTextbox *textbox;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_SKINNED_IS_TEXTBOX(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    textbox = UI_SKINNED_TEXTBOX(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
-                             GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
-                             GDK_POINTER_MOTION_HINT_MASK;
-    attributes.visual = gtk_widget_get_visual(widget);
-    attributes.colormap = gtk_widget_get_colormap(widget);
-
-    attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-    widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-
-    gdk_window_set_user_data(widget->window, widget);
-}
-
-static void ui_skinned_textbox_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    requisition->width = textbox->width*(priv->scaled ? cfg.scale_factor : 1);
-    requisition->height = textbox->height*(priv->scaled ?  cfg.scale_factor : 1 );
-}
-
-static void ui_skinned_textbox_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (priv->scaled ? cfg.scale_factor : 1);
-    widget->allocation.y *= (priv->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-        gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-
-    if (textbox->x + priv->move_x - widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1) <3);
-        priv->move_x = 0;
-    if (textbox->y + priv->move_y - widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1) <3);
-        priv->move_y = 0;
-    textbox->x = widget->allocation.x/(priv->scaled ? cfg.scale_factor : 1);
-    textbox->y = widget->allocation.y/(priv->scaled ? cfg.scale_factor : 1);
-
-    if (textbox->width - (guint) (widget->allocation.width / (priv->scaled ? cfg.scale_factor : 1)) > 2) {
-            textbox->width = (guint) (widget->allocation.width / (priv->scaled ? cfg.scale_factor : 1));
-            if (priv->pixbuf_text) g_free(priv->pixbuf_text);
-            priv->pixbuf_text = NULL;
-            priv->offset = 0;
-            gtk_widget_set_size_request(widget, textbox->width, textbox->height);
-            gtk_widget_queue_draw(GTK_WIDGET(textbox));
-    }
-}
-
-static gboolean ui_skinned_textbox_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-    g_return_val_if_fail (textbox->width > 0 && textbox->height > 0, FALSE);
-
-    GdkPixbuf *obj = NULL;
-    gint cw;
-
-    if (textbox->text && (!priv->pixbuf_text || strcmp(textbox->text, priv->pixbuf_text)))
-        textbox_generate_pixmap(textbox);
-
-    if (priv->pixbuf) {
-        if (skin_get_id() != priv->skin_id) {
-            priv->skin_id = skin_get_id();
-            textbox_generate_pixmap(textbox);
-        }
-        obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, textbox->width, textbox->height);
-
-        if (cfg.twoway_scroll) { // twoway scroll
-            cw = priv->pixbuf_width - priv->offset;
-            if (cw > textbox->width)
-                cw = textbox->width;
-            gdk_pixbuf_copy_area(priv->pixbuf, priv->offset, 0, cw, textbox->height, obj, 0, 0);
-            if (cw < textbox->width)
-                gdk_pixbuf_copy_area(priv->pixbuf, 0, 0, textbox->width - cw, textbox->height,
-                                     obj, textbox->width - cw, textbox->height);
-        } else { // oneway scroll
-            int cw1, cw2;
-
-            if (priv->offset >= priv->pixbuf_width)
-                priv->offset = 0;
-
-            if (priv->pixbuf_width - priv->offset > textbox->width) { // case1
-                cw1 = textbox->width;
-                gdk_pixbuf_copy_area(priv->pixbuf, priv->offset, 0, cw1, textbox->height,
-                                     obj, 0, 0);
-            } else { // case 2
-                cw1 = priv->pixbuf_width - priv->offset;
-                gdk_pixbuf_copy_area(priv->pixbuf, priv->offset, 0, cw1, textbox->height, obj, 0, 0);
-                cw2 = textbox->width - cw1;
-                gdk_pixbuf_copy_area(priv->pixbuf, 0, 0, cw2, textbox->height, obj, cw1, 0);
-            }
-        }
-
-        ui_skinned_widget_draw(widget, obj, textbox->width, textbox->height, priv->scaled);
-
-        g_object_unref(obj);
-    }
-
-    return FALSE;
-}
-
-static gboolean ui_skinned_textbox_button_press(GtkWidget *widget, GdkEventButton *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    if (event->type == GDK_BUTTON_PRESS) {
-        textbox = UI_SKINNED_TEXTBOX(widget);
-        if (event->button == 3 && !g_signal_has_handler_pending(widget, textbox_signals[RIGHT_CLICKED], 0, TRUE))
-            return FALSE;
-        else if (event->button == 1) {
-            if (priv->scroll_allowed) {
-                if ((priv->pixbuf_width > textbox->width) && priv->is_scrollable) {
-                    priv->is_dragging = TRUE;
-                    priv->drag_off = priv->offset;
-                    priv->drag_x = event->x;
-                }
-            } else
-                g_signal_emit(widget, textbox_signals[CLICKED], 0);
-
-        } else if (event->button == 3) {
-            g_signal_emit(widget, textbox_signals[RIGHT_CLICKED], 0, event);
-        } else
-            priv->is_dragging = FALSE;
-    } else if (event->type == GDK_2BUTTON_PRESS) {
-        if (event->button == 1) {
-           if (g_signal_has_handler_pending(widget, textbox_signals[DOUBLE_CLICKED], 0, TRUE))
-               g_signal_emit(widget, textbox_signals[DOUBLE_CLICKED], 0);
-           else
-               return FALSE;
-        }
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_textbox_button_release(GtkWidget *widget, GdkEventButton *event) {
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(widget);
-
-    if (event->button == 1) {
-        priv->is_dragging = FALSE;
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_textbox_motion_notify(GtkWidget *widget, GdkEventMotion *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_SKINNED_IS_TEXTBOX (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(widget);
-
-    if (priv->is_dragging) {
-        if (priv->scroll_allowed &&
-            priv->pixbuf_width > textbox->width) {
-            priv->offset = priv->drag_off - (event->x - priv->drag_x);
-
-            while (priv->offset < 0)
-                priv->offset = 0;
-
-            while (priv->offset > (priv->pixbuf_width - textbox->width))
-                priv->offset = (priv->pixbuf_width - textbox->width);
-
-            gtk_widget_queue_draw(widget);
-        }
-    }
-
-  return TRUE;
-}
-
-static void ui_skinned_textbox_toggle_scaled(UiSkinnedTextbox *textbox) {
-    GtkWidget *widget = GTK_WIDGET (textbox);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    priv->scaled = !priv->scaled;
-
-    gtk_widget_set_size_request(widget, textbox->width*(priv->scaled ? cfg.scale_factor : 1 ), 
-    textbox->height*(priv->scaled ? cfg.scale_factor : 1 ));
-
-    gtk_widget_queue_draw(GTK_WIDGET(textbox));
-}
-
-static void ui_skinned_textbox_redraw(UiSkinnedTextbox *textbox) {
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    if (priv->move_x || priv->move_y)
-        gtk_fixed_move(GTK_FIXED(gtk_widget_get_parent(GTK_WIDGET(textbox))), GTK_WIDGET(textbox),
-                       textbox->x+priv->move_x, textbox->y+priv->move_y);
-
-    gtk_widget_queue_draw(GTK_WIDGET(textbox));
-}
-
-static gboolean ui_skinned_textbox_should_scroll(UiSkinnedTextbox *textbox) {
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    if (!priv->scroll_allowed)
-        return FALSE;
-
-    if (priv->font) {
-        gint width;
-        text_get_extents(priv->fontname, textbox->text, &width, NULL, NULL, NULL);
-
-        if (width <= textbox->width)
-            return FALSE;
-        else
-            return TRUE;
-    }
-
-    if (g_utf8_strlen(textbox->text, -1) * aud_active_skin->properties.textbox_bitmap_font_width > textbox->width)
-        return TRUE;
-
-    return FALSE;
-}
-
-void ui_skinned_textbox_set_xfont(GtkWidget *widget, gboolean use_xfont, const gchar * fontname) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    gint ascent, descent;
-
-    g_return_if_fail(textbox != NULL);
-
-    if (priv->font) {
-        pango_font_description_free(priv->font);
-        priv->font = NULL;
-    }
-
-    textbox->y = priv->nominal_y;
-    textbox->height = priv->nominal_height;
-
-    /* Make sure the pixmap is regenerated */
-    if (priv->pixbuf_text) {
-        g_free(priv->pixbuf_text);
-        priv->pixbuf_text = NULL;
-    }
-
-    if (!use_xfont || strlen(fontname) == 0)
-        return;
-
-    priv->font = pango_font_description_from_string(fontname);
-    priv->fontname = g_strdup(fontname);
-
-    text_get_extents(fontname,
-                     "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz ",
-                     NULL, NULL, &ascent, &descent);
-    priv->font_ascent = ascent;
-    priv->font_descent = descent;
-
-
-    if (priv->font == NULL)
-        return;
-
-    textbox->height = priv->font_ascent;
-    if (textbox->height > priv->nominal_height)
-        textbox->y -= (textbox->height - priv->nominal_height) / 2;
-    else
-        textbox->height = priv->nominal_height;
-}
-
-void ui_skinned_textbox_set_text(GtkWidget *widget, const gchar *text) {
-    g_return_if_fail(text != NULL);
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX (widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    if (!strcmp(textbox->text, text))
-         return;
-    if (textbox->text)
-        g_free(textbox->text);
-
-    textbox->text = str_assert_utf8(text);
-    priv->scroll_back = FALSE;
-    gtk_widget_queue_draw(GTK_WIDGET(textbox));
-}
-
-static void textbox_generate_xfont_pixmap(UiSkinnedTextbox *textbox, const gchar *pixmaptext) {
-    /* FIXME: should operate directly on priv->pixbuf, it shouldn't use pixmap */
-    gint length, i;
-    GdkGC *gc, *maskgc;
-    GdkColor *c, pattern;
-    GdkBitmap *mask;
-    PangoLayout *layout;
-    gint width;
-    GdkPixmap *pixmap;
-
-    g_return_if_fail(textbox != NULL);
-    g_return_if_fail(pixmaptext != NULL);
-    g_return_if_fail(textbox->height > 0);
-
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    length = g_utf8_strlen(pixmaptext, -1);
-
-    text_get_extents(priv->fontname, pixmaptext, &width, NULL, NULL, NULL);
-
-    priv->pixbuf_width = MAX(width, textbox->width);
-    pixmap = gdk_pixmap_new(mainwin->window, priv->pixbuf_width,
-                                   textbox->height,
-                                   gdk_rgb_get_visual()->depth);
-    gc = gdk_gc_new(pixmap);
-    c = skin_get_color(aud_active_skin, SKIN_TEXTBG);
-    for (i = 0; i < textbox->height; i++) {
-        gdk_gc_set_foreground(gc, &c[6 * i / textbox->height]);
-        gdk_draw_line(pixmap, gc, 0, i, priv->pixbuf_width, i);
-    }
-
-    mask = gdk_pixmap_new(mainwin->window, priv->pixbuf_width, textbox->height, 1);
-    maskgc = gdk_gc_new(mask);
-    pattern.pixel = 0;
-    gdk_gc_set_foreground(maskgc, &pattern);
-
-    gdk_draw_rectangle(mask, maskgc, TRUE, 0, 0, priv->pixbuf_width, textbox->height);
-    pattern.pixel = 1;
-    gdk_gc_set_foreground(maskgc, &pattern);
-
-    gdk_gc_set_foreground(gc, skin_get_color(aud_active_skin, SKIN_TEXTFG));
-
-    layout = gtk_widget_create_pango_layout(mainwin, pixmaptext);
-    pango_layout_set_font_description(layout, priv->font);
-
-    gdk_draw_layout(pixmap, gc, 0, (priv->font_descent / 2), layout);
-    g_object_unref(layout);
-
-    g_object_unref(maskgc);
-
-    gdk_gc_set_clip_mask(gc, mask);
-    c = skin_get_color(aud_active_skin, SKIN_TEXTFG);
-    for (i = 0; i < textbox->height; i++) {
-        gdk_gc_set_foreground(gc, &c[6 * i / textbox->height]);
-        gdk_draw_line(pixmap, gc, 0, i, priv->pixbuf_width, i);
-    }
-    priv->pixbuf = gdk_pixbuf_get_from_drawable(NULL, pixmap, gdk_colormap_get_system(), 0, 0, 0, 0, priv->pixbuf_width, textbox->height);
-    g_object_unref(mask);
-    g_object_unref(gc);
-}
-
-static gboolean textbox_scroll(gpointer data) {
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(data);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    if (!priv->is_dragging) {
-        if (priv->scroll_dummy < TEXTBOX_SCROLL_WAIT)
-            priv->scroll_dummy++;
-        else {
-            if(cfg.twoway_scroll) {
-                if (priv->scroll_back)
-                    priv->offset -= 1;
-                else
-                    priv->offset += 1;
-
-                if (priv->offset >= (priv->pixbuf_width - textbox->width)) {
-                    priv->scroll_back = TRUE;
-                    priv->scroll_dummy = 0;
-                    priv->offset = priv->pixbuf_width - textbox->width;
-                }
-                if (priv->offset <= 0) {
-                    priv->scroll_back = FALSE;
-                    priv->scroll_dummy = 0;
-                    priv->offset = 0;
-                }
-            }
-            else { // oneway scroll
-                priv->scroll_back = FALSE;
-                priv->offset += 1;
-            }
-            gtk_widget_queue_draw(GTK_WIDGET(textbox));
-        }
-    }
-    return TRUE;
-}
-
-static void textbox_generate_pixmap(UiSkinnedTextbox *textbox) {
-    gint length, i, x, y, wl;
-    gchar *pixmaptext;
-    gchar *tmp, *stxt;
-
-    g_return_if_fail(textbox != NULL);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    if (priv->pixbuf) {
-        g_object_unref(priv->pixbuf);
-        priv->pixbuf = NULL;
-    }
-
-    /*
-     * Don't reset the offset if only text after the last '(' has
-     * changed.  This is a hack to avoid visual noice on vbr files
-     * where we guess the length.
-     */
-    if (!(priv->pixbuf_text && strrchr(textbox->text, '(') &&
-          !strncmp(priv->pixbuf_text, textbox->text,
-                   strrchr(textbox->text, '(') - textbox->text)))
-        priv->offset = 0;
-
-    g_free(priv->pixbuf_text);
-    priv->pixbuf_text = g_strdup(textbox->text);
-
-    /*
-     * wl is the number of (partial) letters visible. Only makes
-     * sense when using skinned font.
-     */
-    wl = textbox->width / 5;
-    if (wl * 5 != textbox->width)
-        wl++;
-
-    length = g_utf8_strlen(textbox->text, -1);
-
-    priv->is_scrollable = FALSE;
-
-    priv->is_scrollable = ui_skinned_textbox_should_scroll(textbox);
-
-    if (priv->is_scrollable) {
-        if(!cfg.twoway_scroll) {
-            pixmaptext = g_strdup_printf("%s *** ", priv->pixbuf_text);
-            length += 5;
-        } else
-            pixmaptext = g_strdup(priv->pixbuf_text);
-    } else
-    if (!priv->font && length <= wl) {
-        gint pad = wl - length;
-        gchar *padchars = g_strnfill(pad, ' ');
-
-        pixmaptext = g_strconcat(priv->pixbuf_text, padchars, NULL);
-        g_free(padchars);
-        length += pad;
-    } else
-        pixmaptext = g_strdup(priv->pixbuf_text);
-
-    if (priv->is_scrollable) {
-        if (priv->scroll_enabled && !priv->scroll_timeout) {
-            gint tag;
-            tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT;
-            priv->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
-        }
-    } else {
-        if (priv->scroll_timeout) {
-            g_source_remove(priv->scroll_timeout);
-            priv->scroll_timeout = 0;
-        }
-        priv->offset = 0;
-    }
-
-    if (priv->font) {
-        textbox_generate_xfont_pixmap(textbox, pixmaptext);
-        g_free(pixmaptext);
-        return;
-    }
-
-    priv->pixbuf_width = length * aud_active_skin->properties.textbox_bitmap_font_width;
-    priv->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
-                                  priv->pixbuf_width, aud_active_skin->properties.textbox_bitmap_font_height);
-
-    for (tmp = stxt = g_utf8_strup(pixmaptext, -1), i = 0;
-         tmp != NULL && i < length; i++, tmp = g_utf8_next_char(tmp)) {
-        gchar c = *tmp;
-        x = y = -1;
-        if (c >= 'A' && c <= 'Z') {
-            x = aud_active_skin->properties.textbox_bitmap_font_width * (c - 'A');
-            y = 0;
-        }
-        else if (c >= '0' && c <= '9') {
-            x = aud_active_skin->properties.textbox_bitmap_font_width * (c - '0');
-            y = aud_active_skin->properties.textbox_bitmap_font_height;
-        }
-        else
-            textbox_handle_special_char(tmp, &x, &y);
-
-        skin_draw_pixbuf(GTK_WIDGET(textbox), aud_active_skin,
-                         priv->pixbuf, priv->skin_index,
-                         x, y, i * aud_active_skin->properties.textbox_bitmap_font_width, 0,
-                         aud_active_skin->properties.textbox_bitmap_font_width, 
-                         aud_active_skin->properties.textbox_bitmap_font_height);
-    }
-    g_free(stxt);
-    g_free(pixmaptext);
-}
-
-void ui_skinned_textbox_set_scroll(GtkWidget *widget, gboolean scroll) {
-    g_return_if_fail(widget != NULL);
-    UiSkinnedTextbox *textbox = UI_SKINNED_TEXTBOX(widget);
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(textbox);
-
-    priv->scroll_enabled = scroll;
-    if (priv->scroll_enabled && priv->is_scrollable && priv->scroll_allowed) {
-        gint tag;
-        tag = TEXTBOX_SCROLL_SMOOTH_TIMEOUT;
-        if (priv->scroll_timeout) {
-            g_source_remove(priv->scroll_timeout);
-            priv->scroll_timeout = 0;
-        }
-        priv->scroll_timeout = g_timeout_add(tag, textbox_scroll, textbox);
-
-    } else {
-
-        if (priv->scroll_timeout) {
-            g_source_remove(priv->scroll_timeout);
-            priv->scroll_timeout = 0;
-        }
-
-        priv->offset = 0;
-        gtk_widget_queue_draw(GTK_WIDGET(textbox));
-    }
-}
-
-static void textbox_handle_special_char(gchar *c, gint * x, gint * y) {
-    gint tx, ty;
-
-    switch (*c) {
-    case '"':
-        tx = 26;
-        ty = 0;
-        break;
-    case '\r':
-        tx = 10;
-        ty = 1;
-        break;
-    case ':':
-    case ';':
-        tx = 12;
-        ty = 1;
-        break;
-    case '(':
-        tx = 13;
-        ty = 1;
-        break;
-    case ')':
-        tx = 14;
-        ty = 1;
-        break;
-    case '-':
-        tx = 15;
-        ty = 1;
-        break;
-    case '`':
-    case '\'':
-        tx = 16;
-        ty = 1;
-        break;
-    case '!':
-        tx = 17;
-        ty = 1;
-        break;
-    case '_':
-        tx = 18;
-        ty = 1;
-        break;
-    case '+':
-        tx = 19;
-        ty = 1;
-        break;
-    case '\\':
-        tx = 20;
-        ty = 1;
-        break;
-    case '/':
-        tx = 21;
-        ty = 1;
-        break;
-    case '[':
-        tx = 22;
-        ty = 1;
-        break;
-    case ']':
-        tx = 23;
-        ty = 1;
-        break;
-    case '^':
-        tx = 24;
-        ty = 1;
-        break;
-    case '&':
-        tx = 25;
-        ty = 1;
-        break;
-    case '%':
-        tx = 26;
-        ty = 1;
-        break;
-    case '.':
-    case ',':
-        tx = 27;
-        ty = 1;
-        break;
-    case '=':
-        tx = 28;
-        ty = 1;
-        break;
-    case '$':
-        tx = 29;
-        ty = 1;
-        break;
-    case '#':
-        tx = 30;
-        ty = 1;
-        break;
-    case '?':
-        tx = 3;
-        ty = 2;
-        break;
-    case '*':
-        tx = 4;
-        ty = 2;
-        break;
-    default:
-        tx = 29;
-        ty = 0;
-        break;
-    }
-
-    const gchar *change[] = {"Ą", "A", "Ę", "E", "Ć", "C", "Ł", "L", "Ó", "O", "Ś", "S", "Ż", "Z", "Ź", "Z",
-                             "Ń", "N", "Ü", "U", NULL};
-    int i;
-    for (i = 0; change[i]; i+=2) {
-         if (!strncmp(c, change[i], strlen(change[i]))) {
-             tx = (*change[i+1] - 'A');
-             break;
-         }
-    }
-
-    /* those are commonly included into skins */
-    if (!strncmp(c, "Å", strlen("Å"))) {
-        tx = 0;
-        ty = 2;
-    } else if (!strncmp(c, "Ö", strlen("Ö"))) {
-        tx = 1;
-        ty = 2;
-    } else if (!strncmp(c, "Ä", strlen("Ä"))) {
-        tx = 2;
-        ty = 2;
-    }
-
-    *x = tx * aud_active_skin->properties.textbox_bitmap_font_width;
-    *y = ty * aud_active_skin->properties.textbox_bitmap_font_height;
-}
-
-void ui_skinned_textbox_move_relative(GtkWidget *widget, gint x, gint y) {
-    UiSkinnedTextboxPrivate *priv = UI_SKINNED_TEXTBOX_GET_PRIVATE(widget);
-    priv->move_x += x;
-    priv->move_y += y;
-}
--- a/src/audacious/ui_skinned_textbox.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007 Tomasz Moń
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_TEXTBOX_H
-#define AUDACIOUS_UI_SKINNED_TEXTBOX_H
-
-#include <gtk/gtk.h>
-#include "ui_skin.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SKINNED_TEXTBOX(obj)          GTK_CHECK_CAST (obj, ui_skinned_textbox_get_type (), UiSkinnedTextbox)
-#define UI_SKINNED_TEXTBOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_textbox_get_type (), UiSkinnedTextboxClass)
-#define UI_SKINNED_IS_TEXTBOX(obj)       GTK_CHECK_TYPE (obj, ui_skinned_textbox_get_type ())
-
-typedef struct _UiSkinnedTextbox        UiSkinnedTextbox;
-typedef struct _UiSkinnedTextboxClass   UiSkinnedTextboxClass;
-
-struct _UiSkinnedTextbox {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    gchar            *text;
-};
-
-struct _UiSkinnedTextboxClass {
-    GtkWidgetClass          parent_class;
-    void (* clicked)        (UiSkinnedTextbox *textbox);
-    void (* double_clicked) (UiSkinnedTextbox *textbox);
-    void (* right_clicked)  (UiSkinnedTextbox *textbox);
-    void (* scaled)         (UiSkinnedTextbox *textbox);
-    void (* redraw)         (UiSkinnedTextbox *textbox);
-};
-
-GtkWidget* ui_skinned_textbox_new (GtkWidget *fixed, gint x, gint y, gint w, gboolean allow_scroll, SkinPixmapId si);
-GtkType ui_skinned_textbox_get_type(void);
-void ui_skinned_textbox_set_xfont(GtkWidget *widget, gboolean use_xfont, const gchar * fontname);
-void ui_skinned_textbox_set_text(GtkWidget *widget, const gchar *text);
-void ui_skinned_textbox_set_scroll(GtkWidget *widget, gboolean scroll);
-void ui_skinned_textbox_move_relative(GtkWidget *widget, gint x, gint y);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SKINNED_TEXTBOX_H */
--- a/src/audacious/ui_skinned_window.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,286 +0,0 @@
-/*
- * Audacious: A cross-platform multimedia player
- * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "platform/smartinclude.h"
-#include "ui_skin.h"
-
-#include <gtk/gtkmain.h>
-#include <glib-object.h>
-#include <glib/gmacros.h>
-#include <gtk/gtkmarshal.h>
-#include <gtk/gtkwindow.h>
-#include <string.h>
-
-#include "main.h"
-#include "ui_dock.h"
-#include "ui_skinned_window.h"
-#include "ui_playlist.h"
-
-static void ui_skinned_window_class_init(SkinnedWindowClass *klass);
-static void ui_skinned_window_init(GtkWidget *widget);
-static GtkWindowClass *parent = NULL;
-
-GType
-ui_skinned_window_get_type(void)
-{
-  static GType window_type = 0;
-
-  if (!window_type)
-    {
-      static const GTypeInfo window_info =
-      {
-        sizeof (SkinnedWindowClass),
-        NULL,           /* base_init */
-        NULL,           /* base_finalize */
-        (GClassInitFunc) ui_skinned_window_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (SkinnedWindow),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) ui_skinned_window_init
-      };
-
-      window_type =
-        g_type_register_static (GTK_TYPE_WINDOW, "SkinnedWindow_",
-                                &window_info, 0);
-    }
-
-  return window_type;
-}
-
-static void
-ui_skinned_window_map(GtkWidget *widget)
-{
-    (* GTK_WIDGET_CLASS (parent)->map) (widget);
-
-    SkinnedWindow *window = SKINNED_WINDOW(widget);
-    if (window->type == WINDOW_MAIN)
-        gtk_widget_shape_combine_mask(widget, skin_get_mask(aud_active_skin, SKIN_MASK_MAIN + cfg.player_shaded), 0, 0);
-    else if (window->type == WINDOW_EQ)
-        gtk_widget_shape_combine_mask(widget, skin_get_mask(aud_active_skin, SKIN_MASK_EQ + cfg.equalizer_shaded), 0, 0);
-
-    gtk_window_set_keep_above(GTK_WINDOW(widget), cfg.always_on_top);
-}
-
-static gboolean
-ui_skinned_window_motion_notify_event(GtkWidget *widget,
-                                      GdkEventMotion *event)
-{
-    if (dock_is_moving(GTK_WINDOW(widget)))
-        dock_move_motion(GTK_WINDOW(widget), event);
-
-    return FALSE;
-}
-
-static gboolean ui_skinned_window_focus_in(GtkWidget *widget, GdkEventFocus *focus) {
-    gboolean val = GTK_WIDGET_CLASS (parent)->focus_in_event (widget, focus);
-    gtk_widget_queue_draw(widget);
-    return val;
-}
-
-static gboolean ui_skinned_window_focus_out(GtkWidget *widget, GdkEventFocus *focus) {
-    gboolean val = GTK_WIDGET_CLASS (parent)->focus_out_event (widget, focus);
-    gtk_widget_queue_draw(widget);
-    return val;
-}
-
-static gboolean ui_skinned_window_button_press(GtkWidget *widget, GdkEventButton *event) {
-    if (event->button == 1 && event->type == GDK_BUTTON_PRESS &&
-        (cfg.easy_move || cfg.equalizer_shaded || (event->y / cfg.scale_factor) < 14)) {
-         dock_move_press(get_dock_window_list(), GTK_WINDOW(widget),
-                         event, SKINNED_WINDOW(widget)->type == WINDOW_MAIN ? TRUE : FALSE);
-    }
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_window_button_release(GtkWidget *widget, GdkEventButton *event) {
-    if (dock_is_moving(GTK_WINDOW(widget)))
-       dock_move_release(GTK_WINDOW(widget));
-
-    return TRUE;
-}
-
-static gboolean ui_skinned_window_expose(GtkWidget *widget, GdkEventExpose *event) {
-    SkinnedWindow *window = SKINNED_WINDOW(widget);
-
-    GdkPixbuf *obj = NULL;
-
-    gint width = 0, height = 0;
-    switch (window->type) {
-        case WINDOW_MAIN:
-            width = aud_active_skin->properties.mainwin_width;
-            height = aud_active_skin->properties.mainwin_height;
-            break;
-        case WINDOW_EQ:
-            width = 275 * (cfg.scaled ? cfg.scale_factor : 1);
-            height = 116 * (cfg.scaled ? cfg.scale_factor : 1) ;
-            break;
-        case WINDOW_PLAYLIST:
-            width = playlistwin_get_width();
-            height = cfg.playlist_height;
-            break;
-        default:
-            return FALSE;
-    }
-    obj = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
-
-    gboolean focus = gtk_window_has_toplevel_focus(GTK_WINDOW(widget));
-
-    switch (window->type) {
-        case WINDOW_MAIN:
-            skin_draw_pixbuf(widget, aud_active_skin, obj,SKIN_MAIN, 0, 0, 0, 0, width, height);
-            skin_draw_mainwin_titlebar(aud_active_skin, obj, cfg.player_shaded, focus || !cfg.dim_titlebar);
-            break;
-        case WINDOW_EQ:
-            skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQMAIN, 0, 0, 0, 0, width, height);
-            if (focus || !cfg.dim_titlebar) {
-                if (!cfg.equalizer_shaded)
-                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQMAIN, 0, 134, 0, 0, width, 14);
-                else
-                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQ_EX, 0, 0, 0, 0, width, 14);
-            } else {
-                if (!cfg.equalizer_shaded)
-                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQMAIN, 0, 149, 0, 0, width, 14);
-                else
-                    skin_draw_pixbuf(widget, aud_active_skin, obj, SKIN_EQ_EX, 0, 15, 0, 0, width, 14);
-            }
-            break;
-        case WINDOW_PLAYLIST:
-            focus |= !cfg.dim_titlebar;
-            if (cfg.playlist_shaded) {
-                skin_draw_playlistwin_shaded(aud_active_skin, obj, width, focus);
-            } else {
-                skin_draw_playlistwin_frame(aud_active_skin, obj, width, cfg.playlist_height, focus);
-            }
-            break;
-    }
-
-    ui_skinned_widget_draw(GTK_WIDGET(window), obj, width, height,
-                           window->type != WINDOW_PLAYLIST && cfg.scaled);
-
-    g_object_unref(obj);
-
-    return FALSE;
-}
-
-static void
-ui_skinned_window_class_init(SkinnedWindowClass *klass)
-{
-    GtkWidgetClass *widget_class;
-
-    widget_class = (GtkWidgetClass*) klass;
-
-    parent = gtk_type_class(gtk_window_get_type());
-
-    widget_class->motion_notify_event = ui_skinned_window_motion_notify_event;
-    widget_class->expose_event = ui_skinned_window_expose;
-    widget_class->focus_in_event = ui_skinned_window_focus_in;
-    widget_class->focus_out_event = ui_skinned_window_focus_out;
-    widget_class->button_press_event = ui_skinned_window_button_press;
-    widget_class->button_release_event = ui_skinned_window_button_release;
-    widget_class->map = ui_skinned_window_map;
-}
-
-void
-ui_skinned_window_hide(SkinnedWindow *window)
-{
-    g_return_if_fail(SKINNED_CHECK_WINDOW(window));
-
-    gtk_window_get_position(GTK_WINDOW(window), &window->x, &window->y);
-    gtk_widget_hide(GTK_WIDGET(window));
-}
-
-void
-ui_skinned_window_show(SkinnedWindow *window)
-{
-    g_return_if_fail(SKINNED_CHECK_WINDOW(window));
-
-    gtk_window_move(GTK_WINDOW(window), window->x, window->y);
-    gtk_widget_show_all(GTK_WIDGET(window));
-}
-
-static void
-ui_skinned_window_init(GtkWidget *widget)
-{
-    SkinnedWindow *window;
-    window = SKINNED_WINDOW(widget);
-    window->x = -1;
-    window->y = -1;
-}
-
-GtkWidget *
-ui_skinned_window_new(const gchar *wmclass_name)
-{
-    GtkWidget *widget = g_object_new(ui_skinned_window_get_type(), NULL);
-    GtkWindow *window = GTK_WINDOW(widget);
-
-    window->type = SKINNED_WINDOW_TYPE;
-
-    if (wmclass_name)
-        gtk_window_set_wmclass(GTK_WINDOW(widget), wmclass_name, "Audacious");
-
-    gtk_widget_add_events(GTK_WIDGET(widget),
-                          GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK |
-                          GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
-                          GDK_SCROLL_MASK | GDK_KEY_PRESS_MASK |
-                          GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK);
-    gtk_widget_realize(GTK_WIDGET(widget));
-
-    set_dock_window_list(dock_window_set_decorated(get_dock_window_list(),
-                                                   GTK_WINDOW(widget),
-                                                   cfg.show_wm_decorations));
-    gtk_widget_set_app_paintable(GTK_WIDGET(widget), TRUE);
-    gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
-    gtk_widget_shape_combine_mask(widget, NULL, 0, 0);
-
-    if (!strcmp(wmclass_name, "player"))
-        SKINNED_WINDOW(widget)->type = WINDOW_MAIN;
-    if (!strcmp(wmclass_name, "equalizer"))
-        SKINNED_WINDOW(widget)->type = WINDOW_EQ;
-    if (!strcmp(wmclass_name, "playlist"))
-        SKINNED_WINDOW(widget)->type = WINDOW_PLAYLIST;
-
-    /* GtkFixed hasn't got its GdkWindow, this means that it can be used to
-       display widgets while the logo below will be displayed anyway;
-       however fixed positions are not that great, cause the button sizes may (will)
-       vary depending on the gtk style used, so it's not possible to center
-       them unless a fixed width and heigth is forced (and this may bring to cutted
-       text if someone, i.e., uses a big font for gtk widgets);
-       other types of container most likely have their GdkWindow, this simply
-       means that the logo must be drawn on the container widget, instead of the
-       window; otherwise, it won't be displayed correctly */
-    SKINNED_WINDOW(widget)->fixed = gtk_fixed_new();
-    gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(SKINNED_WINDOW(widget)->fixed));
-    return widget;
-}
-
-void ui_skinned_window_draw_all(GtkWidget *widget) {
-    if (SKINNED_WINDOW(widget)->type == WINDOW_MAIN)
-        mainwin_refresh_hints();
-
-    gtk_widget_queue_draw(widget);
-    GList *iter;
-    for (iter = GTK_FIXED (SKINNED_WINDOW(widget)->fixed)->children; iter; iter = g_list_next (iter)) {
-         GtkFixedChild *child_data = (GtkFixedChild *) iter->data;
-         GtkWidget *child = child_data->widget;
-         gtk_widget_queue_draw(child);
-    }
-}
--- a/src/audacious/ui_skinned_window.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Audacious: A cross-platform multimedia player
- * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINNED_WINDOW_H
-#define AUDACIOUS_UI_SKINNED_WINDOW_H
-
-#define SKINNED_WINDOW(obj)          GTK_CHECK_CAST (obj, ui_skinned_window_get_type (), SkinnedWindow)
-#define SKINNED_WINDOW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_skinned_window_get_type (), SkinnedWindowClass)
-#define SKINNED_CHECK_WINDOW(obj)    GTK_CHECK_TYPE (obj, ui_skinned_window_get_type ())
-#define SKINNED_TYPE_WINDOW          (ui_skinned_window_get_type())
-
-#ifdef GDK_WINDOWING_QUARTZ
-# define SKINNED_WINDOW_TYPE		GTK_WINDOW_POPUP
-#else
-# define SKINNED_WINDOW_TYPE		GTK_WINDOW_TOPLEVEL
-#endif
-
-enum {
-    WINDOW_MAIN,
-    WINDOW_EQ,
-    WINDOW_PLAYLIST
-};
-
-typedef struct _SkinnedWindow SkinnedWindow;
-typedef struct _SkinnedWindowClass SkinnedWindowClass;
-
-struct _SkinnedWindow
-{
-  GtkWindow window;
-
-  GtkWidget *canvas;
-  gint x,y;
-
-  gint type;
-  GtkWidget *fixed;
-};
-
-struct _SkinnedWindowClass
-{
-  GtkWindowClass        parent_class;
-};
-
-extern GType ui_skinned_window_get_type(void);
-extern GtkWidget *ui_skinned_window_new(const gchar *wmclass_name);
-extern void ui_skinned_window_draw_all(GtkWidget *widget);
-
-#endif /* AUDACIOUS_UI_SKINNED_WINDOW_H */
--- a/src/audacious/ui_skinselector.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,404 +0,0 @@
-/*  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include "ui_skinselector.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "platform/smartinclude.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "main.h"
-#include "ui_skin.h"
-#include "util.h"
-
-#define EXTENSION_TARGETS 7
-
-static gchar *ext_targets[EXTENSION_TARGETS] = { "bmp", "xpm", "png", "svg",
-        "gif", "jpg", "jpeg" };
-
-#define THUMBNAIL_WIDTH  90
-#define THUMBNAIL_HEIGHT 40
-
-
-enum SkinViewCols {
-    SKIN_VIEW_COL_PREVIEW,
-    SKIN_VIEW_COL_FORMATTEDNAME,
-    SKIN_VIEW_COL_NAME,
-    SKIN_VIEW_N_COLS
-};
-
-
-GList *skinlist = NULL;
-
-
-
-static gchar *
-get_thumbnail_filename(const gchar * path)
-{
-    gchar *basename, *pngname, *thumbname;
-
-    g_return_val_if_fail(path != NULL, NULL);
-
-    basename = g_path_get_basename(path);
-    pngname = g_strconcat(basename, ".png", NULL);
-
-    thumbname = g_build_filename(aud_paths[BMP_PATH_SKIN_THUMB_DIR],
-                                 pngname, NULL);
-
-    g_free(basename);
-    g_free(pngname);
-
-    return thumbname;
-}
-
-
-static GdkPixbuf *
-skin_get_preview(const gchar * path)
-{
-    GdkPixbuf *preview = NULL;
-    gchar *dec_path, *preview_path;
-    gboolean is_archive = FALSE;
-    gint i = 0;
-    gchar buf[60];			/* gives us lots of room */
-
-    if (file_is_archive(path))
-    {
-        if (!(dec_path = archive_decompress(path)))
-            return NULL;
-
-        is_archive = TRUE;
-    }
-    else
-    {
-        dec_path = g_strdup(path);
-    }
-
-    for (i = 0; i < EXTENSION_TARGETS; i++)
-    {
-        sprintf(buf, "main.%s", ext_targets[i]);
-
-        if ((preview_path = find_path_recursively(dec_path, buf)) != NULL)
-            break;
-    }
-
-    if (preview_path)
-    {
-        preview = gdk_pixbuf_new_from_file(preview_path, NULL);
-        g_free(preview_path);
-    }
-
-    if (is_archive)
-        del_directory(dec_path);
-
-    g_free(dec_path);
-
-    return preview;
-}
-
-
-static GdkPixbuf *
-skin_get_thumbnail(const gchar * path)
-{
-    GdkPixbuf *scaled = NULL;
-    GdkPixbuf *preview;
-    gchar *thumbname;
-
-    g_return_val_if_fail(path != NULL, NULL);
-
-    if (g_str_has_suffix(path, "thumbs"))
-        return NULL;
-
-    thumbname = get_thumbnail_filename(path);
-
-    if (g_file_test(thumbname, G_FILE_TEST_EXISTS)) {
-        scaled = gdk_pixbuf_new_from_file(thumbname, NULL);
-        g_free(thumbname);
-        return scaled;
-    }
-
-    if (!(preview = skin_get_preview(path))) {
-        g_free(thumbname);
-        return NULL;
-    }
-
-    scaled = gdk_pixbuf_scale_simple(preview,
-                                     THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT,
-                                     GDK_INTERP_BILINEAR);
-    g_object_unref(preview);
-
-    gdk_pixbuf_save(scaled, thumbname, "png", NULL, NULL);
-    g_free(thumbname);
-
-    return scaled;
-}
-
-static void
-skinlist_add(const gchar * filename)
-{
-    SkinNode *node;
-    gchar *basename;
-
-    g_return_if_fail(filename != NULL);
-
-    node = g_slice_new0(SkinNode);
-    node->path = g_strdup(filename);
-
-    basename = g_path_get_basename(filename);
-
-    if (file_is_archive(filename)) {
-        node->name = archive_basename(basename);
-	node->desc = _("Archived Winamp 2.x skin");
-        g_free(basename);
-    }
-    else {
-        node->name = basename;
-	node->desc = _("Unarchived Winamp 2.x skin");
-    }
-
-    skinlist = g_list_prepend(skinlist, node);
-}
-
-static gboolean
-scan_skindir_func(const gchar * path, const gchar * basename, gpointer data)
-{
-    if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
-        if (file_is_archive(path)) {
-            skinlist_add(path);
-        }
-    }
-    else if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
-        skinlist_add(path);
-    }
-
-    return FALSE;
-}
-
-static void
-scan_skindir(const gchar * path)
-{
-    GError *error = NULL;
-
-    g_return_if_fail(path != NULL);
-
-    if (path[0] == '.')
-        return;
-
-    if (!dir_foreach(path, scan_skindir_func, NULL, &error)) {
-        g_warning("Failed to open directory (%s): %s", path, error->message);
-        g_error_free(error);
-        return;
-    }
-}
-
-static gint
-skinlist_compare_func(gconstpointer a, gconstpointer b)
-{
-    g_return_val_if_fail(a != NULL && SKIN_NODE(a)->name != NULL, 1);
-    g_return_val_if_fail(b != NULL && SKIN_NODE(b)->name != NULL, 1);
-    return strcasecmp(SKIN_NODE(a)->name, SKIN_NODE(b)->name);
-}
-
-static void
-skin_free_func(gpointer data)
-{
-    g_return_if_fail(data != NULL);
-    g_free(SKIN_NODE(data)->name);
-    g_free(SKIN_NODE(data)->path);
-    g_slice_free(SkinNode, data);
-}
-
-
-static void
-skinlist_clear(void)
-{
-    if (!skinlist)
-        return;
-
-    g_list_foreach(skinlist, (GFunc) skin_free_func, NULL);
-    g_list_free(skinlist);
-    skinlist = NULL;
-}
-
-void
-skinlist_update(void)
-{
-    gchar *skinsdir;
-
-    skinlist_clear();
-
-    scan_skindir(aud_paths[BMP_PATH_USER_SKIN_DIR]);
-    scan_skindir(DATA_DIR G_DIR_SEPARATOR_S "Skins");
-
-    skinsdir = getenv("SKINSDIR");
-    if (skinsdir) {
-        gchar **dir_list = g_strsplit(skinsdir, ":", 0);
-        gchar **dir;
-
-        for (dir = dir_list; *dir; dir++)
-            scan_skindir(*dir);
-        g_strfreev(dir_list);
-    }
-
-    skinlist = g_list_sort(skinlist, skinlist_compare_func);
-
-    g_assert(skinlist != NULL);
-}
-
-void
-skin_view_update(GtkTreeView * treeview, GtkWidget * refresh_button)
-{
-    GtkTreeSelection *selection = NULL;
-    GtkListStore *store;
-    GtkTreeIter iter, iter_current_skin;
-    gboolean have_current_skin = FALSE;
-    GtkTreePath *path;
-
-    GdkPixbuf *thumbnail;
-    gchar *formattedname;
-    gchar *name;
-    GList *entry;
-
-    gtk_widget_set_sensitive(GTK_WIDGET(treeview), FALSE);
-    gtk_widget_set_sensitive(GTK_WIDGET(refresh_button), FALSE);
-
-    store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-
-    gtk_list_store_clear(store);
-
-    skinlist_update();
-
-    for (entry = skinlist; entry; entry = g_list_next(entry)) {
-        thumbnail = skin_get_thumbnail(SKIN_NODE(entry->data)->path);
-
-        formattedname = g_strdup_printf("<big><b>%s</b></big>\n<i>%s</i>",
-		SKIN_NODE(entry->data)->name, SKIN_NODE(entry->data)->desc);
-        name = SKIN_NODE(entry->data)->name;
-
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                           SKIN_VIEW_COL_PREVIEW, thumbnail,
-                           SKIN_VIEW_COL_FORMATTEDNAME, formattedname,
-                           SKIN_VIEW_COL_NAME, name, -1);
-        if (thumbnail)
-            g_object_unref(thumbnail);
-        g_free(formattedname);
-
-        if (g_strstr_len(aud_active_skin->path,
-                         strlen(aud_active_skin->path), name) ) {
-            iter_current_skin = iter;
-            have_current_skin = TRUE;
-        }
-    }
-
-    if (have_current_skin) {
-        selection = gtk_tree_view_get_selection(treeview);
-        gtk_tree_selection_select_iter(selection, &iter_current_skin);
-
-        path = gtk_tree_model_get_path(GTK_TREE_MODEL(store),
-		                               &iter_current_skin);
-        gtk_tree_view_scroll_to_cell(treeview, path, NULL, TRUE, 0.5, 0.5);
-        gtk_tree_path_free(path);
-    }
-
-    gtk_widget_set_sensitive(GTK_WIDGET(treeview), TRUE);
-    gtk_widget_set_sensitive(GTK_WIDGET(refresh_button), TRUE);
-}
-
-
-static void
-skin_view_on_cursor_changed(GtkTreeView * treeview,
-                            gpointer data)
-{
-    GtkTreeModel *model;
-    GtkTreeSelection *selection;
-    GtkTreeIter iter;
-
-    GList *node;
-    gchar *name;
-    gchar *comp = NULL;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, SKIN_VIEW_COL_NAME, &name, -1);
-
-    for (node = skinlist; node; node = g_list_next(node)) {
-        comp = SKIN_NODE(node->data)->path;
-        if (g_strrstr(comp, name))
-            break;
-    }
-
-    g_free(name);
-
-    aud_active_skin_load(comp);
-}
-
-
-void
-skin_view_realize(GtkTreeView * treeview)
-{
-    GtkListStore *store;
-    GtkTreeViewColumn *column;
-    GtkCellRenderer *renderer;
-    GtkTreeSelection *selection;
-
-    gtk_widget_show_all(GTK_WIDGET(treeview));
-    
-    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
-    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
-
-    store = gtk_list_store_new(SKIN_VIEW_N_COLS, GDK_TYPE_PIXBUF,
-                               G_TYPE_STRING , G_TYPE_STRING);
-    gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-    gtk_tree_view_column_set_spacing(column, 16);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview),
-                                GTK_TREE_VIEW_COLUMN(column));
-
-    renderer = gtk_cell_renderer_pixbuf_new();
-    gtk_tree_view_column_pack_start(column, renderer, FALSE);
-    gtk_tree_view_column_set_attributes(column, renderer, "pixbuf",
-                                        SKIN_VIEW_COL_PREVIEW, NULL);
-
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes(column, renderer, "markup",
-                                        SKIN_VIEW_COL_FORMATTEDNAME, NULL);
-
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
-    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
-
-    g_signal_connect(treeview, "cursor-changed",
-                     G_CALLBACK(skin_view_on_cursor_changed), NULL);
-}
--- a/src/audacious/ui_skinselector.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*  BMP - Cross-platform multimedia player
- *  Copyright (C) 2003-2004  BMP development team.
- *
- *  Based on XMMS:
- *  Copyright (C) 1998-2003  XMMS development team.
- *
- *  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; under version 3 of the License.
- *
- *  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, see <http://www.gnu.org/licenses>.
- *
- *  The Audacious team does not consider modular code linking to
- *  Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SKINSELECTOR_H
-#define AUDACIOUS_UI_SKINSELECTOR_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#define SKIN_NODE(x)  ((SkinNode *)(x))
-struct _SkinNode {
-    gchar *name;
-    gchar *desc;
-    gchar *path;
-    GTime *time;
-};
-
-typedef struct _SkinNode SkinNode;
-
-extern GList *skinlist;
-
-void skinlist_update();
-void skin_view_realize(GtkTreeView * treeview);
-void skin_view_update(GtkTreeView * treeview, GtkWidget * refresh_button);
-
-#endif /* AUDACIOUS_UI_SKINSELECTOR_H */
--- a/src/audacious/ui_svis.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,550 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007  Audacious development team.
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skin.h"
-#include "ui_svis.h"
-#include "ui_vis.h"
-#include "main.h"
-#include "util.h"
-#include "strings.h"
-#include "playback.h"
-#include <string.h>
-#include <ctype.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkmarshal.h>
-#include <gtk/gtkimage.h>
-
-#define UI_TYPE_SVIS           (ui_svis_get_type())
-
-static gint svis_redraw_delays[] = { 1, 2, 4, 8 };
-
-/* FIXME: Are the svis_scope_colors correct? */
-static guint8 svis_scope_colors[] = { 20, 19, 18, 19, 20 };
-static guint8 svis_vu_normal_colors[] = { 17, 17, 17, 12, 12, 12, 2, 2 };
-
-#define DRAW_DS_PIXEL(ptr,value) \
-	*(ptr) = (value); \
-	*((ptr) + 1) = (value); \
-	*((ptr) + 76) = (value); \
-	*((ptr) + 77) = (value);
-
-#define SVIS_HEIGHT 5
-#define SVIS_WIDTH 38
-
-enum {
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-static void ui_svis_class_init         (UiSVisClass *klass);
-static void ui_svis_init               (UiSVis *svis);
-static void ui_svis_destroy            (GtkObject *object);
-static void ui_svis_realize            (GtkWidget *widget);
-static void ui_svis_unrealize          (GtkWidget *widget);
-static void ui_svis_map                (GtkWidget *widget);
-static void ui_svis_unmap              (GtkWidget *widget);
-static void ui_svis_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_svis_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_svis_expose         (GtkWidget *widget, GdkEventExpose *event);
-static void ui_svis_toggle_scaled      (UiSVis *svis);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint vis_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_svis_get_type() {
-    static GType vis_type = 0;
-    if (!vis_type) {
-        static const GTypeInfo vis_info = {
-            sizeof (UiSVisClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_svis_class_init,
-            NULL,
-            NULL,
-            sizeof (UiSVis),
-            0,
-            (GInstanceInitFunc) ui_svis_init,
-        };
-        vis_type = g_type_register_static (GTK_TYPE_WIDGET, "UiSVis_", &vis_info, 0);
-    }
-
-    return vis_type;
-}
-
-static void ui_svis_class_init(UiSVisClass *klass) {
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_svis_destroy;
-
-    widget_class->realize = ui_svis_realize;
-    widget_class->unrealize = ui_svis_unrealize;
-    widget_class->map = ui_svis_map;
-    widget_class->unmap = ui_svis_unmap;
-    widget_class->expose_event = ui_svis_expose;
-    widget_class->size_request = ui_svis_size_request;
-    widget_class->size_allocate = ui_svis_size_allocate;
-
-    klass->scaled = ui_svis_toggle_scaled;
-
-    vis_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiSVisClass, scaled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-}
-
-static void ui_svis_init(UiSVis *svis) {
-
-}
-
-GtkWidget* ui_svis_new(GtkWidget *fixed, gint x, gint y) {
-    UiSVis *svis = g_object_new (ui_svis_get_type (), NULL);
-
-    svis->x = x;
-    svis->y = y;
-
-    svis->width = SVIS_WIDTH;
-    svis->height = SVIS_HEIGHT;
-
-    svis->fixed = fixed;
-    svis->scaled = FALSE;
-
-    svis->visible_window = TRUE;
-    svis->event_window = NULL;
-
-    gtk_fixed_put(GTK_FIXED(svis->fixed), GTK_WIDGET(svis), svis->x, svis->y);
-
-    return GTK_WIDGET(svis);
-}
-
-static void ui_svis_destroy(GtkObject *object) {
-    UiSVis *svis;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_IS_SVIS (object));
-
-    svis = UI_SVIS (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_svis_realize(GtkWidget *widget) {
-    UiSVis *svis;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_IS_SVIS(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    svis = UI_SVIS(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
-
-    if (svis->visible_window)
-    {
-      attributes.visual = gtk_widget_get_visual(widget);
-      attributes.colormap = gtk_widget_get_colormap(widget);
-      attributes.wclass = GDK_INPUT_OUTPUT;
-      attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-      widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-      GTK_WIDGET_UNSET_FLAGS(widget, GTK_NO_WINDOW);
-      gdk_window_set_user_data(widget->window, widget);
-    }
-    else
-    {
-      widget->window = gtk_widget_get_parent_window (widget);
-      g_object_ref (widget->window);
-
-      attributes.wclass = GDK_INPUT_ONLY;
-      attributes_mask = GDK_WA_X | GDK_WA_Y;
-      svis->event_window = gdk_window_new (widget->window, &attributes, attributes_mask);
-      GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
-      gdk_window_set_user_data(svis->event_window, widget);
-    }
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-}
-
-static void ui_svis_unrealize(GtkWidget *widget) {
-    UiSVis *svis;
-    svis = UI_SVIS(widget);
-
-    if ( svis->event_window != NULL )
-    {
-      gdk_window_set_user_data( svis->event_window , NULL );
-      gdk_window_destroy( svis->event_window );
-      svis->event_window = NULL;
-    }
-
-    if (GTK_WIDGET_CLASS (parent_class)->unrealize)
-        (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
-}
-
-static void ui_svis_map(GtkWidget *widget)
-{
-    UiSVis *svis;
-    svis = UI_SVIS(widget);
-
-    if (svis->event_window != NULL)
-      gdk_window_show (svis->event_window);
-
-    if (GTK_WIDGET_CLASS (parent_class)->map)
-      (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
-}
-
-static void ui_svis_unmap (GtkWidget *widget)
-{
-    UiSVis *svis;
-    svis = UI_SVIS(widget);
-
-    if (svis->event_window != NULL)
-      gdk_window_hide (svis->event_window);
-
-    if (GTK_WIDGET_CLASS (parent_class)->unmap)
-      (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
-}
-
-static void ui_svis_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiSVis *svis = UI_SVIS(widget);
-
-    requisition->width = svis->width * (svis->scaled ? cfg.scale_factor : 1);
-    requisition->height = svis->height*(svis->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_svis_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiSVis *svis = UI_SVIS (widget);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (svis->scaled ? cfg.scale_factor : 1 );
-    widget->allocation.y *= (svis->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-    {
-        if (svis->event_window != NULL)
-            gdk_window_move_resize(svis->event_window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-        else
-            gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-    }
-
-    svis->x = widget->allocation.x/(svis->scaled ? cfg.scale_factor : 1);
-    svis->y = widget->allocation.y/(svis->scaled ? cfg.scale_factor : 1);
-}
-
-static gboolean ui_svis_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_IS_SVIS (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiSVis *svis = UI_SVIS (widget);
-
-    gint x, y, h;
-    guchar svis_color[24][3];
-    guchar rgb_data[SVIS_WIDTH * 2 * SVIS_HEIGHT * 2], *ptr, c;
-    guint32 colors[24];
-    GdkRgbCmap *cmap;
-
-    if (!GTK_WIDGET_VISIBLE(widget))
-        return FALSE;
-
-    if (!svis->visible_window)
-        return FALSE;
-
-    skin_get_viscolor(aud_active_skin, svis_color);
-    for (y = 0; y < 24; y++) {
-        colors[y] =
-            svis_color[y][0] << 16 | svis_color[y][1] << 8 | svis_color[y][2];
-    }
-    cmap = gdk_rgb_cmap_new(colors, 24);
-
-    if (!cfg.scaled) {
-      memset(rgb_data, 0, SVIS_WIDTH * SVIS_HEIGHT);
-      if (cfg.vis_type == VIS_ANALYZER  && !playback_get_paused() && playback_get_playing()){
-	for(y=0; y < SVIS_HEIGHT; y++){
-	  if (cfg.analyzer_type == ANALYZER_BARS){
-	    for(x=0;x< SVIS_WIDTH; x++){
-	      if(svis->data[x] > y << 1)
-		{
-		  rgb_data[x*3+ (SVIS_HEIGHT - y) * SVIS_WIDTH] = 23;
-		  rgb_data[x*3+1 + (SVIS_HEIGHT - y) * SVIS_WIDTH] = 23;
-		  
-		}
-	    }
-	  }
-	  else{
-	    for(x=0;x< SVIS_WIDTH; x++){
-	      if(svis->data[x] > y << 1)
-		{
-		  rgb_data[x + (SVIS_HEIGHT - y) * SVIS_WIDTH] = 23;
-		}
-	    }
-	  }
-	}
-      }
-	else if (cfg.vis_type == VIS_VOICEPRINT){
-	  switch (cfg.vu_mode) {
-	  case VU_NORMAL:
-	    for (y = 0; y < 2; y++) {
-	      ptr = rgb_data + ((y * 3) * 38);
-	      h = (svis->data[y] * 7) / 37;
-	      for (x = 0; x < h; x++, ptr += 5) {
-		c = svis_vu_normal_colors[x];
-		*(ptr) = c;
-		*(ptr + 1) = c;
-		*(ptr + 2) = c;
-		*(ptr + 38) = c;
-		*(ptr + 39) = c;
-		*(ptr + 40) = c;
-	      }
-	    }
-	    break;
-	  case VU_SMOOTH:
-	    for (y = 0; y < 2; y++) {
-	      ptr = rgb_data + ((y * 3) * SVIS_WIDTH);
-	      for (x = 0; x < svis->data[y]; x++, ptr++) {
-		c = 17 - ((x * 15) / 37);
-		*(ptr) = c;
-		*(ptr + 38) = c;
-	      }
-	    }
-	    break;
-	  }	  
-	}
-        else if (cfg.vis_type == VIS_SCOPE) {
-            for (x = 0; x < 38; x++) {
-                h = svis->data[x << 1] / 3;
-                ptr = rgb_data + ((4 - h) * 38) + x;
-                *ptr = svis_scope_colors[h];
-            }
-        }
-
-    }
-    else {            /*svis scaling, this needs some work, since a lot of stuff is hardcoded --majeru*/
-
-      memset(rgb_data, 0, SVIS_WIDTH * cfg.scale_factor * SVIS_HEIGHT * cfg.scale_factor);
-      if (cfg.vis_type == VIS_ANALYZER && !playback_get_paused() && playback_get_playing()){
-	  for(y=0; y < SVIS_HEIGHT; y++){
-            if (cfg.analyzer_type == ANALYZER_BARS){
-              for(x=0;x< SVIS_WIDTH; x++){
-                if(svis->data[x] > y << 1)
-                {
-                  ptr = rgb_data + x * 6 + (SVIS_HEIGHT * 2 - y * 2) * SVIS_WIDTH *2;
-                  DRAW_DS_PIXEL(ptr, 23);
-                  DRAW_DS_PIXEL(ptr + 2, 23);
-                }
-              }
-            }
-            else{
-              for(x=0;x< SVIS_WIDTH; x++){
-                if(svis->data[x] > y << 1)
-                {
-                  ptr = rgb_data + x * 2 + (SVIS_HEIGHT * 2 - y * 2) * SVIS_WIDTH * 2;
-                  DRAW_DS_PIXEL(ptr, 23);
-                }
-              }
-            }
-	  }
-        }
-	else if (cfg.vis_type == VIS_VOICEPRINT){
-	  switch (cfg.vu_mode) {
-	  case VU_NORMAL:
-	    for (y = 0; y < 2; y++) {
-	      ptr = rgb_data + ((y * 3) * 152);
-	      h = (svis->data[y] * 8) / 37;
-	      for (x = 0; x < h; x++, ptr += 10) {
-		c = svis_vu_normal_colors[x];
-		DRAW_DS_PIXEL(ptr, c);
-		DRAW_DS_PIXEL(ptr + 2, c);
-		DRAW_DS_PIXEL(ptr + 4, c);
-		DRAW_DS_PIXEL(ptr + 152, c);
-		DRAW_DS_PIXEL(ptr + 154, c);
-		DRAW_DS_PIXEL(ptr + 156, c);
-	      }
-	    }
-	    break;
-	  case VU_SMOOTH:
-	    for (y = 0; y < 2; y++) {
-	      ptr = rgb_data + ((y * 3) * 152);
-	      for (x = 0; x < svis->data[y]; x++, ptr += 2) {
-		c = 17 - ((x * 15) / 37);
-		DRAW_DS_PIXEL(ptr, c);
-		DRAW_DS_PIXEL(ptr + 152, c);
-	      }
-	    }
-	    break;
-	  }  
-	}
-        else if (cfg.vis_type == VIS_SCOPE) {
-            for (x = 0; x < 38; x++) {
-                h = svis->data[x << 1] / 3;
-                ptr = rgb_data + ((4 - h) * 152) + (x << 1);
-                *ptr = svis_scope_colors[h];
-                *(ptr + 1) = svis_scope_colors[h];
-                *(ptr + 76) = svis_scope_colors[h];
-                *(ptr + 77) = svis_scope_colors[h];
-            }
-        }
-
-
-    }
-
-    GdkPixmap *obj = NULL;
-    GdkGC *gc;
-    obj = gdk_pixmap_new(NULL, svis->width* ( svis->scaled ? cfg.scale_factor : 1), 
-        svis->height*(svis->scaled ? cfg.scale_factor : 1), gdk_rgb_get_visual()->depth);
-    gc = gdk_gc_new(obj);
-
-    if (!svis->scaled) {
-        gdk_draw_indexed_image(obj, gc, 0, 0, svis->width, svis->height,
-                               GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
-                               38, cmap);
-    } else {
-        gdk_draw_indexed_image(obj, gc,
-                               0 << 1, 0 << 1,
-                               svis->width << 1, svis->height << 1,
-                               GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
-                               76, cmap);
-    }
-
-    gdk_rgb_cmap_free(cmap);
-    gdk_draw_drawable (widget->window, gc, obj, 0, 0, 0, 0,
-                       svis->width*(svis->scaled ? cfg.scale_factor : 1), 
-                       svis->height*(svis->scaled ? cfg.scale_factor : 1));
-    g_object_unref(obj);
-    g_object_unref(gc);
-
-    return FALSE;
-}
-
-static void ui_svis_toggle_scaled(UiSVis *svis) {
-    GtkWidget *widget = GTK_WIDGET (svis);
-    svis->scaled = !svis->scaled;
-
-    gtk_widget_set_size_request(widget, svis->width* cfg.scale_factor, svis->height * cfg.scale_factor);
-
-    gtk_widget_queue_draw(widget);
-}
-
-void ui_svis_set_visible(GtkWidget *widget, gboolean window_is_visible)
-{
-    UiSVis *svis;
-    gboolean widget_is_visible;
-
-    g_return_if_fail(UI_IS_SVIS(widget));
-
-    svis = UI_SVIS (widget);
-    widget_is_visible = GTK_WIDGET_VISIBLE(widget);
-
-    svis->visible_window = window_is_visible;
-
-    if (GTK_WIDGET_REALIZED (widget))
-    {
-        if ( widget_is_visible )
-            gtk_widget_hide(widget);
-
-        gtk_widget_unrealize(widget);
-        gtk_widget_realize(widget);
-
-        if ( widget_is_visible )
-            gtk_widget_show(widget);
-    }
-
-    if (widget_is_visible)
-        gtk_widget_queue_resize(widget);
-}
-
-void ui_svis_clear_data(GtkWidget *widget) {
-    g_return_if_fail(UI_IS_SVIS(widget));
-
-    gint i;
-    UiSVis *svis = UI_SVIS (widget);
-
-    for (i = 0; i < 75; i++) {
-        svis->data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0;
-    }
-}
-
-void ui_svis_timeout_func(GtkWidget *widget, guchar * data) {
-    g_return_if_fail(UI_IS_SVIS(widget));
-
-    UiSVis *svis = UI_SVIS (widget);
-    static GTimer *timer = NULL;
-    gulong micros = 9999999;
-    gboolean falloff = FALSE;
-    gint i;
-
-    if (!timer) {
-        timer = g_timer_new();
-        g_timer_start(timer);
-    }
-    else {
-        g_timer_elapsed(timer, &micros);
-        if (micros > 14000)
-            g_timer_reset(timer);
-
-    }
-
-    if (cfg.vis_type == VIS_VOICEPRINT) {
-        if (micros > 14000)
-            falloff = TRUE;
-
-        for (i = 0; i < 2; i++) {
-            if (falloff || data) {
-                if (data && data[i] > svis->data[i])
-                    svis->data[i] = data[i];
-                else if (falloff) {
-                    if (svis->data[i] >= 2)
-                        svis->data[i] -= 2;
-                    else
-                        svis->data[i] = 0;
-                }
-            }
-
-        }
-    }
-    else if (data) {
-        for (i = 0; i < 75; i++)
-            svis->data[i] = data[i];
-    }
-
-    if (micros > 14000) {
-        if (!svis->refresh_delay) {
-            gtk_widget_queue_draw(widget);
-            svis->refresh_delay = svis_redraw_delays[cfg.vis_refresh];
-        }
-        svis->refresh_delay--;
-    }
-}
--- a/src/audacious/ui_svis.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007  Audacious development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_SVIS_H
-#define AUDACIOUS_UI_SVIS_H
-
-#include <gtk/gtk.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_SVIS(obj)          GTK_CHECK_CAST (obj, ui_svis_get_type (), UiSVis)
-#define UI_SVIS_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_svis_get_type (), UiSVisClass)
-#define UI_IS_SVIS(obj)       GTK_CHECK_TYPE (obj, ui_svis_get_type ())
-
-typedef struct _UiSVis        UiSVis;
-typedef struct _UiSVisClass   UiSVisClass;
-
-struct _UiSVis {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    gint             data[75];
-    gint             refresh_delay;
-    gboolean         scaled;
-    GtkWidget        *fixed;
-    gboolean         visible_window;
-    GdkWindow        *event_window;
-};
-
-struct _UiSVisClass {
-    GtkWidgetClass          parent_class;
-    void (* scaled)        (UiSVis *vis);
-};
-
-GtkWidget* ui_svis_new (GtkWidget *fixed, gint x, gint y);
-GtkType ui_svis_get_type(void);
-void ui_svis_clear_data(GtkWidget *widget);
-void ui_svis_timeout_func(GtkWidget *widget, guchar * data);
-void ui_svis_set_visible(GtkWidget *widget, gboolean window_is_visible);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_SVIS_H */
--- a/src/audacious/ui_urlopener.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_urlopener.c	Wed Aug 06 22:33:27 2008 +0300
@@ -44,7 +44,6 @@
 #include "main.h"
 #include "playback.h"
 #include "strings.h"
-#include "ui_playlist.h"
 
 #ifdef USE_CHARDET
 #include "../libguess/libguess.h"
@@ -157,3 +156,46 @@
 
     return win;
 }
+
+static void
+on_add_url_add_clicked(GtkWidget * widget,
+                       GtkWidget * entry)
+{
+    const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
+    if (text && *text)
+        playlist_add_url(playlist_get_active(), text);
+}
+
+static void
+on_add_url_ok_clicked(GtkWidget * widget,
+                      GtkWidget * entry)
+{
+    Playlist *playlist = playlist_get_active();
+
+    const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
+    if (text && *text)
+    {
+        playlist_clear(playlist);
+        playlist_add_url(playlist, text);
+        playback_initiate();
+    }
+}
+
+void
+show_add_url_window(void)
+{
+    static GtkWidget *url_window = NULL;
+
+    if (!url_window) {
+        url_window =
+            util_add_url_dialog_new(_("Enter location to play:"),
+                                    G_CALLBACK(on_add_url_ok_clicked),
+                                    G_CALLBACK(on_add_url_add_clicked));
+
+        g_signal_connect(url_window, "destroy",
+                         G_CALLBACK(gtk_widget_destroyed),
+                         &url_window);
+    }
+
+    gtk_window_present(GTK_WINDOW(url_window));
+}
--- a/src/audacious/ui_urlopener.h	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audacious/ui_urlopener.h	Wed Aug 06 22:33:27 2008 +0300
@@ -39,6 +39,7 @@
 
 GtkWidget *util_add_url_dialog_new(const gchar * caption, GCallback ok_func,
                                    GCallback enqueue_func);
+void show_add_url_window(void);
 
 G_END_DECLS
 
--- a/src/audacious/ui_vis.c	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,724 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007  Audacious development team.
- *
- * Based on:
- * BMP - Cross-platform multimedia player
- * Copyright (C) 2003-2004  BMP development team.
- * XMMS:
- * Copyright (C) 1998-2003  XMMS development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#include "ui_skin.h"
-#include "ui_vis.h"
-#include "main.h"
-#include "util.h"
-#include "playback.h"
-
-static const gfloat vis_afalloff_speeds[] = { 0.34, 0.5, 1.0, 1.3, 1.6 };
-static const gfloat vis_pfalloff_speeds[] = { 1.2, 1.3, 1.4, 1.5, 1.6 };
-static const gint vis_redraw_delays[] = { 1, 2, 4, 8 };
-static const guint8 vis_scope_colors[] =
-    { 21, 21, 20, 20, 19, 19, 18, 19, 19, 20, 20, 21, 21 };
-static guchar voiceprint_data[76*16];
-
-enum {
-    DOUBLED,
-    LAST_SIGNAL
-};
-
-static void ui_vis_class_init         (UiVisClass *klass);
-static void ui_vis_init               (UiVis *vis);
-static void ui_vis_destroy            (GtkObject *object);
-static void ui_vis_realize            (GtkWidget *widget);
-static void ui_vis_unrealize          (GtkWidget *widget);
-static void ui_vis_map                (GtkWidget *widget);
-static void ui_vis_unmap              (GtkWidget *widget);
-static void ui_vis_size_request       (GtkWidget *widget, GtkRequisition *requisition);
-static void ui_vis_size_allocate      (GtkWidget *widget, GtkAllocation *allocation);
-static gboolean ui_vis_expose         (GtkWidget *widget, GdkEventExpose *event);
-static void ui_vis_toggle_scaled      (UiVis *vis);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint vis_signals[LAST_SIGNAL] = { 0 };
-
-GType ui_vis_get_type() {
-    static GType vis_type = 0;
-    if (!vis_type) {
-        static const GTypeInfo vis_info = {
-            sizeof (UiVisClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) ui_vis_class_init,
-            NULL,
-            NULL,
-            sizeof (UiVis),
-            0,
-            (GInstanceInitFunc) ui_vis_init,
-        };
-        vis_type = g_type_register_static (GTK_TYPE_WIDGET, "UiVis_", &vis_info, 0);
-    }
-
-    return vis_type;
-}
-
-static void ui_vis_class_init(UiVisClass *klass) {
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    object_class = (GtkObjectClass*) klass;
-    widget_class = (GtkWidgetClass*) klass;
-    parent_class = gtk_type_class (gtk_widget_get_type ());
-
-    object_class->destroy = ui_vis_destroy;
-
-    widget_class->realize = ui_vis_realize;
-    widget_class->unrealize = ui_vis_unrealize;
-    widget_class->map = ui_vis_map;
-    widget_class->unmap = ui_vis_unmap;
-    widget_class->expose_event = ui_vis_expose;
-    widget_class->size_request = ui_vis_size_request;
-    widget_class->size_allocate = ui_vis_size_allocate;
-
-    klass->doubled = ui_vis_toggle_scaled;
-
-    vis_signals[DOUBLED] = 
-        g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-                      G_STRUCT_OFFSET (UiVisClass, doubled), NULL, NULL,
-                      gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
-}
-
-static void ui_vis_init(UiVis *vis) {
-    memset(voiceprint_data, 0, 16*76);
-}
-
-GtkWidget* ui_vis_new(GtkWidget *fixed, gint x, gint y, gint width) {
-    UiVis *vis = g_object_new (ui_vis_get_type (), NULL);
-
-    vis->x = x;
-    vis->y = y;
-
-    vis->width = width;
-    vis->height = 16;
-
-    vis->fixed = fixed;
-    vis->scaled = FALSE;
-
-    vis->visible_window = TRUE;
-    vis->event_window = NULL;
-
-    gtk_fixed_put(GTK_FIXED(vis->fixed), GTK_WIDGET(vis), vis->x, vis->y);
-
-    return GTK_WIDGET(vis);
-}
-
-static void ui_vis_destroy(GtkObject *object) {
-    UiVis *vis;
-
-    g_return_if_fail (object != NULL);
-    g_return_if_fail (UI_IS_VIS (object));
-
-    vis = UI_VIS (object);
-
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static void ui_vis_realize(GtkWidget *widget) {
-    UiVis *vis;
-    GdkWindowAttr attributes;
-    gint attributes_mask;
-
-    g_return_if_fail (widget != NULL);
-    g_return_if_fail (UI_IS_VIS(widget));
-
-    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-    vis = UI_VIS(widget);
-
-    attributes.x = widget->allocation.x;
-    attributes.y = widget->allocation.y;
-    attributes.width = widget->allocation.width;
-    attributes.height = widget->allocation.height;
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.event_mask = gtk_widget_get_events(widget);
-    attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
-
-    if (vis->visible_window)
-    {
-      attributes.visual = gtk_widget_get_visual(widget);
-      attributes.colormap = gtk_widget_get_colormap(widget);
-      attributes.wclass = GDK_INPUT_OUTPUT;
-      attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-      widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
-      GTK_WIDGET_UNSET_FLAGS(widget, GTK_NO_WINDOW);
-      gdk_window_set_user_data(widget->window, widget);
-    }
-    else
-    {
-      widget->window = gtk_widget_get_parent_window (widget);
-      g_object_ref (widget->window);
-
-      attributes.wclass = GDK_INPUT_ONLY;
-      attributes_mask = GDK_WA_X | GDK_WA_Y;
-      vis->event_window = gdk_window_new (widget->window, &attributes, attributes_mask);
-      GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
-      gdk_window_set_user_data(vis->event_window, widget);
-    }
-
-    widget->style = gtk_style_attach(widget->style, widget->window);
-}
-
-static void ui_vis_unrealize(GtkWidget *widget) {
-    UiVis *vis;
-    vis = UI_VIS(widget);
-
-    if ( vis->event_window != NULL )
-    {
-      gdk_window_set_user_data( vis->event_window , NULL );
-      gdk_window_destroy( vis->event_window );
-      vis->event_window = NULL;
-    }
-
-    if (GTK_WIDGET_CLASS (parent_class)->unrealize)
-        (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
-}
-
-static void ui_vis_map(GtkWidget *widget)
-{
-    UiVis *vis;
-    vis = UI_VIS(widget);
-
-    if (vis->event_window != NULL)
-      gdk_window_show (vis->event_window);
-
-    if (GTK_WIDGET_CLASS (parent_class)->map)
-      (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
-}
-
-static void ui_vis_unmap (GtkWidget *widget)
-{
-    UiVis *vis;
-    vis = UI_VIS(widget);
-
-    if (vis->event_window != NULL)
-      gdk_window_hide (vis->event_window);
-
-    if (GTK_WIDGET_CLASS (parent_class)->unmap)
-      (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
-}
-
-static void ui_vis_size_request(GtkWidget *widget, GtkRequisition *requisition) {
-    UiVis *vis = UI_VIS(widget);
-
-    requisition->width = vis->width*(vis->scaled ? cfg.scale_factor : 1);
-    requisition->height = vis->height*(vis->scaled ? cfg.scale_factor : 1);
-}
-
-static void ui_vis_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
-    UiVis *vis = UI_VIS (widget);
-
-    widget->allocation = *allocation;
-    widget->allocation.x *= (vis->scaled ? cfg.scale_factor : 1);
-    widget->allocation.y *= (vis->scaled ? cfg.scale_factor : 1);
-    if (GTK_WIDGET_REALIZED (widget))
-    {
-        if (vis->event_window != NULL)
-            gdk_window_move_resize(vis->event_window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-        else
-            gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
-    }
-
-    vis->x = widget->allocation.x/(vis->scaled ? cfg.scale_factor : 1);
-    vis->y = widget->allocation.y/(vis->scaled ? cfg.scale_factor : 1);
-}
-
-static gboolean ui_vis_expose(GtkWidget *widget, GdkEventExpose *event) {
-    g_return_val_if_fail (widget != NULL, FALSE);
-    g_return_val_if_fail (UI_IS_VIS (widget), FALSE);
-    g_return_val_if_fail (event != NULL, FALSE);
-
-    UiVis *vis = UI_VIS (widget);
-
-    gint x, y, n, h = 0, h2;
-    gfloat delta;
-    guchar skin_col[2][3];
-    guchar vis_color[24][3];
-    guchar vis_voice_color[256][3], voice_c[3];
-    guchar rgb_data[76 * 16 * 3 * 2 * 2], *ptr, c;
-    guint32 colors[24];
-    GdkColor *fgc, *bgc;
-    GdkRgbCmap *cmap;
-
-    if (!GTK_WIDGET_VISIBLE(widget))
-        return FALSE;
-
-    if (!vis->visible_window)
-        return FALSE;
-
-    skin_get_viscolor(aud_active_skin, vis_color);
-    for (y = 0; y < 24; y++) {
-        colors[y] =
-            vis_color[y][0] << 16 | vis_color[y][1] << 8 | vis_color[y][2];
-    }
-    cmap = gdk_rgb_cmap_new(colors, 24);
-
-    if (!vis->scaled) {
-      if(cfg.vis_type == VIS_VOICEPRINT /*&& cfg.voiceprint_mode != VOICEPRINT_NORMAL*/){
-	memset(rgb_data, 0, 76 * 16 * 3);
-      }
-      else{
-	memset(rgb_data, 0, 76 * 16);
-	for (y = 1; y < 16; y += 2) {
-	  ptr = rgb_data + (y * 76);
-	  for (x = 0; x < 76; x += 2, ptr += 2)
-	    *ptr = 1;
-      }
-      }
-    }
-    else{
-      if(cfg.vis_type == VIS_VOICEPRINT /*&& cfg.voiceprint_mode != VOICEPRINT_NORMAL*/){
-	memset(rgb_data, 0, 3 * 4 * 16 * 76);
-      }
-      else{
-	memset(rgb_data, 0, (guint)(76 * cfg.scale_factor) * 32);
-	for (y = 1; y < 16; y += 2) {
-	  ptr = rgb_data + (y * (guint)(76 * 4 * cfg.scale_factor));
-	  for (x = 0; x < 76; x += 2, ptr += 4) {
-	    *ptr = 1;
-	    *(ptr + 1) = 1;
-	    *(ptr + (guint)(76 * cfg.scale_factor)) = 1;
-	    *(ptr + (guint)(76 * cfg.scale_factor)+1) = 1;
-	}
-      }
-      }
-    }
-    if (cfg.vis_type == VIS_ANALYZER) {
-      for (x = 0; x < 75; x++) {
-	if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0)
-	  h = vis->data[x >> 2];
-	else if (cfg.analyzer_type == ANALYZER_LINES)
-	  h = vis->data[x];
-	if (h && (cfg.analyzer_type == ANALYZER_LINES ||
-		  (x % 4) != 3)) {
-	  if (!vis->scaled) {
-	    ptr = rgb_data + ((16 - h) * 76) + x;
-	    switch (cfg.analyzer_mode) {
-	    case ANALYZER_NORMAL:
-	      for (y = 0; y < h; y++, ptr += 76)
-		*ptr = 18 - h + y;
-	      break;
-	    case ANALYZER_FIRE:
-	      for (y = 0; y < h; y++, ptr += 76)
-		*ptr = y + 2;
-	      break;
-	    case ANALYZER_VLINES:
-	      for (y = 0; y < h; y++, ptr += 76)
-		*ptr = 18 - h;
-	      break;
-	    }
-	  }
-	  else{
-	    ptr = rgb_data + ((16 - h) * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
-	    switch (cfg.analyzer_mode) {
-	    case ANALYZER_NORMAL:
-	      for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
-		*ptr = 18 - h + y;
-		*(ptr + 1) = 18 - h + y;
-		*(ptr + (guint)(76 * cfg.scale_factor)) = 18 - h + y;
-		*(ptr + (guint)(76 * cfg.scale_factor)+1) = 18 - h + y;
-	      }
-	      break;
-	    case ANALYZER_FIRE:
-	      for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
-		*ptr = y + 2;
-		*(ptr + 1) = y + 2;
-		*(ptr + (guint)(76 * cfg.scale_factor)) = y + 2;
-		*(ptr + (guint)(76 * cfg.scale_factor)+1) = y + 2;
-	      }
-	      break;
-	    case ANALYZER_VLINES:
-	      for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
-		*ptr = 18 - h;
-		*(ptr + 1) = 18 - h;
-		*(ptr + (guint)(76 * cfg.scale_factor)) = 18 - h;
-		*(ptr + (guint)(76 * cfg.scale_factor)+1) = 18 - h;
-	      }
-	      
-	      break;
-	    }
-	  }
-	}
-      }
-      if (cfg.analyzer_peaks) {
-	for (x = 0; x < 75; x++) {
-	  if (cfg.analyzer_type == ANALYZER_BARS && (x % 4) == 0)
-	    h = vis->peak[x >> 2];
-	  else if (cfg.analyzer_type == ANALYZER_LINES)
-	    h = vis->peak[x];
-	  if (h && (cfg.analyzer_type == ANALYZER_LINES || (x % 4) != 3)){
-	    
-	    if (!vis->scaled) {
-	      rgb_data[(16 - h) * 76 + x] = 23;
-	    }
-	    else{
-	      ptr = rgb_data + (16 - h) * (guint)(76 * 4 * cfg.scale_factor) + (guint)(x * cfg.scale_factor);
-	      *ptr = 23;
-	      *(ptr + 1) = 23;
-	      *(ptr + (guint)(76 * cfg.scale_factor)) = 23;
-	      *(ptr + (guint)(76 * cfg.scale_factor)+1) = 23;
-	    }
-	  }
-	}
-      }
-    }
-    else if (cfg.vis_type == VIS_VOICEPRINT) {
-      if(!playback_get_paused() && playback_get_playing()){/*Don't scroll when it's paused or stopped*/
-	for (y = 0; y < 16; y ++)
-	  for (x = 75; x > 0; x--)
-	    voiceprint_data[x + y * 76] = voiceprint_data[x-1+y*76];
-	  for(y=0;y<16;y++)
-	    voiceprint_data[y * 76] = vis->data[y];
-      }
-      if(playback_get_playing()){ /*Only draw the data if we're playing*/
-	if(cfg.voiceprint_mode == VOICEPRINT_NORMAL){ 
-	  /* Create color gradient from the skin's background- and foreground color*/
-	  fgc = skin_get_color(aud_active_skin, SKIN_TEXTFG);
-	  bgc = skin_get_color(aud_active_skin, SKIN_TEXTBG);
-	  skin_col[0][0] = fgc->red   >> 8;
-	  skin_col[0][1] = fgc->green >> 8;
-	  skin_col[0][2] = fgc->blue  >> 8;
-	  skin_col[1][0] = bgc->red   >> 8;
-	  skin_col[1][1] = bgc->green >> 8;
-	  skin_col[1][2] = bgc->blue  >> 8;
-	  for(n=0;n<3;n++){
-	    for(x=0;x<256;x++){
-	      if(skin_col[0][n] > skin_col[1][n]){
-		delta = (gfloat)(skin_col[0][n] - skin_col[1][n]) / 256.0;
-		vis_voice_color[x][n] = skin_col[1][n] + (gfloat)(delta * x);
-	      }
-	      else if(skin_col[0][n] == skin_col[1][n]){
-		vis_voice_color[x][n] = skin_col[0][n];
-	      }
-	      else{
-		delta = (gfloat)(skin_col[1][n] - skin_col[0][n]) / 256.0;
-		vis_voice_color[x][n] = skin_col[1][n] - (gfloat)(delta * x);
-	      }
-	    }
-	  }
-	}
-	for (y = 0; y < 16; y ++){
-	  for (x = 0; x < 76; x++){
-	    guint8 d = voiceprint_data[x + y*76];
-	    
-	    if(cfg.voiceprint_mode == VOICEPRINT_NORMAL){
-	      voice_c[0] = vis_voice_color[d][0];
-	      voice_c[1] = vis_voice_color[d][1];
-	      voice_c[2] = vis_voice_color[d][2];
-	    }
-	    else if(cfg.voiceprint_mode == VOICEPRINT_FIRE){
-	      voice_c[0] = d < 64 ? (d * 2) : 255;
-	      voice_c[1] = d < 64 ? 0 : (d < 128 ? (d-64) * 2 : 255);
-	      voice_c[2] = d < 128 ? 0 : (d-128) * 2;
-	      /* Test for black->blue->green->red. Isn't pretty, though...
-		 voice_c[0] = d > 192 ? (d - 192) << 2 : 0;
-		 voice_c[1] = d > 64 ? (d < 128 ? (d - 64) << 2 : (d < 192 ? (192 - d) << 2 : 0)) : 0;
-		 voice_c[2] = d < 64 ? d << 2 : (d < 128 ? (128 - d) << 2 : 0);
-	      */
-	    }
-	    else if(cfg.voiceprint_mode == VOICEPRINT_ICE){	    
-	      voice_c[0] = d;
-	      voice_c[1] = d < 128 ? d * 2 : 255;
-	      voice_c[2] = d < 64 ? d * 4 : 255; 
-	    }
-	    if(!vis->scaled){
-	      for(n=0;n<3;n++)
-		rgb_data[x * 3 + y * 76*3+n] = voice_c[n];
-	    }
-	    else{
-	      ptr = rgb_data + (guint)(x * 3 * cfg.scale_factor) + (guint) (y * 76 * 3 * cfg.scale_factor);
-	      for(n=0;n<3;n++)
-		{
-		  *(ptr + n) = voice_c[n];
-		  *(ptr + n + 3) = voice_c[n];
-		  *(ptr + (guint)(n + 76 * cfg.scale_factor * 3)) = voice_c[n];
-		  *(ptr + (guint)(n + 3 + 76 * cfg.scale_factor * 3)) = voice_c[n];
-		}
-	    }
-	  }
-	}
-      }
-    }
-    if (cfg.vis_type == VIS_SCOPE) {
-      for (x = 0; x < 75; x++) {
-	switch (cfg.scope_mode) {
-	case SCOPE_DOT:
-	  h = vis->data[x];
-	  if (!vis->scaled) {
-	  ptr = rgb_data + ((14 - h) * 76) + x;
-	    *ptr = vis_scope_colors[h + 1];
-	  }else{
-	    ptr = rgb_data + ((14 - h) * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
-	    *ptr = vis_scope_colors[h + 1];
-	    *(ptr + 1) = vis_scope_colors[h + 1];
-	    *(ptr + (guint)(76 * cfg.scale_factor)) = vis_scope_colors[h + 1];
-	    *(ptr + (guint)(76 * cfg.scale_factor)+1) = vis_scope_colors[h + 1];
-	  }
-	  break;
-	case SCOPE_LINE:
-	  if (x != 74) {
-	    h = 14 - vis->data[x];
-	    h2 = 14 - vis->data[x + 1];
-	    if (h > h2) {
-	      y = h;
-	      h = h2;
-	      h2 = y;
-	    }
-	    if (!vis->scaled) {
-	    ptr = rgb_data + (h * 76) + x;
-	    for (y = h; y <= h2; y++, ptr += 76)
-	      *ptr = vis_scope_colors[y - 2];
-	    }
-	    else{
-	      ptr = rgb_data + (h * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
-	      for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
-		*ptr = vis_scope_colors[y - 2];
-		*(ptr + 1) = vis_scope_colors[y - 2];
-		*(ptr + (guint)(76 * cfg.scale_factor)) = vis_scope_colors[y - 2];
-		*(ptr + (guint)(76 * cfg.scale_factor)+1) = vis_scope_colors[y - 2];
-	      }
-	    }
-	  }
-	  else {
-	    h = 14 - vis->data[x];
-	    if (!vis->scaled) {
-	      ptr = rgb_data + (h * 76) + x;
-	      *ptr = vis_scope_colors[h + 1];
-	    }else{
-	      ptr = rgb_data + (h * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
-	      *ptr = vis_scope_colors[h + 1];
-	      *(ptr + 1) = vis_scope_colors[h + 1];
-	      *(ptr + (guint)(76 * cfg.scale_factor)) = vis_scope_colors[h + 1];
-	      *(ptr + (guint)(76 * cfg.scale_factor)+1) = vis_scope_colors[h + 1];
-	    }
-	  }
-	  break;
-	case SCOPE_SOLID:
-	  h = 14 - vis->data[x];
-	  h2 = 8;
-	  c = vis_scope_colors[(gint) vis->data[x]];
-	  if (h > h2) {
-	    y = h;
-	    h = h2;
-	    h2 = y;
-	  }
-	  if (!vis->scaled) {
-	    ptr = rgb_data + (h * 76) + x;
-	    for (y = h; y <= h2; y++, ptr += 76)
-	      *ptr = c;
-	  }else{
-	    ptr = rgb_data + (h * (guint)(76 * 4 * cfg.scale_factor)) + (guint)(x * cfg.scale_factor);
-	    for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * cfg.scale_factor)) {
-	      *ptr = c;
-	      *(ptr + 1) = c;
-	      *(ptr + (guint)(76 * cfg.scale_factor)) = c;
-	      *(ptr + (guint)(76 * cfg.scale_factor)+1) = c;
-	    }
-	  }
-	  break;
-	}
-      }
-    }
-
-    GdkPixmap *obj = NULL;
-    GdkGC *gc;
-    obj = gdk_pixmap_new(NULL, vis->width*(vis->scaled ? cfg.scale_factor : 1), vis->height*(vis->scaled ? cfg.scale_factor : 1), gdk_rgb_get_visual()->depth);
-    gc = gdk_gc_new(obj);
-
-    if (!vis->scaled) {
-        if (cfg.vis_type == VIS_VOICEPRINT) {
-            gdk_draw_rgb_image(obj, gc, 0, 0, vis->width, vis->height,
-                               GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
-                               76 * 3);
-        } else {
-            gdk_draw_indexed_image(obj, gc, 0, 0, vis->width, vis->height,
-                                   GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
-                                   76 , cmap);
-        }
-    } else {
-        if (cfg.vis_type == VIS_VOICEPRINT) {
-            gdk_draw_rgb_image(obj, gc, 0 << 1, 0 << 1,
-                               vis->width << 1, vis->height << 1,
-                               GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
-                               76 * 2 * 3);
-        } else {
-            gdk_draw_indexed_image(obj, gc, 0 << 1, 0 << 1,
-                                   vis->width << 1, vis->height << 1,
-                                   GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
-                                   76 * 2 , cmap);
-        }
-    }
-
-    gdk_draw_drawable (widget->window, gc, obj, 0, 0, 0, 0,
-                       vis->width*(vis->scaled ? cfg.scale_factor : 1), vis->height*(vis->scaled ? cfg.scale_factor : 1));
-    g_object_unref(obj);
-    g_object_unref(gc);
-    gdk_rgb_cmap_free(cmap);
-    return FALSE;
-}
-
-static void ui_vis_toggle_scaled(UiVis *vis) {
-    GtkWidget *widget = GTK_WIDGET (vis);
-    vis->scaled = !vis->scaled;
-
-    gtk_widget_set_size_request(widget, vis->width*(vis->scaled ? cfg.scale_factor : 1), vis->height*(vis->scaled ? cfg.scale_factor : 1));
-
-    gtk_widget_queue_draw(GTK_WIDGET(vis));
-}
-
-void ui_vis_draw_pixel(GtkWidget *widget, guchar* texture, gint x, gint y, guint8 colour) {
-    UiVis *vis = UI_VIS (widget);
-    if (vis->scaled){
-        texture[y * 76 + x] = colour;
-        texture[y * 76 + x + 1] = colour;
-        texture[y * 76 * 4 + x] = colour;
-        texture[y * 76 * 4 + x + 1] = colour;
-    } else {
-        texture[y * 76 + x] = colour;
-    }
-}
-
-void ui_vis_set_visible(GtkWidget *widget, gboolean window_is_visible)
-{
-    UiVis *vis;
-    gboolean widget_is_visible;
-
-    g_return_if_fail(UI_IS_VIS(widget));
-
-    vis = UI_VIS (widget);
-    widget_is_visible = GTK_WIDGET_VISIBLE(widget);
-
-    vis->visible_window = window_is_visible;
-
-    if (GTK_WIDGET_REALIZED (widget))
-    {
-        if ( widget_is_visible )
-            gtk_widget_hide(widget);
-
-        gtk_widget_unrealize(widget);
-        gtk_widget_realize(widget);
-
-        if ( widget_is_visible )
-            gtk_widget_show(widget);
-    }
-
-    if (widget_is_visible)
-        gtk_widget_queue_resize(widget);
-}
-
-void ui_vis_clear_data(GtkWidget *widget) {
-    g_return_if_fail(UI_IS_VIS(widget));
-
-    gint i;
-    UiVis *vis = UI_VIS (widget);
-
-    memset(voiceprint_data, 0, 16*76);
-    for (i = 0; i < 75; i++) {
-        vis->data[i] = (cfg.vis_type == VIS_SCOPE) ? 6 : 0;
-        vis->peak[i] = 0;
-    }
-}
-
-void ui_vis_timeout_func(GtkWidget *widget, guchar * data) {
-    g_return_if_fail(UI_IS_VIS(widget));
-
-    UiVis *vis = UI_VIS (widget);
-    static GTimer *timer = NULL;
-    gulong micros = 9999999;
-    gboolean falloff = FALSE;
-    gint i;
-
-    if (!timer) {
-        timer = g_timer_new();
-        g_timer_start(timer);
-    }
-    else {
-      g_timer_elapsed(timer, &micros);
-      if (micros > 14000)
-	g_timer_reset(timer);
-    }
-    if (cfg.vis_type == VIS_ANALYZER) {
-        if (micros > 14000)
-            falloff = TRUE;
-        if (data || falloff) {
-            for (i = 0; i < 75; i++) {
-                if (data && data[i] > vis->data[i]) {
-                    vis->data[i] = data[i];
-                    if (vis->data[i] > vis->peak[i]) {
-                        vis->peak[i] = vis->data[i];
-                        vis->peak_speed[i] = 0.01;
-
-                    }
-                    else if (vis->peak[i] > 0.0) {
-                        vis->peak[i] -= vis->peak_speed[i];
-                        vis->peak_speed[i] *=
-                            vis_pfalloff_speeds[cfg.peaks_falloff];
-                        if (vis->peak[i] < vis->data[i])
-                            vis->peak[i] = vis->data[i];
-                        if (vis->peak[i] < 0.0)
-                            vis->peak[i] = 0.0;
-                    }
-                }
-                else if (falloff) {
-                    if (vis->data[i] > 0.0) {
-                        vis->data[i] -=
-                            vis_afalloff_speeds[cfg.analyzer_falloff];
-                        if (vis->data[i] < 0.0)
-                            vis->data[i] = 0.0;
-                    }
-                    if (vis->peak[i] > 0.0) {
-                        vis->peak[i] -= vis->peak_speed[i];
-                        vis->peak_speed[i] *=
-                            vis_pfalloff_speeds[cfg.peaks_falloff];
-                        if (vis->peak[i] < vis->data[i])
-                            vis->peak[i] = vis->data[i];
-                        if (vis->peak[i] < 0.0)
-                            vis->peak[i] = 0.0;
-                    }
-                }
-            }
-        }
-    }
-    else if (cfg.vis_type == VIS_VOICEPRINT && data){
-      for(i = 0; i < 16; i++)
-	{
-	  vis->data[i] = data[15 - i];
-	}
-    }
-    else if (data) {
-        for (i = 0; i < 75; i++)
-            vis->data[i] = data[i];
-    }
-
-    if (micros > 14000) {
-        if (!vis->refresh_delay) {
-            gtk_widget_queue_draw(widget);
-            vis->refresh_delay = vis_redraw_delays[cfg.vis_refresh];
-        }
-        vis->refresh_delay--;
-    }
-}
--- a/src/audacious/ui_vis.h	Wed Aug 06 22:30:35 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Audacious - a cross-platform multimedia player
- * Copyright (c) 2007  Audacious development team.
- *
- * 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; under version 3 of the License.
- *
- * 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, see <http://www.gnu.org/licenses>.
- *
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
- */
-
-#ifndef AUDACIOUS_UI_VIS_H
-#define AUDACIOUS_UI_VIS_H
-
-#include <gtk/gtk.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define UI_VIS(obj)          GTK_CHECK_CAST (obj, ui_vis_get_type (), UiVis)
-#define UI_VIS_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, ui_vis_get_type (), UiVisClass)
-#define UI_IS_VIS(obj)       GTK_CHECK_TYPE (obj, ui_vis_get_type ())
-
-typedef enum {
-    VIS_ANALYZER, VIS_SCOPE, VIS_VOICEPRINT, VIS_OFF
-} VisType;
-
-typedef enum {
-    ANALYZER_NORMAL, ANALYZER_FIRE, ANALYZER_VLINES
-} AnalyzerMode;
-
-typedef enum {
-    ANALYZER_LINES, ANALYZER_BARS
-} AnalyzerType;
-
-typedef enum {
-    SCOPE_DOT, SCOPE_LINE, SCOPE_SOLID
-} ScopeMode;
-typedef enum {
-  VOICEPRINT_NORMAL, VOICEPRINT_FIRE, VOICEPRINT_ICE
-} VoiceprintMode;
-
-
-typedef enum {
-    VU_NORMAL, VU_SMOOTH
-} VUMode;
-
-typedef enum {
-    REFRESH_FULL, REFRESH_HALF, REFRESH_QUARTER, REFRESH_EIGTH
-} RefreshRate;
-
-typedef enum {
-    FALLOFF_SLOWEST, FALLOFF_SLOW, FALLOFF_MEDIUM, FALLOFF_FAST,
-    FALLOFF_FASTEST
-} FalloffSpeed;
-
-typedef struct _UiVis        UiVis;
-typedef struct _UiVisClass   UiVisClass;
-
-struct _UiVis {
-    GtkWidget        widget;
-
-    gint             x, y, width, height;
-    gfloat           data[75], peak[75], peak_speed[75];
-    gint             refresh_delay;
-    gboolean         scaled;
-    GtkWidget        *fixed;
-    gboolean         visible_window;
-    GdkWindow        *event_window;
-};
-
-struct _UiVisClass {
-    GtkWidgetClass          parent_class;
-    void (* doubled)        (UiVis *vis);
-};
-
-GtkWidget* ui_vis_new (GtkWidget *fixed, gint x, gint y, gint width);
-GtkType ui_vis_get_type(void);
-void ui_vis_set_vis(GtkWidget *widget, gint num);
-void ui_vis_clear_data(GtkWidget *widget);
-void ui_vis_timeout_func(GtkWidget *widget, guchar * data);
-void ui_vis_set_visible(GtkWidget *widget, gboolean window_is_visible);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* AUDACIOUS_UI_VIS_H */
--- a/src/audtool/handlers_general.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audtool/handlers_general.c	Wed Aug 06 22:33:27 2008 +0300
@@ -270,28 +270,6 @@
     }
 }
 
-void get_skin(gint argc, gchar **argv)
-{
-    gchar *skin = NULL;
-    skin = audacious_remote_get_skin(dbus_proxy);
-    audtool_report("%s", skin);
-    g_free(skin);
-}
-
-void set_skin(gint argc, gchar **argv)
-{
-    if (argc < 2)
-    {
-        audtool_whine_args(argv[0], "<skin>");
-        exit(1);
-    }
-
-    if(!argv[1] || !strcmp(argv[1], ""))
-       return;
-
-    audacious_remote_set_skin(dbus_proxy, argv[1]);
-}
-
 void get_version(gint argc, gchar **argv)
 {
     gchar *version = NULL;
--- a/src/audtool/main.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/audtool/main.c	Wed Aug 06 22:33:27 2008 +0300
@@ -131,8 +131,6 @@
 
 	{"activate", activate, "activates and raises audacious", 0},
 	{"always-on-top", toggle_aot, "on/off always on top", 1},
-    {"get-skin", get_skin, "gets skin", 0},
-    {"set-skin", set_skin, "sets skin", 1},
     {"version", get_version, "shows audaciuos version", 0},
 	{"shutdown", shutdown_audacious_server, "shuts down audacious", 0},
 
--- a/src/libaudclient/audctrl.c	Wed Aug 06 22:30:35 2008 +0300
+++ b/src/libaudclient/audctrl.c	Wed Aug 06 22:33:27 2008 +0300
@@ -358,33 +358,6 @@
 }
 
 /**
- * audacious_remote_get_skin:
- * @proxy: DBus proxy for audacious
- *
- * Queries Audacious about it's skin.
- *
- * Return value: A path to the currently selected skin.
- **/
-gchar *audacious_remote_get_skin(DBusGProxy *proxy) {
-    gchar *skin = NULL;
-    org_atheme_audacious_get_skin (proxy, &skin, &error);
-    g_clear_error(&error);
-    return skin;
-}
-
-/**
- * audacious_remote_set_skin:
- * @proxy: DBus proxy for audacious
- * @skinfile: Path to a skinfile to use with Audacious.
- *
- * Tells audacious to start using the skinfile provided.
- **/
-void audacious_remote_set_skin(DBusGProxy *proxy, gchar *skinfile) {
-    org_atheme_audacious_set_skin(proxy, skinfile, &error);
-	g_clear_error(&error);
-}
-
-/**
  * audacious_remote_get_playlist_file:
  * @proxy: DBus proxy for audacious
  * @pos: The playlist position to query for.